From 0d2191ca859d7166a59fe0b8028638d933d3c84f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 16 Apr 2019 22:48:11 +0800 Subject: [PATCH] ## v0.4.16 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 增加 ISelect.AsType 实现弱类型查询,配合 Select().AsType(实体类型); - 补充 ISelect.From; - 补充 ExpressionTree 单元测试; - 优化 ToList(a => new Dto()),会按优先级查询 Join 实体属性; --- .../GetDataReaderValueBlockExpressionTest.cs | 346 ++++++++++++++++++ FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs | 23 +- FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs | 24 +- .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 25 +- .../SqlServer/Curd/SqlServerSelectTest.cs | 24 +- FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs | 24 +- FreeSql.Tests/UnitTest1.cs | 2 +- FreeSql/Extensions/EntityUtilExtensions.cs | 176 ++++++--- FreeSql/FreeSql.csproj | 2 +- FreeSql/Interface/Curd/ISelect/ISelect0.cs | 6 + FreeSql/Interface/Curd/ISelect/ISelect1.cs | 7 + FreeSql/Interface/Curd/ISelect/ISelect2.cs | 40 ++ FreeSql/Internal/CommonExpression.cs | 56 ++- .../SelectProvider/Select0Provider.cs | 11 +- .../SelectProvider/Select1Provider.cs | 1 + .../SelectProvider/Select2Provider.cs | 152 ++++++++ FreeSql/Internal/UtilsExpressionTree.cs | 208 ++++++++++- FreeSql/MySql/Curd/MySqlSelect.cs | 5 + FreeSql/Oracle/Curd/OracleSelect.cs | 5 + FreeSql/PostgreSQL/Curd/PostgreSQLSelect.cs | 9 +- FreeSql/SqlServer/Curd/SqlServerSelect.cs | 9 +- FreeSql/Sqlite/Curd/SqliteSelect.cs | 5 + 22 files changed, 1043 insertions(+), 117 deletions(-) create mode 100644 FreeSql.Tests/ExpressionTree/GetDataReaderValueBlockExpressionTest.cs create mode 100644 FreeSql/Interface/Curd/ISelect/ISelect2.cs create mode 100644 FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs diff --git a/FreeSql.Tests/ExpressionTree/GetDataReaderValueBlockExpressionTest.cs b/FreeSql.Tests/ExpressionTree/GetDataReaderValueBlockExpressionTest.cs new file mode 100644 index 00000000..7a8929d4 --- /dev/null +++ b/FreeSql.Tests/ExpressionTree/GetDataReaderValueBlockExpressionTest.cs @@ -0,0 +1,346 @@ +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; + +namespace FreeSql.ExpressionTree { + public class GetDataReaderValueBlockExpressionTest { + + [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 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)); + } + + [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 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")); + } + + [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 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")); + } + + [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 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")); + } + + [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 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")); + } + + [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 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")); + } + + [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 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")); + } + + [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 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")); + } + + [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 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")); + } + + [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 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")); + } + + [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 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")); + } + + [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 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")); + } + } +} diff --git a/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index 506a73d1..faa2d176 100644 --- a/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -139,7 +139,8 @@ namespace FreeSql.Tests.MySql { class TestDto { public int id { get; set; } - public string name { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 } [Fact] public void ToList() { @@ -149,6 +150,10 @@ namespace FreeSql.Tests.MySql { 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 t0 = select.Limit(50).ToList(); @@ -303,14 +308,20 @@ namespace FreeSql.Tests.MySql { } [Fact] public void From() { - //������� - var query2 = select.From((s, b, c) => s + 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 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(); + 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() { diff --git a/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs index 4f387df6..8faed4fc 100644 --- a/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs @@ -130,7 +130,8 @@ namespace FreeSql.Tests.Oracle { } class TestDto { public int id { get; set; } - public string name { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 } [Fact] public void ToList() { @@ -140,6 +141,11 @@ namespace FreeSql.Tests.Oracle { 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); @@ -199,14 +205,20 @@ namespace FreeSql.Tests.Oracle { } [Fact] public void From() { - //������� - var query2 = select.From((s, b, c) => s + 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 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(); + 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() { diff --git a/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs index 035e50ee..fe7b67c4 100644 --- a/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs +++ b/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -121,7 +121,8 @@ namespace FreeSql.Tests.PostgreSQL { } class TestDto { public int id { get; set; } - public string name { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 } [Fact] public void ToList() { @@ -131,6 +132,11 @@ namespace FreeSql.Tests.PostgreSQL { 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(); @@ -269,14 +275,21 @@ namespace FreeSql.Tests.PostgreSQL { } [Fact] public void From() { - //������� - var query2 = select.From((s, b, c) => s + + 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 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(); + 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() { diff --git a/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index f36460c2..29478dee 100644 --- a/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -132,7 +132,8 @@ namespace FreeSql.Tests.SqlServer { } class TestDto { public int id { get; set; } - public string name { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 } [Fact] public void ToList() { @@ -142,6 +143,11 @@ namespace FreeSql.Tests.SqlServer { 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); @@ -201,14 +207,20 @@ namespace FreeSql.Tests.SqlServer { } [Fact] public void From() { - //������� - var query2 = select.From((s, b, c) => s + 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 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(); + 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() { diff --git a/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index bc625bfb..40078a45 100644 --- a/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -124,7 +124,8 @@ namespace FreeSql.Tests.Sqlite { } class TestDto { public int id { get; set; } - public string name { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 } [Fact] public void ToList() { @@ -134,6 +135,11 @@ 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 => 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.sqlite.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); var testGuidId5 = g.sqlite.Select().ToList(); var testGuidId6 = g.sqlite.Select().ToList(a => a.id); @@ -193,14 +199,20 @@ namespace FreeSql.Tests.Sqlite { } [Fact] public void From() { - //������� - var query2 = select.From((s, b, c) => s + 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 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(); + 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() { diff --git a/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/UnitTest1.cs index 96b430e5..24b42c86 100644 --- a/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/UnitTest1.cs @@ -74,7 +74,7 @@ namespace FreeSql.Tests { //var dic = Newtonsoft.Json.JsonConvert.DeserializeObject>(testjson); var reqs = Newtonsoft.Json.JsonConvert.DeserializeObject>(testjson); reqs.ForEach(t => { - g.oracle.Insert(t).ExecuteAffrows(); + g.oracle.Insert(t).ExecuteAffrows(); }); diff --git a/FreeSql/Extensions/EntityUtilExtensions.cs b/FreeSql/Extensions/EntityUtilExtensions.cs index 065ceb84..38bb347a 100644 --- a/FreeSql/Extensions/EntityUtilExtensions.cs +++ b/FreeSql/Extensions/EntityUtilExtensions.cs @@ -21,10 +21,14 @@ namespace FreeSql.Extensions.EntityUtil { /// /// /// - /// + /// /// - public static string GetEntityKeyString(this IFreeSql orm, TEntity item, string splitString = "*|_,[,_|*") { - var func = _dicGetEntityKeyString.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(typeof(TEntity), t => { + public static void 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 = "*|_,[,_|*") { + 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)); @@ -96,7 +100,7 @@ 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 func(item); + return func(entity); } static ConcurrentDictionary>> _dicGetEntityKeyValues = new ConcurrentDictionary>>(); /// @@ -104,10 +108,14 @@ namespace FreeSql.Extensions.EntityUtil { /// /// /// - /// + /// /// - public static object[] GetEntityKeyValues(this IFreeSql orm, TEntity item) { - var func = _dicGetEntityKeyValues.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(typeof(TEntity), t => { + public static void 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[])); @@ -132,7 +140,7 @@ namespace FreeSql.Extensions.EntityUtil { }); return Expression.Lambda>(Expression.Block(new[] { var1Parm, var2Ret }, exps), new[] { parm1 }).Compile(); }); - return func(item); + return func(entity); } static ConcurrentDictionary>> _dicGetEntityString = new ConcurrentDictionary>>(); /// @@ -140,10 +148,14 @@ namespace FreeSql.Extensions.EntityUtil { /// /// /// - /// + /// /// - public static string GetEntityString(this IFreeSql orm, TEntity item) { - var func = _dicGetEntityString.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(typeof(TEntity), t => { + public static void 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)); @@ -176,15 +188,18 @@ namespace FreeSql.Extensions.EntityUtil { }); return Expression.Lambda>(Expression.Block(new[] { var1Parm, var2Sb }, exps), new[] { parm1 }).Compile(); }); - return func(item); + return func(entity); } /// /// 使用新实体的值,复盖旧实体的值 /// static ConcurrentDictionary>> _dicMapEntityValue = new ConcurrentDictionary>>(); - public static void MapEntityValue(this IFreeSql orm, TEntity from, TEntity to) { - var func = _dicMapEntityValue.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(typeof(TEntity), t => { + 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)); @@ -213,15 +228,18 @@ namespace FreeSql.Extensions.EntityUtil { } return Expression.Lambda>(Expression.Block(new[] { var1Parm, var2Parm }, exps), new[] { parm1, parm2 }).Compile(); }); - func(from, to); + func(entityFrom, entityTo); } static ConcurrentDictionary>> _dicMapEntityKeyValue = new ConcurrentDictionary>>(); /// /// 使用新实体的主键值,复盖旧实体的主键值 /// - public static void MapEntityKeyValue(this IFreeSql orm, TEntity from, TEntity to) { - var func = _dicMapEntityKeyValue.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(typeof(TEntity), t => { + 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)); @@ -242,7 +260,7 @@ namespace FreeSql.Extensions.EntityUtil { } return Expression.Lambda>(Expression.Block(new[] { var1Parm, var2Parm }, exps), new[] { parm1, parm2 }).Compile(); }); - func(from, to); + func(entityFrom, entityTo); } static ConcurrentDictionary>> _dicSetEntityIdentityValueWithPrimary = new ConcurrentDictionary>>(); @@ -251,10 +269,14 @@ namespace FreeSql.Extensions.EntityUtil { /// /// /// - /// + /// /// - public static void SetEntityIdentityValueWithPrimary(this IFreeSql orm, TEntity item, long idtval) { - var func = _dicSetEntityIdentityValueWithPrimary.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(typeof(TEntity), t => { + 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)); @@ -274,7 +296,7 @@ namespace FreeSql.Extensions.EntityUtil { } return Expression.Lambda>(Expression.Block(new[] { var1Parm }, exps), new[] { parm1, parm2 }).Compile(); }); - func(item, idtval); + func(entity, idtval); } static ConcurrentDictionary>> _dicGetEntityIdentityValueWithPrimary = new ConcurrentDictionary>>(); /// @@ -282,9 +304,13 @@ namespace FreeSql.Extensions.EntityUtil { /// /// /// - /// - public static long GetEntityIdentityValueWithPrimary(this IFreeSql orm, TEntity item) { - var func = _dicGetEntityIdentityValueWithPrimary.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(typeof(TEntity), t => { + /// + public static void 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)); @@ -317,7 +343,7 @@ namespace FreeSql.Extensions.EntityUtil { exps.Add(Expression.Label(returnTarget, Expression.Default(typeof(long)))); return Expression.Lambda>(Expression.Block(new[] { var1Parm }, exps), new[] { parm1 }).Compile(); }); - return func(item); + return func(entity); } static ConcurrentDictionary>> _dicClearEntityPrimaryValueWithIdentityAndGuid = new ConcurrentDictionary>>(); @@ -326,9 +352,13 @@ namespace FreeSql.Extensions.EntityUtil { /// /// /// - /// - public static void ClearEntityPrimaryValueWithIdentityAndGuid(this IFreeSql orm, TEntity item) { - var func = _dicClearEntityPrimaryValueWithIdentityAndGuid.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(typeof(TEntity), t => { + /// + 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)); @@ -349,7 +379,7 @@ namespace FreeSql.Extensions.EntityUtil { } return Expression.Lambda>(Expression.Block(new[] { var1Parm }, exps), new[] { parm1 }).Compile(); }); - func(item); + func(entity); } static ConcurrentDictionary>> _dicClearEntityPrimaryValueWithIdentity = new ConcurrentDictionary>>(); @@ -358,9 +388,13 @@ namespace FreeSql.Extensions.EntityUtil { /// /// /// - /// - public static void ClearEntityPrimaryValueWithIdentity(this IFreeSql orm, TEntity item) { - var func = _dicClearEntityPrimaryValueWithIdentity.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(typeof(TEntity), t => { + /// + 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)); @@ -380,7 +414,7 @@ namespace FreeSql.Extensions.EntityUtil { } return Expression.Lambda>(Expression.Block(new[] { var1Parm }, exps), new[] { parm1 }).Compile(); }); - func(item); + func(entity); } static ConcurrentDictionary>> _dicCompareEntityValueReturnColumns = new ConcurrentDictionary>>(); @@ -389,11 +423,14 @@ namespace FreeSql.Extensions.EntityUtil { /// /// /// - /// - /// + /// + /// /// - public static string[] CompareEntityValueReturnColumns(this IFreeSql orm, TEntity up, TEntity oldval, bool isEqual) { - var func = _dicCompareEntityValueReturnColumns.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(typeof(TEntity), t => { + public static void 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)); @@ -432,7 +469,7 @@ namespace FreeSql.Extensions.EntityUtil { 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(up, oldval, isEqual); + return func(entity1, entity2, isEqual); } static ConcurrentDictionary>> _dicSetEntityIncrByWithPropertyName = new ConcurrentDictionary>>(); @@ -441,10 +478,15 @@ namespace FreeSql.Extensions.EntityUtil { /// /// /// - /// - /// - public static void SetEntityIncrByWithPropertyName(this IFreeSql orm, TEntity item, string propertyName, int incrBy) { - var func = _dicSetEntityIncrByWithPropertyName.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(typeof(TEntity), t => { + /// + /// + /// + 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)); @@ -470,7 +512,53 @@ namespace FreeSql.Extensions.EntityUtil { } return Expression.Lambda>(Expression.Block(new[] { var1Parm }, exps), new[] { parm1, parm2, parm3 }).Compile(); }); - func(item, propertyName, incrBy); + func(entity, propertyName, incrBy); + } + + 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]; + exps.Add( + Expression.Assign( + Expression.MakeMemberAccess(var1Parm, prop), + Expression.Add( + Expression.MakeMemberAccess(var1Parm, prop), + Expression.Convert( + FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(prop.PropertyType, 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(); diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 31f88d0f..1b236d4f 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.4.15 + 0.4.16 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index 33eee69b..3eeb410b 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -71,6 +71,12 @@ namespace FreeSql { /// TSelect AsTable(Func tableRule); /// + /// 动态Type,在使用 Select<object> 后使用本方法,指定实体类型 + /// + /// + /// + TSelect AsType(Type entityType); + /// /// 返回即将执行的SQL语句 /// /// 指定字段 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect1.cs b/FreeSql/Interface/Curd/ISelect/ISelect1.cs index 414d6b23..2b448b5d 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect1.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect1.cs @@ -106,6 +106,13 @@ namespace FreeSql { /// ISelect As(string alias = "a"); + /// + /// 多表查询 + /// + /// + /// + /// + ISelect From(Expression, T2, ISelectFromExpression>> exp) where T2 : class; /// /// 多表查询 /// diff --git a/FreeSql/Interface/Curd/ISelect/ISelect2.cs b/FreeSql/Interface/Curd/ISelect/ISelect2.cs new file mode 100644 index 00000000..3ea773b6 --- /dev/null +++ b/FreeSql/Interface/Curd/ISelect/ISelect2.cs @@ -0,0 +1,40 @@ +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 { + + bool Any(Expression> exp); + Task AnyAsync(Expression> exp); + + DataTable ToDataTable(Expression> select); + Task ToDataTableAsync(Expression> select); + + List ToList(Expression> select); + Task> ToListAsync(Expression> select); + 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); + + ISelect Where(Expression> exp); + ISelect WhereIf(bool condition, Expression> exp); + + ISelectGrouping GroupBy(Expression> exp); + + ISelect OrderBy(Expression> column); + ISelect OrderByDescending(Expression> column); + } +} \ No newline at end of file diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index e10c2f78..36a52058 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -101,19 +101,27 @@ namespace FreeSql.Internal { } else { //dto 映射 var dtoProps = _dicReadAnonymousFieldDtoPropertys.GetOrAdd(initExp.NewExpression.Type, dtoType => dtoType.GetProperties()); - var dtoTb0 = _tables.First(); foreach (var dtoProp in dtoProps) { - if (dtoTb0.Table.Columns.TryGetValue(dtoProp.Name, out var trydtocol)) { - var child = new ReadAnonymousTypeInfo { - Property = dtoProp, - CsName = dtoProp.Name, - CsType = dtoProp.PropertyType - }; - parent.Childs.Add(child); - ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtoTb0.Parameter, dtoTb0.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString); + 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 + }; + 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} 没有一个属性名和 {dtoTb0.Table.Type.Name} 相同"); + if (parent.Childs.Any() == false) throw new Exception($"映射异常:{initExp.NewExpression.Type.Name} 没有一个属性名相同"); } return true; case ExpressionType.New: @@ -134,19 +142,27 @@ namespace FreeSql.Internal { //dto 映射 parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties; var dtoProps = _dicReadAnonymousFieldDtoPropertys.GetOrAdd(newExp.Type, dtoType => dtoType.GetProperties()); - var dtoTb0 = _tables.First(); foreach (var dtoProp in dtoProps) { - if (dtoTb0.Table.Columns.TryGetValue(dtoProp.Name, out var trydtocol)) { - var child = new ReadAnonymousTypeInfo { - Property = dtoProp, - CsName = dtoProp.Name, - CsType = dtoProp.PropertyType - }; - parent.Childs.Add(child); - ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtoTb0.Parameter, dtoTb0.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString); + 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 + }; + 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} 没有一个属性名和 {dtoTb0.Table.Type.Name} 相同"); + if (parent.Childs.Any() == false) throw new Exception($"映射异常:{newExp.Type.Name} 没有一个属性名相同"); } return true; } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index e06370af..1788448c 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -74,7 +74,7 @@ namespace FreeSql.Internal.CommonProvider { _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) _orm.CodeFirst.SyncStructure(); + if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure(); } public TSelect TrackToList(Action track) { @@ -519,6 +519,15 @@ namespace FreeSql.Internal.CommonProvider { 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); + if (newtb == null) throw new Exception("ISelect.AsType 参数错误,请传入正确的实体类型"); + _tables[0].Table = newtb; + 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); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 1e6a9775..eb506d56 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -70,6 +70,7 @@ 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; } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs new file mode 100644 index 00000000..12b700b2 --- /dev/null +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs @@ -0,0 +1,152 @@ +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq.Expressions; +using System.Threading.Tasks; + +namespace FreeSql.Internal.CommonProvider { + + 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 }); + } + + 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); + } + + 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); + } + + 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); + } + + 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.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); + } + + 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); + } + + 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); + } + + 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); + } + + 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.WhereIf(bool condition, Expression> exp) { + if (condition) return this.Where(null); + if (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(); + } + + 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/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index f4d66d08..72caee6c 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -385,7 +385,7 @@ namespace FreeSql.Internal { } if (isLazy) { - cscode.Append(" public bool __lazy__").Append(pnv.Name).AppendLine(" = false;") + 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") @@ -460,7 +460,7 @@ namespace FreeSql.Internal { } if (isLazy) { - cscode.Append(" public bool __lazy__").Append(pnv.Name).AppendLine(" = false;") + 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") @@ -550,7 +550,7 @@ namespace FreeSql.Internal { } if (isLazy) { - cscode.Append(" public bool __lazy__").Append(pnv.Name).AppendLine(" = false;") + 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") @@ -1009,6 +1009,17 @@ namespace FreeSql.Internal { static MethodInfo MethodJTokenParse = typeof(JToken).GetMethod("Parse", new[] { typeof(string) }); static MethodInfo MethodJObjectParse = typeof(JObject).GetMethod("Parse", new[] { typeof(string) }); static MethodInfo MethodJArrayParse = typeof(JArray).GetMethod("Parse", new[] { typeof(string) }); + 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() }); public static Expression GetDataReaderValueBlockExpression(Type type, Expression value) { var returnTarget = Expression.Label(typeof(object)); var valueExp = Expression.Variable(typeof(object), "locvalue"); @@ -1024,7 +1035,7 @@ namespace FreeSql.Internal { var label = Expression.Label(typeof(int)); return Expression.IfThenElse( Expression.TypeEqual(valueExp, type), - Expression.Return(returnTarget, valueExp), + Expression.Return(returnTarget, valueExp), Expression.Block( new[] { arrNewExp, arrExp, arrLenExp, arrXExp, arrReadValExp }, Expression.Assign(arrExp, Expression.TypeAs(valueExp, typeof(Array))), @@ -1051,10 +1062,15 @@ 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)))); - switch(type.FullName) { - case "System.Guid": return Expression.IfThenElse( + Expression tryparseExp = null; + Expression tryparseBooleanExp = null; + ParameterExpression tryparseVarExp = null; + switch (type.FullName) { + case "System.Guid": + return Expression.IfThenElse( Expression.TypeEqual(valueExp, type), Expression.Return(returnTarget, valueExp), Expression.Return(returnTarget, Expression.Convert(Expression.Call(MethodGuidParse, Expression.Convert(valueExp, typeof(string))), typeof(object))) @@ -1069,22 +1085,190 @@ namespace FreeSql.Internal { 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 "System.TimeSpan": return Expression.IfThenElse( + case "System.TimeSpan": + return Expression.IfThenElse( Expression.TypeEqual(valueExp, type), Expression.Return(returnTarget, valueExp), Expression.Return(returnTarget, Expression.Convert(Expression.Call(MethodTimeSpanFromSeconds, Expression.Call(MethodDoubleParse, Expression.Call(MethodToString, valueExp))), 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.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; } + Expression switchExp = null; + if (tryparseExp != null) + switchExp = Expression.Switch( + Expression.Constant(type), + Expression.SwitchCase(tryparseExp, + 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.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 + switchExp = Expression.Return(returnTarget, Expression.Call(MethodConvertChangeType, valueExp, Expression.Constant(type, typeof(Type)))); + return Expression.IfThenElse( Expression.TypeEqual(valueExp, type), Expression.Return(returnTarget, valueExp), - Expression.Return(returnTarget, Expression.Call(MethodConvertChangeType, valueExp, Expression.Constant(type, typeof(Type)))) + Expression.IfThenElse( + Expression.TypeEqual(valueExp, typeof(string)), + switchExp, + Expression.Return(returnTarget, Expression.Call(MethodConvertChangeType, valueExp, Expression.Constant(type, typeof(Type)))) + ) ); }; return Expression.Block( new[] { valueExp }, - Expression.Assign(valueExp, value), + Expression.Assign(valueExp, Expression.Convert(value, typeof(object))), Expression.IfThenElse( Expression.Or( Expression.Equal(valueExp, Expression.Constant(null)), @@ -1097,9 +1281,9 @@ namespace FreeSql.Internal { ); } public static object GetDataReaderValue(Type type, object value) { - if (value == null || value == DBNull.Value) return null; + //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(), valueType => { + 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(); @@ -1233,7 +1417,7 @@ namespace FreeSql.Internal { #endregion } internal static object GetDataReaderValue22(Type type, object value) { - if (value == null || value == DBNull.Value) return null; + if (value == null || value == DBNull.Value) return Activator.CreateInstance(type); if (type.FullName == "System.Byte[]") return value; if (type.IsArray) { var elementType = type.GetElementType(); diff --git a/FreeSql/MySql/Curd/MySqlSelect.cs b/FreeSql/MySql/Curd/MySqlSelect.cs index 2f5e04dd..812a39b8 100644 --- a/FreeSql/MySql/Curd/MySqlSelect.cs +++ b/FreeSql/MySql/Curd/MySqlSelect.cs @@ -78,6 +78,7 @@ 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; } @@ -88,6 +89,10 @@ namespace FreeSql.MySql.Curd { 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.GetAllFieldExpressionTree().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.GetAllFieldExpressionTree().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.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); diff --git a/FreeSql/Oracle/Curd/OracleSelect.cs b/FreeSql/Oracle/Curd/OracleSelect.cs index 1f355b84..09234bf1 100644 --- a/FreeSql/Oracle/Curd/OracleSelect.cs +++ b/FreeSql/Oracle/Curd/OracleSelect.cs @@ -90,6 +90,7 @@ 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; } @@ -100,6 +101,10 @@ namespace FreeSql.Oracle.Curd { 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.GetAllFieldExpressionTree().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.GetAllFieldExpressionTree().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.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); diff --git a/FreeSql/PostgreSQL/Curd/PostgreSQLSelect.cs b/FreeSql/PostgreSQL/Curd/PostgreSQLSelect.cs index 9a788d73..e441722c 100644 --- a/FreeSql/PostgreSQL/Curd/PostgreSQLSelect.cs +++ b/FreeSql/PostgreSQL/Curd/PostgreSQLSelect.cs @@ -80,6 +80,7 @@ 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; } @@ -90,10 +91,10 @@ namespace FreeSql.PostgreSQL.Curd { 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.GetAllFieldExpressionTree().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.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRulesInvoke, _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.GetAllFieldExpressionTree().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.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); diff --git a/FreeSql/SqlServer/Curd/SqlServerSelect.cs b/FreeSql/SqlServer/Curd/SqlServerSelect.cs index b2713ac0..4ba02704 100644 --- a/FreeSql/SqlServer/Curd/SqlServerSelect.cs +++ b/FreeSql/SqlServer/Curd/SqlServerSelect.cs @@ -175,6 +175,7 @@ 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; } @@ -185,10 +186,10 @@ namespace FreeSql.SqlServer.Curd { 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.GetAllFieldExpressionTree().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.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRulesInvoke, _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.GetAllFieldExpressionTree().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.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm); diff --git a/FreeSql/Sqlite/Curd/SqliteSelect.cs b/FreeSql/Sqlite/Curd/SqliteSelect.cs index 334dc7b4..6cd48ac2 100644 --- a/FreeSql/Sqlite/Curd/SqliteSelect.cs +++ b/FreeSql/Sqlite/Curd/SqliteSelect.cs @@ -78,6 +78,7 @@ 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; } @@ -88,6 +89,10 @@ namespace FreeSql.Sqlite.Curd { 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.GetAllFieldExpressionTree().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.GetAllFieldExpressionTree().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.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm);