From 0068474992eb8f7dc2baa28950478cef96a1bc8f Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 18 Jan 2019 19:17:40 +0800 Subject: [PATCH] =?UTF-8?q?Reflection=20=E6=9B=BF=E6=8D=A2=20ExpressionTre?= =?UTF-8?q?e=EF=BC=8C=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95=E5=B7=B2?= =?UTF-8?q?=E9=80=9A=E8=BF=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MySqlAdoTest.cs | 5 + .../PostgreSQL/PostgreSQLCodeFirstTest.cs | 4 +- FreeSql.Tests/UnitTest1.cs | 20 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/Interface/IAdo.cs | 80 ++++- FreeSql/Internal/CommonExpression.cs | 5 +- .../CommonProvider/AdoProvider/AdoProvider.cs | 18 +- .../AdoProvider/AdoProviderAsync.cs | 27 +- .../SelectProvider/Select0Provider.cs | 187 +++++++++-- FreeSql/Internal/UtilsExpressionTree.cs | 294 +++++++++++++----- FreeSql/MySql/Curd/MySqlSelect.cs | 18 +- FreeSql/Oracle/Curd/OracleSelect.cs | 18 +- FreeSql/PostgreSQL/Curd/PostgreSQLSelect.cs | 18 +- FreeSql/SqlServer/Curd/SqlServerSelect.cs | 18 +- FreeSql/Sqlite/Curd/SqliteSelect.cs | 18 +- readme.md | 22 +- 16 files changed, 537 insertions(+), 217 deletions(-) diff --git a/FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs b/FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs index f3549082..6804c4a1 100644 --- a/FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs +++ b/FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs @@ -56,6 +56,11 @@ namespace FreeSql.Tests.PerformanceTest { time.Stop(); sb.AppendLine($"Elapsed: {time.Elapsed}; Query Tuple Counts: {t4.Count}; ORM: FreeSql*"); + time.Restart(); + var t41 = g.mysql.Select().ToList<(int, string, string)>("id,title,url"); + time.Stop(); + sb.AppendLine($"Elapsed: {time.Elapsed}; Query ToList Counts: {t41.Count}; ORM: FreeSql*"); + time.Restart(); var t5 = g.mysql.Ado.Query("select * from song"); time.Stop(); diff --git a/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs index ff6d8d11..74720b16 100644 --- a/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs +++ b/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -278,8 +278,8 @@ namespace FreeSql.Tests.PostgreSQL { testFielLongArrayNullable = new long?[] { 500, 600, 700, null, 999, 1000 }, testFielLongNullable = long.MinValue }; - var item3 = insert.AppendData(item2).ExecuteInserted(); - var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + var item3 = insert.AppendData(item2).ExecuteInserted().First(); + var newitem2 = select.Where(a => a.Id == item3.Id).ToOne(); var items = select.ToList(); } diff --git a/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/UnitTest1.cs index 795ed340..1fc120eb 100644 --- a/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/UnitTest1.cs @@ -27,7 +27,7 @@ namespace FreeSql.Tests { .Any() ).Any() - ).ToSql(); + ).ToList(); var groupby = g.mysql.Select().From((s, b, c) => s @@ -38,7 +38,7 @@ namespace FreeSql.Tests { .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) .OrderBy(a => a.Key.tt2) .OrderByDescending(a => a.Count()) - .ToSql(a => new { a.Key.tt2, cou1 = a.Count(), arg1 = a.Avg(a.Key.mod4), + .ToList(a => new { a.Key.tt2, cou1 = a.Count(), arg1 = a.Avg(a.Key.mod4), ccc2 = a.Key.tt2 ?? "now()", //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") }); @@ -47,13 +47,13 @@ namespace FreeSql.Tests { var arrg222 = g.mysql.Select().ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); - var t1 = g.mysql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); - var t2 = g.mysql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); + var t1 = g.mysql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); + var t2 = g.mysql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); - var sql1 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).ToSql(); - var sql2 = select.LeftJoin((a, b) => a.TypeGuid == b.Guid && b.Name == "111").ToSql(); - var sql3 = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").ToSql(); + var sql1 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).ToList(); + var sql2 = select.LeftJoin((a, b) => a.TypeGuid == b.Guid && b.Name == "111").ToList(); + var sql3 = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").ToList(); //g.mysql.Select().Join((a, b, c) => new Model.JoinResult3( // Model.JoinType.LeftJoin, a.TypeGuid == b.Guid, @@ -69,7 +69,7 @@ namespace FreeSql.Tests { var sql4 = select.From((s, b, c) => s .InnerJoin(a => a.TypeGuid == b.Guid) .LeftJoin(a => c.Id == b.ParentId) - .Where(a => b.Name == "xxx")).ToSql(); + .Where(a => b.Name == "xxx")).ToList(); //.Where(a => a.Id == 1).ToSql(); @@ -94,12 +94,12 @@ namespace FreeSql.Tests { } }); - var ttt122 = g.mysql.Select().Where(a => a.Id > 0).ToSql(); + var ttt122 = g.mysql.Select().Where(a => a.Id > 0).ToList(); - var sql5 = g.mysql.Select().From((s, b, c) => s).Where((a, b, c) => a.Id == b.ParentId).ToSql(); + var sql5 = g.mysql.Select().From((s, b, c) => s).Where((a, b, c) => a.Id == b.ParentId).ToList(); diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 8ab3ad7b..c26670f2 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.0.7 + 0.0.8 true YeXiangQin 打造 .NETCore 最方便的 ORM,DbFirst 与 CodeFirst 混合使用,提供从实体同步数据库,或者从数据库生成实体代码,支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite 数据库。 diff --git a/FreeSql/Interface/IAdo.cs b/FreeSql/Interface/IAdo.cs index 482fe438..61cf4433 100644 --- a/FreeSql/Interface/IAdo.cs +++ b/FreeSql/Interface/IAdo.cs @@ -50,7 +50,7 @@ namespace FreeSql { #endregion /// - /// 若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + /// 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 /// /// /// @@ -58,18 +58,38 @@ namespace FreeSql { /// void ExecuteReader(Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + /// 查询,ExecuteReader(dr => {}, "select * from user where age > @age", new { age = 25 }) + /// + /// + /// + void ExecuteReader(Action readerHander, string cmdText, object parms = null); + /// + /// 查询 /// /// /// object[][] ExecuteArray(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + /// 查询,ExecuteArray("select * from user where age > @age", new { age = 25 }) + /// + /// + /// + /// + object[][] ExecuteArray(string cmdText, object parms = null); + /// + /// 查询 /// /// /// DataTable ExecuteDataTable(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// + /// 查询,ExecuteDataTable("select * from user where age > @age", new { age = 25 }) + /// + /// + /// + /// + DataTable ExecuteDataTable(string cmdText, object parms = null); + /// /// 在【主库】执行 /// /// @@ -77,12 +97,26 @@ namespace FreeSql { /// int ExecuteNonQuery(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// + /// 在【主库】执行,ExecuteNonQuery("delete from user where age > @age", new { age = 25 }) + /// + /// + /// + /// + int ExecuteNonQuery(string cmdText, object parms = null); + /// /// 在【主库】执行 /// /// /// /// object ExecuteScalar(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + /// + /// 在【主库】执行,ExecuteScalar("select 1 from user where age > @age", new { age = 25 }) + /// + /// + /// + /// + object ExecuteScalar(string cmdText, object parms = null); /// /// 执行SQL返回对象集合,Query<User>("select * from user where age > @age", new SqlParameter { ParameterName = "age", Value = 25 }) @@ -104,7 +138,7 @@ namespace FreeSql { #region async /// - /// 若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + /// 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 /// /// /// @@ -112,18 +146,38 @@ namespace FreeSql { /// Task ExecuteReaderAsync(Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + /// 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > @age", new { age = 25 }) + /// + /// + /// + Task ExecuteReaderAsync(Func readerHander, string cmdText, object parms = null); + /// + /// 查询 /// /// /// Task ExecuteArrayAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// - /// 若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + /// 查询,ExecuteArrayAsync("select * from user where age > @age", new { age = 25 }) + /// + /// + /// + /// + Task ExecuteArrayAsync(string cmdText, object parms = null); + /// + /// 查询 /// /// /// Task ExecuteDataTableAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// + /// 查询,ExecuteDataTableAsync("select * from user where age > @age", new { age = 25 }) + /// + /// + /// + /// + Task ExecuteDataTableAsync(string cmdText, object parms = null); + /// /// 在【主库】执行 /// /// @@ -131,12 +185,26 @@ namespace FreeSql { /// Task ExecuteNonQueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// + /// 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > @age", new { age = 25 }) + /// + /// + /// + /// + Task ExecuteNonQueryAsync(string cmdText, object parms = null); + /// /// 在【主库】执行 /// /// /// /// Task ExecuteScalarAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + /// + /// 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > @age", new { age = 25 }) + /// + /// + /// + /// + Task ExecuteScalarAsync(string cmdText, object parms = null); /// /// 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > @age", new SqlParameter { ParameterName = "age", Value = 25 }) diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 73a6d9e7..0f778e52 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -1,6 +1,7 @@ using FreeSql.Internal.Model; using System; using System.Collections.Generic; +using System.Data.Common; using System.Linq; using System.Linq.Expressions; using System.Reflection; @@ -90,8 +91,8 @@ namespace FreeSql.Internal { if (index >= 0) field.Append(" as").Append(++index); return false; } - internal object ReadAnonymous(ReadAnonymousTypeInfo parent, object[] dr, ref int index) { - if (parent.Childs.Any() == false) return dr[++index]; + internal object ReadAnonymous(ReadAnonymousTypeInfo parent, DbDataReader dr, ref int index) { + if (parent.Childs.Any() == false) return dr.GetValue(++index); switch (parent.ConsturctorType) { case ReadAnonymousTypeInfoConsturctorType.Arguments: var args = new object[parent.Childs.Count]; diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs index 67d666d7..f08afce6 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs @@ -62,23 +62,19 @@ namespace FreeSql.Internal.CommonProvider { if (isThrowException) throw e; } - public List Query(string sql, object parms = null) => Query(CommandType.Text, sql, GetDbParamtersByObject(sql, parms)); + public List Query(string cmdText, object parms = null) => Query(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); public List Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { var names = new Dictionary(StringComparer.CurrentCultureIgnoreCase); var ret = new List(); var type = typeof(T); - var defaultValue = default(T); ExecuteReader(dr => { if (names.Any() == false) for (var a = 0; a < dr.FieldCount; a++) names.Add(dr.GetName(a), a); - object[] values = new object[names.Count]; - dr.GetValues(values); - var read = Utils.ExecuteArrayRowReadClassOrTuple(type, names, values, 0); - ret.Add(read.Value == null ? defaultValue : (T)read.Value); + ret.Add((T)Utils.ExecuteArrayRowReadClassOrTuple(type, names, dr, 0).Value); }, cmdType, cmdText, cmdParms); return ret; } - public void ExecuteReader(Action readerHander, string sql, object parms = null) => ExecuteReader(readerHander, CommandType.Text, sql, GetDbParamtersByObject(sql, parms)); + public void ExecuteReader(Action readerHander, string cmdText, object parms = null) => ExecuteReader(readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); public void ExecuteReader(Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { var dt = DateTime.Now; var logtxt = new StringBuilder(); @@ -172,7 +168,7 @@ namespace FreeSql.Internal.CommonProvider { LoggerException(pool, pc.cmd, ex, dt, logtxt); pc.cmd.Parameters.Clear(); } - public object[][] ExecuteArray(string sql, object parms = null) => ExecuteArray(CommandType.Text, sql, GetDbParamtersByObject(sql, parms)); + public object[][] ExecuteArray(string cmdText, object parms = null) => ExecuteArray(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); public object[][] ExecuteArray(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { List ret = new List(); ExecuteReader(dr => { @@ -182,7 +178,7 @@ namespace FreeSql.Internal.CommonProvider { }, cmdType, cmdText, cmdParms); return ret.ToArray(); } - public DataTable ExecuteDataTable(string sql, object parms = null) => ExecuteDataTable(CommandType.Text, sql, GetDbParamtersByObject(sql, parms)); + public DataTable ExecuteDataTable(string cmdText, object parms = null) => ExecuteDataTable(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); public DataTable ExecuteDataTable(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { var ret = new DataTable(); ExecuteReader(dr => { @@ -194,7 +190,7 @@ namespace FreeSql.Internal.CommonProvider { }, cmdType, cmdText, cmdParms); return ret; } - public int ExecuteNonQuery(string sql, object parms = null) => ExecuteNonQuery(CommandType.Text, sql, GetDbParamtersByObject(sql, parms)); + public int ExecuteNonQuery(string cmdText, object parms = null) => ExecuteNonQuery(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); public int ExecuteNonQuery(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { var dt = DateTime.Now; var logtxt = new StringBuilder(); @@ -219,7 +215,7 @@ namespace FreeSql.Internal.CommonProvider { pc.cmd.Parameters.Clear(); return val; } - public object ExecuteScalar(string sql, object parms = null) => ExecuteScalar(CommandType.Text, sql, GetDbParamtersByObject(sql, parms)); + public object ExecuteScalar(string cmdText, object parms = null) => ExecuteScalar(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); public object ExecuteScalar(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { var dt = DateTime.Now; var logtxt = new StringBuilder(); diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs index 40faba24..b9c0fd3f 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs @@ -9,25 +9,20 @@ using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider { partial class AdoProvider { - public Task> QueryAsync(string sql, object parms = null) => QueryAsync(CommandType.Text, sql, GetDbParamtersByObject(sql, parms)); + public Task> QueryAsync(string cmdText, object parms = null) => QueryAsync(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); async public Task> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { var names = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - var ds = new List(); - await ExecuteReaderAsync(async dr => { + var ret = new List(); + var type = typeof(T); + await ExecuteReaderAsync(dr => { if (names.Any() == false) for (var a = 0; a < dr.FieldCount; a++) names.Add(dr.GetName(a), a); - object[] values = new object[dr.FieldCount]; - for (int a = 0; a < values.Length; a++) if (!await dr.IsDBNullAsync(a)) values[a] = await dr.GetFieldValueAsync(a); - ds.Add(values); + ret.Add((T)Utils.ExecuteArrayRowReadClassOrTuple(type, names, dr, 0).Value); + return Task.CompletedTask; }, cmdType, cmdText, cmdParms); - var ret = new List(); - foreach (var row in ds) { - var read = Utils.ExecuteArrayRowReadClassOrTuple(typeof(T), names, row); - ret.Add(read.Value == null ? default(T) : (T) read.Value); - } return ret; } - public Task ExecuteReaderAsync(Func readerHander, string sql, object parms = null) => ExecuteReaderAsync(readerHander, CommandType.Text, sql, GetDbParamtersByObject(sql, parms)); + public Task ExecuteReaderAsync(Func readerHander, string cmdText, object parms = null) => ExecuteReaderAsync(readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); async public Task ExecuteReaderAsync(Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { var dt = DateTime.Now; var logtxt = new StringBuilder(); @@ -121,7 +116,7 @@ namespace FreeSql.Internal.CommonProvider { LoggerException(pool, cmd, ex, dt, logtxt); cmd.Parameters.Clear(); } - public Task ExecuteArrayAsync(string sql, object parms = null) => ExecuteArrayAsync(CommandType.Text, sql, GetDbParamtersByObject(sql, parms)); + public Task ExecuteArrayAsync(string cmdText, object parms = null) => ExecuteArrayAsync(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); async public Task ExecuteArrayAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { List ret = new List(); await ExecuteReaderAsync(async dr => { @@ -131,7 +126,7 @@ namespace FreeSql.Internal.CommonProvider { }, cmdType, cmdText, cmdParms); return ret.ToArray(); } - public Task ExecuteDataTableAsync(string sql, object parms = null) => ExecuteDataTableAsync(CommandType.Text, sql, GetDbParamtersByObject(sql, parms)); + public Task ExecuteDataTableAsync(string cmdText, object parms = null) => ExecuteDataTableAsync(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); async public Task ExecuteDataTableAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { var ret = new DataTable(); await ExecuteReaderAsync(async dr => { @@ -143,7 +138,7 @@ namespace FreeSql.Internal.CommonProvider { }, cmdType, cmdText, cmdParms); return ret; } - public Task ExecuteNonQueryAsync(string sql, object parms = null) => ExecuteNonQueryAsync(CommandType.Text, sql, GetDbParamtersByObject(sql, parms)); + public Task ExecuteNonQueryAsync(string cmdText, object parms = null) => ExecuteNonQueryAsync(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); async public Task ExecuteNonQueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { var dt = DateTime.Now; var logtxt = new StringBuilder(); @@ -168,7 +163,7 @@ namespace FreeSql.Internal.CommonProvider { cmd.Parameters.Clear(); return val; } - public Task ExecuteScalarAsync(string sql, object parms = null) => ExecuteScalarAsync(CommandType.Text, sql, GetDbParamtersByObject(sql, parms)); + public Task ExecuteScalarAsync(string cmdText, object parms = null) => ExecuteScalarAsync(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); async public Task ExecuteScalarAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { var dt = DateTime.Now; var logtxt = new StringBuilder(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 35ff52b1..0721bde7 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -147,11 +147,10 @@ namespace FreeSql.Internal.CommonProvider { return _orm.Cache.Shell(_cache.key, _cache.seconds, () => { List ret = new List(); Type type = typeof(TTuple); - var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql, _params.ToArray()); - foreach (var dr in ds) { + _orm.Ado.ExecuteReader(dr => { var read = Utils.ExecuteArrayRowReadClassOrTuple(type, null, dr); - ret.Add(read.Value == null ? default(TTuple) : (TTuple)read.Value); - } + ret.Add((TTuple)read.Value); + }, CommandType.Text, sql, _params.ToArray()); return ret; }); } @@ -162,19 +161,40 @@ namespace FreeSql.Internal.CommonProvider { return _orm.Cache.ShellAsync(_cache.key, _cache.seconds, async () => { List ret = new List(); Type type = typeof(TTuple); - var ds = await _orm.Ado.ExecuteArrayAsync(CommandType.Text, sql, _params.ToArray()); - foreach (var dr in ds) { + await _orm.Ado.ExecuteReaderAsync(dr => { var read = Utils.ExecuteArrayRowReadClassOrTuple(type, null, dr); - ret.Add(read.Value == null ? default(TTuple) : (TTuple)read.Value); - } + ret.Add((TTuple)read.Value); + return Task.CompletedTask; + }, CommandType.Text, sql, _params.ToArray()); return ret; }); } public List ToList() { - return this.ToListMapReader(this.GetAllField()); + var af = this.GetAllFieldExpressionTree(); + var sql = this.ToSql(af.Field); + if (_cache.seconds > 0 && string.IsNullOrEmpty(_cache.key)) _cache.key = $"{sql}{string.Join("|", _params.Select(a => a.Value))}"; + + return _orm.Cache.Shell(_cache.key, _cache.seconds, () => { + List ret = new List(); + _orm.Ado.ExecuteReader(dr => { + ret.Add(af.Read(dr)); + }, CommandType.Text, sql, _params.ToArray()); + return ret; + }); } - public Task> ToListAsync() { - return this.ToListMapReaderAsync(this.GetAllField()); + async public Task> ToListAsync() { + var af = this.GetAllFieldExpressionTree(); + var sql = this.ToSql(af.Field); + if (_cache.seconds > 0 && string.IsNullOrEmpty(_cache.key)) _cache.key = $"{sql}{string.Join("|", _params.Select(a => a.Value))}"; + + return await _orm.Cache.ShellAsync(_cache.key, _cache.seconds, async () => { + List ret = new List(); + await _orm.Ado.ExecuteReaderAsync(dr => { + ret.Add(af.Read(dr)); + return Task.CompletedTask; + }, CommandType.Text, sql, _params.ToArray()); + return ret; + }); } public T1 ToOne() { this.Limit(1); @@ -189,27 +209,30 @@ namespace FreeSql.Internal.CommonProvider { var sql = this.ToSql(af.field); if (_cache.seconds > 0 && string.IsNullOrEmpty(_cache.key)) _cache.key = $"{sql}{string.Join("|", _params.Select(a => a.Value))}"; - var drarr = _orm.Cache.Shell(_cache.key, _cache.seconds, () => _orm.Ado.ExecuteArray(CommandType.Text, sql, _params.ToArray())); - var ret = new List(); - for (var a = 0; a < drarr.Length; a++) { - var dr = drarr[a]; - var index = -1; - ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index)); - } - return ret; + return _orm.Cache.Shell(_cache.key, _cache.seconds, () => { + List ret = new List(); + Type type = typeof(TReturn); + _orm.Ado.ExecuteReader(dr => { + var index = -1; + ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index)); + }, CommandType.Text, sql, _params.ToArray()); + return ret; + }); } async protected Task> ToListMapReaderAsync((ReadAnonymousTypeInfo map, string field) af) { var sql = this.ToSql(af.field); if (_cache.seconds > 0 && string.IsNullOrEmpty(_cache.key)) _cache.key = $"{sql}{string.Join("|", _params.Select(a => a.Value))}"; - var drarr = await _orm.Cache.ShellAsync(_cache.key, _cache.seconds, () => _orm.Ado.ExecuteArrayAsync(CommandType.Text, sql, _params.ToArray())); - var ret = new List(); - for (var a = 0; a < drarr.Length; a++) { - var dr = drarr[a]; - var index = -1; - ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index)); - } - return ret; + return await _orm.Cache.ShellAsync(_cache.key, _cache.seconds, async () => { + List ret = new List(); + Type type = typeof(TReturn); + await _orm.Ado.ExecuteReaderAsync(dr => { + var index = -1; + ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index)); + return Task.CompletedTask; + }, CommandType.Text, sql, _params.ToArray()); + return ret; + }); } protected (ReadAnonymousTypeInfo map, string field) GetExpressionField(Expression newexp) { var map = new ReadAnonymousTypeInfo(); @@ -219,15 +242,113 @@ namespace FreeSql.Internal.CommonProvider { _commonExpression.ReadAnonymousField(_tables, field, map, ref index, newexp, null); return (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null); } - protected (ReadAnonymousTypeInfo map, string field) GetAllField() { - var type = typeof(T1); - var map = new ReadAnonymousTypeInfo { Consturctor = type.GetConstructor(new Type[0]), ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties }; + static ConcurrentDictionary _dicConstructor = new ConcurrentDictionary(); + static ConcurrentDictionary _dicGetAllFieldExpressionTree = new ConcurrentDictionary(); + public class GetAllFieldExpressionTreeInfo { + public string Field { get; set; } + public Func Read { get; set; } + } + protected GetAllFieldExpressionTreeInfo GetAllFieldExpressionTree() { + var key = string.Join("+", _tables.Select(a => $"{a.Table.DbName}-{a.Alias}")); + return _dicGetAllFieldExpressionTree.GetOrAdd(key, s => { + var type = _tables.First().Table.Type; + + var rowExp = Expression.Parameter(typeof(DbDataReader), "row"); + var returnTarget = Expression.Label(type); + var retExp = Expression.Variable(type, "ret"); + var dataIndexExp = Expression.Variable(typeof(int), "dataIndex"); + var readExp = Expression.Variable(typeof(Utils.RowInfo), "read"); + var readExpValue = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyValue); + var readExpDataIndex = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyDataIndex); + var blockExp = new List(); + var ctor = type.GetConstructor(new Type[0]) ?? type.GetConstructors().First(); + blockExp.AddRange(new Expression[] { + Expression.Assign(retExp, Expression.New(ctor, ctor.GetParameters().Select(a => Expression.Default(a.ParameterType)))), + Expression.Assign(dataIndexExp, Expression.Constant(0)) + }); + + var field = new StringBuilder(); + var dicfield = new Dictionary(); + var tb = _tables.First(); + var index = 0; + var ps = _tables.First().Table.Properties; + foreach (var prop in ps.Values) { + if (tb.Table.ColumnsByCs.TryGetValue(prop.Name, out var col)) { //普通字段 + if (index > 0) field.Append(", "); + var quoteName = _commonUtils.QuoteSqlName(col.Attribute.Name); + field.Append(_commonUtils.QuoteReadColumn(col.CsType, $"{tb.Alias}.{quoteName}")); + ++index; + if (dicfield.ContainsKey(quoteName)) field.Append(" as").Append(index); + else dicfield.Add(quoteName, true); + } else { + var tb2 = _tables.Where(a => a.Table.Type == prop.PropertyType && a.Alias.Contains(prop.Name)).FirstOrDefault(); + if (tb2 == null && ps.Where(pw => pw.Value.PropertyType == prop.PropertyType).Count() == 1) tb2 = _tables.Where(a => a.Table.Type == prop.PropertyType).FirstOrDefault(); + if (tb2 == null) continue; + foreach (var col2 in tb2.Table.Columns.Values) { + if (index > 0) field.Append(", "); + var quoteName = _commonUtils.QuoteSqlName(col2.Attribute.Name); + field.Append(_commonUtils.QuoteReadColumn(col2.CsType, $"{tb2.Alias}.{quoteName}")); + ++index; + if (dicfield.ContainsKey(quoteName)) field.Append(" as").Append(index); + else dicfield.Add(quoteName, true); + } + } + //只读到二级属性 + var propGetSetMethod = prop.GetSetMethod(); + Expression readExpAssign = null; //加速缓存 + if (prop.PropertyType.IsArray) readExpAssign = Expression.New(Utils.RowInfo.Constructor, + Expression.Call(Utils.MethodGetDataReaderValue, new Expression[] { Expression.Constant(prop.PropertyType), Expression.Call(rowExp, Utils.MethodDataReaderGetValue, dataIndexExp) }), + Expression.Add(dataIndexExp, Expression.Constant(1)) + ); + else { + var proptypeGeneric = prop.PropertyType; + if (proptypeGeneric.FullName.StartsWith("System.Nullable`1[")) proptypeGeneric = proptypeGeneric.GenericTypeArguments.First(); + if (proptypeGeneric.IsEnum || + Utils.dicExecuteArrayRowReadClassOrTuple.ContainsKey(proptypeGeneric)) readExpAssign = Expression.New(Utils.RowInfo.Constructor, + Expression.Call(Utils.MethodGetDataReaderValue, new Expression[] { Expression.Constant(prop.PropertyType), Expression.Call(rowExp, Utils.MethodDataReaderGetValue, dataIndexExp) }), + Expression.Add(dataIndexExp, Expression.Constant(1)) + ); + else { + readExpAssign = Expression.Call(Utils.MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(prop.PropertyType), Expression.Constant(null, typeof(Dictionary)), rowExp, dataIndexExp }); + } + } + blockExp.AddRange(new Expression[] { + //以下注释部分为【严格读取】,会损失一点性能 + //Expression.IfThen(Expression.Not(Expression.And( + // Expression.NotEqual(namesExp, Expression.Constant(null)), + // Expression.Not(Expression.Call(namesExp, namesExp.Type.GetMethod("TryGetValue"), Expression.Constant(prop.Name), tryidxExp)))), + // Expression.Block( + Expression.Assign(readExp, readExpAssign), + Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp), + Expression.Assign(dataIndexExp, readExpDataIndex)), + Expression.IfThenElse(Expression.Equal(readExpValue, Expression.Constant(null)), + Expression.Call(retExp, propGetSetMethod, Expression.Default(prop.PropertyType)), + Expression.Call(retExp, propGetSetMethod, Expression.Convert(readExpValue, prop.PropertyType))) + // ) + //) + }); + } + blockExp.AddRange(new Expression[] { + Expression.Return(returnTarget, retExp), + Expression.Label(returnTarget, Expression.Default(type)) + }); + return new GetAllFieldExpressionTreeInfo { + Field = field.ToString(), + Read = Expression.Lambda>(Expression.Block(new[] { retExp, dataIndexExp, readExp }, blockExp), new[] { rowExp }).Compile() + }; + }); + } + protected (ReadAnonymousTypeInfo map, string field) GetAllFieldReflection() { + var type = _tables.First().Table.Type; + var constructor = _dicConstructor.GetOrAdd(type, s => type.GetConstructor(new Type[0])); + var map = new ReadAnonymousTypeInfo { Consturctor = constructor, ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties }; + var field = new StringBuilder(); var dicfield = new Dictionary(); var tb = _tables.First(); var index = 0; - var ps = type.GetProperties(); - foreach (var p in ps) { + var ps = _tables.First().Table.Properties; + foreach (var p in ps.Values) { var child = new ReadAnonymousTypeInfo { Property = p, CsName = p.Name }; if (tb.Table.ColumnsByCs.TryGetValue(p.Name, out var col)) { //普通字段 if (index > 0) field.Append(", "); @@ -238,7 +359,7 @@ namespace FreeSql.Internal.CommonProvider { else dicfield.Add(quoteName, true); } else { var tb2 = _tables.Where(a => a.Table.Type == p.PropertyType && a.Alias.Contains(p.Name)).FirstOrDefault(); - if (tb2 == null && ps.Where(pw => pw.PropertyType == p.PropertyType).Count() == 1) tb2 = _tables.Where(a => a.Table.Type == p.PropertyType).FirstOrDefault(); + if (tb2 == null && ps.Where(pw => pw.Value.PropertyType == p.PropertyType).Count() == 1) tb2 = _tables.Where(a => a.Table.Type == p.PropertyType).FirstOrDefault(); if (tb2 == null) continue; child.Consturctor = tb2.Table.Type.GetConstructor(new Type[0]); child.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties; diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 44a3fa7a..b6c5c4b1 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -7,6 +7,8 @@ using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Data; +using System.Data.Common; using System.Diagnostics; using System.Linq; using System.Linq.Expressions; @@ -111,7 +113,7 @@ namespace FreeSql.Internal { return ret.ToArray(); } - static Dictionary dicExecuteArrayRowReadClassOrTuple = new Dictionary { + internal static Dictionary dicExecuteArrayRowReadClassOrTuple = new Dictionary { [typeof(bool)] = true, [typeof(sbyte)] = true, [typeof(short)] = true, @@ -164,7 +166,7 @@ namespace FreeSql.Internal { [typeof(JObject)] = true, [typeof(JArray)] = true, }; - static ConcurrentDictionary, object[], int, RowInfo>> _dicExecuteArrayRowReadClassOrTuple = new ConcurrentDictionary, object[], int, RowInfo>>(); + static ConcurrentDictionary, DbDataReader, int, RowInfo>> _dicExecuteArrayRowReadClassOrTuple = new ConcurrentDictionary, DbDataReader, int, RowInfo>>(); internal class RowInfo { public object Value { get; set; } public int DataIndex { get; set; } @@ -176,17 +178,18 @@ namespace FreeSql.Internal { public static PropertyInfo PropertyValue = typeof(RowInfo).GetProperty("Value"); public static PropertyInfo PropertyDataIndex = typeof(RowInfo).GetProperty("DataIndex"); } - internal static RowInfo ExecuteArrayRowReadClassOrTuple(Type type, Dictionary names, object[] row, int dataIndex = 0) { + internal static MethodInfo MethodDataReaderGetValue = typeof(DbDataReader).GetMethod("GetValue"); + internal static RowInfo ExecuteArrayRowReadClassOrTuple(Type type, Dictionary names, DbDataReader row, int dataIndex = 0) { var func = _dicExecuteArrayRowReadClassOrTuple.GetOrAdd(type, s => { var returnTarget = Expression.Label(typeof(RowInfo)); var typeExp = Expression.Parameter(typeof(Type), "type"); var namesExp = Expression.Parameter(typeof(Dictionary), "names"); - var rowExp = Expression.Parameter(typeof(object[]), "row"); + var rowExp = Expression.Parameter(typeof(DbDataReader), "row"); var dataIndexExp = Expression.Parameter(typeof(int), "dataIndex"); - if (type.IsArray) return Expression.Lambda, object[], int, RowInfo>>( + if (type.IsArray) return Expression.Lambda, DbDataReader, int, RowInfo>>( Expression.New(RowInfo.Constructor, - Expression.Call(MethodGetDataReaderValue, new Expression[] { typeExp, Expression.ArrayAccess(rowExp, dataIndexExp) }), + Expression.Call(MethodGetDataReaderValue, new Expression[] { typeExp, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp) /*Expression.ArrayAccess(rowExp, dataIndexExp)*/ }), Expression.Add(dataIndexExp, Expression.Constant(1)) ), new[] { typeExp, namesExp, rowExp, dataIndexExp }).Compile(); @@ -194,9 +197,9 @@ namespace FreeSql.Internal { if (typeGeneric.FullName.StartsWith("System.Nullable`1[")) typeGeneric = type.GenericTypeArguments.First(); if (typeGeneric.IsEnum || dicExecuteArrayRowReadClassOrTuple.ContainsKey(typeGeneric)) - return Expression.Lambda, object[], int, RowInfo>>( + return Expression.Lambda, DbDataReader, int, RowInfo>>( Expression.New(RowInfo.Constructor, - Expression.Call(MethodGetDataReaderValue, new Expression[] { typeExp, Expression.ArrayAccess(rowExp, dataIndexExp) }), + Expression.Call(MethodGetDataReaderValue, new Expression[] { typeExp, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp) /*Expression.ArrayAccess(rowExp, dataIndexExp)*/ }), Expression.Add(dataIndexExp, Expression.Constant(1)) ), new[] { typeExp, namesExp, rowExp, dataIndexExp }).Compile(); @@ -211,13 +214,32 @@ namespace FreeSql.Internal { var fields = type.GetFields(); foreach (var field in fields) { + Expression read2ExpAssign = null; //加速缓存 + if (field.FieldType.IsArray) read2ExpAssign = Expression.New(RowInfo.Constructor, + Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(field.FieldType), Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp) /*Expression.ArrayAccess(rowExp, dataIndexExp)*/ }), + Expression.Add(dataIndexExp, Expression.Constant(1)) + ); + else { + var fieldtypeGeneric = field.FieldType; + if (fieldtypeGeneric.FullName.StartsWith("System.Nullable`1[")) fieldtypeGeneric = fieldtypeGeneric.GenericTypeArguments.First(); + if (fieldtypeGeneric.IsEnum || + dicExecuteArrayRowReadClassOrTuple.ContainsKey(fieldtypeGeneric)) read2ExpAssign = Expression.New(RowInfo.Constructor, + Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(field.FieldType), Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp) /*Expression.ArrayAccess(rowExp, dataIndexExp)*/ }), + Expression.Add(dataIndexExp, Expression.Constant(1)) + ); + else { + read2ExpAssign = Expression.Call(MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(field.FieldType), namesExp, rowExp, dataIndexExp }); + } + } block2Exp.AddRange(new Expression[] { //Expression.TryCatch(Expression.Block( // typeof(void), - Expression.Assign(read2Exp, Expression.Call(MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(field.FieldType), namesExp, rowExp, dataIndexExp })), + Expression.Assign(read2Exp, read2ExpAssign), Expression.IfThen(Expression.GreaterThan(read2ExpDataIndex, dataIndexExp), Expression.Assign(dataIndexExp, read2ExpDataIndex)), - Expression.Assign(Expression.MakeMemberAccess(ret2Exp, field), Expression.Convert(read2ExpValue, field.FieldType)) + Expression.IfThenElse(Expression.Equal(read2ExpValue, Expression.Constant(null)), + Expression.Assign(Expression.MakeMemberAccess(ret2Exp, field), Expression.Default(field.FieldType)), + Expression.Assign(Expression.MakeMemberAccess(ret2Exp, field), Expression.Convert(read2ExpValue, field.FieldType))) //), //Expression.Catch(typeof(Exception), Expression.Block( // Expression.IfThen(Expression.Equal(read2ExpDataIndex, Expression.Constant(0)), Expression.Throw(Expression.Constant(new Exception(field.Name + "," + 0)))), @@ -233,16 +255,16 @@ namespace FreeSql.Internal { Expression.Return(returnTarget, Expression.New(RowInfo.Constructor, Expression.Convert(ret2Exp, typeof(object)), dataIndexExp)), Expression.Label(returnTarget, Expression.Default(typeof(RowInfo))) }); - return Expression.Lambda, object[], int, RowInfo>>( + return Expression.Lambda, DbDataReader, int, RowInfo>>( Expression.Block(new[] { ret2Exp, read2Exp }, block2Exp), new[] { typeExp, namesExp, rowExp, dataIndexExp }).Compile(); } var rowLenExp = Expression.ArrayLength(rowExp); - return Expression.Lambda, object[], int, RowInfo>>( + return Expression.Lambda, DbDataReader, int, RowInfo>>( Expression.Block( Expression.IfThen( Expression.LessThan(dataIndexExp, rowLenExp), Expression.Return(returnTarget, Expression.New(RowInfo.Constructor, - Expression.Call(MethodGetDataReaderValue, new Expression[] { typeExp, Expression.ArrayAccess(rowExp, dataIndexExp) }), + Expression.Call(MethodGetDataReaderValue, new Expression[] { typeExp, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp) /*Expression.ArrayAccess(rowExp, dataIndexExp)*/ }), Expression.Add(dataIndexExp, Expression.Constant(1)))) ), Expression.Label(returnTarget, Expression.Default(typeof(RowInfo))) @@ -250,14 +272,14 @@ namespace FreeSql.Internal { } if (type == typeof(object) && names != null) { - Func, object[], int, RowInfo> dynamicFunc = (type2, names2, row2, dataindex2) => { + Func, DbDataReader, int, RowInfo> dynamicFunc = (type2, names2, row2, dataindex2) => { dynamic expando = new System.Dynamic.ExpandoObject(); //动态类型字段 可读可写 var expandodic = (IDictionary)expando; foreach (var name in names2) - expandodic.Add(name.Key, row2[name.Value]); + expandodic.Add(name.Key, row2.GetValue(name.Value)); return new RowInfo(expando, names2.Count); }; - return dynamicFunc;// Expression.Lambda, object[], int, RowInfo>>(null); + return dynamicFunc;// Expression.Lambda, DbDataReader, int, RowInfo>>(null); } //类注入属性 @@ -265,42 +287,108 @@ namespace FreeSql.Internal { var readExp = Expression.Variable(typeof(RowInfo), "read"); var readExpValue = Expression.MakeMemberAccess(readExp, RowInfo.PropertyValue); var readExpDataIndex = Expression.MakeMemberAccess(readExp, RowInfo.PropertyDataIndex); + var readExpValueParms = new List(); + var readExpsIndex = Expression.Variable(typeof(int), "readsIndex"); var tryidxExp = Expression.Variable(typeof(int), "tryidx"); var blockExp = new List(); - blockExp.Add(Expression.Assign(retExp, Expression.New(type.GetConstructor(new Type[0])))); - - var props = type.GetProperties(); - foreach (var prop in props) { - var propGetSetMethod = prop.GetSetMethod(); - blockExp.AddRange(new Expression[] { - Expression.Assign(tryidxExp, dataIndexExp), - Expression.IfThen(Expression.Not(Expression.And( - Expression.NotEqual(namesExp, Expression.Constant(null)), - Expression.Not(Expression.Call(namesExp, namesExp.Type.GetMethod("TryGetValue"), Expression.Constant(prop.Name), tryidxExp)))), - Expression.Block( - //Expression.Assign(tryidxExp, Expression.Call(namesExp, namesExp Expression.Constant(prop.Name))), - Expression.Assign(readExp, Expression.Call(MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(prop.PropertyType), namesExp, rowExp, tryidxExp })), - Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp), - Expression.Assign(dataIndexExp, readExpDataIndex)), - Expression.IfThen(Expression.NotEqual(readExpValue, Expression.Constant(null)), - Expression.Call(retExp, propGetSetMethod, Expression.Convert(readExpValue, prop.PropertyType))) - ) - ) - }); + var ctor = type.GetConstructor(new Type[0]) ?? type.GetConstructors().First(); + var ctorParms = ctor.GetParameters(); + if (ctorParms.Length > 0) { + foreach(var ctorParm in ctorParms) { + Expression readExpAssign = null; //加速缓存 + if (ctorParm.ParameterType.IsArray) readExpAssign = Expression.New(RowInfo.Constructor, + Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(ctorParm.ParameterType), Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp) }), + Expression.Add(dataIndexExp, Expression.Constant(1)) + ); + else { + var proptypeGeneric = ctorParm.ParameterType; + if (proptypeGeneric.FullName.StartsWith("System.Nullable`1[")) proptypeGeneric = proptypeGeneric.GenericTypeArguments.First(); + if (proptypeGeneric.IsEnum || + dicExecuteArrayRowReadClassOrTuple.ContainsKey(proptypeGeneric)) readExpAssign = Expression.New(RowInfo.Constructor, + Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(ctorParm.ParameterType), Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp) }), + Expression.Add(dataIndexExp, Expression.Constant(1)) + ); + else { + readExpAssign = Expression.New(RowInfo.Constructor, + Expression.MakeMemberAccess(Expression.Call(MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(ctorParm.ParameterType), namesExp, rowExp, dataIndexExp }), RowInfo.PropertyValue), + Expression.Add(dataIndexExp, Expression.Constant(1))); + } + } + var varctorParm = Expression.Variable(ctorParm.ParameterType, $"ctorParm{ctorParm.Name}"); + readExpValueParms.Add(varctorParm); + blockExp.AddRange(new Expression[] { + Expression.Assign(tryidxExp, dataIndexExp), + //以下注释部分为【严格读取】,会损失一点性能 + //Expression.IfThen(Expression.Not(Expression.And( + // Expression.NotEqual(namesExp, Expression.Constant(null)), + // Expression.Not(Expression.Call(namesExp, namesExp.Type.GetMethod("TryGetValue"), Expression.Constant(prop.Name), tryidxExp)))), + // Expression.Block( + Expression.Assign(readExp, readExpAssign), + Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp), + Expression.Assign(dataIndexExp, readExpDataIndex)), + Expression.IfThenElse(Expression.Equal(readExpValue, Expression.Constant(null)), + Expression.Assign(varctorParm, Expression.Default(ctorParm.ParameterType)), + Expression.Assign(varctorParm, Expression.Convert(readExpValue, ctorParm.ParameterType))) + // ) + //) + }); + } + blockExp.Add(Expression.Assign(retExp, Expression.New(ctor, readExpValueParms))); + } else { + blockExp.Add(Expression.Assign(retExp, Expression.New(ctor))); + + var props = type.GetProperties(); + foreach (var prop in props) { + var propGetSetMethod = prop.GetSetMethod(); + Expression readExpAssign = null; //加速缓存 + if (prop.PropertyType.IsArray) readExpAssign = Expression.New(RowInfo.Constructor, + Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(prop.PropertyType), Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp) /*Expression.ArrayAccess(rowExp, dataIndexExp)*/ }), + Expression.Add(dataIndexExp, Expression.Constant(1)) + ); + else { + var proptypeGeneric = prop.PropertyType; + if (proptypeGeneric.FullName.StartsWith("System.Nullable`1[")) proptypeGeneric = proptypeGeneric.GenericTypeArguments.First(); + if (proptypeGeneric.IsEnum || + dicExecuteArrayRowReadClassOrTuple.ContainsKey(proptypeGeneric)) readExpAssign = Expression.New(RowInfo.Constructor, + Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(prop.PropertyType), Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp) /*Expression.ArrayAccess(rowExp, dataIndexExp)*/ }), + Expression.Add(dataIndexExp, Expression.Constant(1)) + ); + else { + continue; + readExpAssign = Expression.Call(MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(prop.PropertyType), namesExp, rowExp, tryidxExp }); + } + } + blockExp.AddRange(new Expression[] { + Expression.Assign(tryidxExp, dataIndexExp), + //以下注释部分为【严格读取】,会损失一点性能 + //Expression.IfThen(Expression.Not(Expression.And( + // Expression.NotEqual(namesExp, Expression.Constant(null)), + // Expression.Not(Expression.Call(namesExp, namesExp.Type.GetMethod("TryGetValue"), Expression.Constant(prop.Name), tryidxExp)))), + // Expression.Block( + Expression.Assign(readExp, readExpAssign), + Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp), + Expression.Assign(dataIndexExp, readExpDataIndex)), + Expression.IfThenElse(Expression.Equal(readExpValue, Expression.Constant(null)), + Expression.Call(retExp, propGetSetMethod, Expression.Default(prop.PropertyType)), + Expression.Call(retExp, propGetSetMethod, Expression.Convert(readExpValue, prop.PropertyType))) + // ) + //) + }); + } } blockExp.AddRange(new Expression[] { Expression.Return(returnTarget, Expression.New(RowInfo.Constructor, retExp, dataIndexExp)), Expression.Label(returnTarget, Expression.Default(typeof(RowInfo))) }); - return Expression.Lambda, object[], int, RowInfo>>( - Expression.Block(new[] { retExp, readExp, tryidxExp }, blockExp), new[] { typeExp, namesExp, rowExp, dataIndexExp }).Compile(); + return Expression.Lambda, DbDataReader, int, RowInfo>>( + Expression.Block(new[] { retExp, readExp, tryidxExp, readExpsIndex }.Concat(readExpValueParms), blockExp), new[] { typeExp, namesExp, rowExp, dataIndexExp }).Compile(); }); return func(type, names, row, dataIndex); } - static MethodInfo MethodExecuteArrayRowReadClassOrTuple = typeof(Utils).GetMethod("ExecuteArrayRowReadClassOrTuple", BindingFlags.Static | BindingFlags.NonPublic); - static MethodInfo MethodGetDataReaderValue = typeof(Utils).GetMethod("GetDataReaderValue", BindingFlags.Static | BindingFlags.NonPublic); + internal static MethodInfo MethodExecuteArrayRowReadClassOrTuple = typeof(Utils).GetMethod("ExecuteArrayRowReadClassOrTuple", BindingFlags.Static | BindingFlags.NonPublic); + internal static MethodInfo MethodGetDataReaderValue = typeof(Utils).GetMethod("GetDataReaderValue", BindingFlags.Static | BindingFlags.NonPublic); static ConcurrentDictionary> _dicFillPropertyValue = new ConcurrentDictionary>(); internal static void FillPropertyValue(object info, string memberAccessPath, object value) { @@ -322,11 +410,19 @@ namespace FreeSql.Internal { act(info, value); } - static ConcurrentDictionary> _dicGetDataReaderValue = new ConcurrentDictionary>(); + static ConcurrentDictionary>> _dicGetDataReaderValue = new ConcurrentDictionary>>(); + static MethodInfo MethodArrayGetValue = typeof(Array).GetMethod("GetValue", new[] { typeof(int) }); + static MethodInfo MethodMygisGeometryParse = typeof(MygisGeometry).GetMethod("Parse", new[] { typeof(string) }); + static MethodInfo MethodGuidParse = typeof(Guid).GetMethod("Parse", new[] { typeof(string) }); + static MethodInfo MethodEnumParse = typeof(Enum).GetMethod("Parse", new[] { typeof(Type), typeof(string), typeof(bool) }); + static MethodInfo MethodToString = typeof(string).GetMethod("Concat", new[] { typeof(object) }); + static MethodInfo MethodConvertChangeType = typeof(Convert).GetMethod("ChangeType", new[] { typeof(object), typeof(Type) }); + static MethodInfo MethodTimeSpanFromSeconds = typeof(TimeSpan).GetMethod("FromSeconds"); + static MethodInfo MethodDoubleParse = typeof(double).GetMethod("Parse", new[] { typeof(string) }); internal static object GetDataReaderValue(Type type, object value) { if (value == null || value == DBNull.Value) return null; - var func = _dicGetDataReaderValue.GetOrAdd(type, k => { + var func = _dicGetDataReaderValue.GetOrAdd(type, k1 => new ConcurrentDictionary>()).GetOrAdd(value.GetType(), valueType => { var returnTarget = Expression.Label(typeof(object)); var parmExp = Expression.Parameter(typeof(object), "value"); @@ -334,94 +430,90 @@ namespace FreeSql.Internal { if (type.IsArray) { var elementType = type.GetElementType(); - var valueArr = value as Array; + if (elementType == valueType.GetElementType()) return Expression.Lambda>(parmExp, parmExp).Compile(); - if (elementType == valueArr.GetType().GetElementType()) return Expression.Lambda>(parmExp, parmExp).Compile(); - - var arr = Expression.Variable(type, "arr"); + var ret = Expression.Variable(type, "ret"); + var arr = Expression.Variable(valueType, "arr"); var arrlen = Expression.Variable(typeof(int), "arrlen"); var x = Expression.Variable(typeof(int), "x"); + var readval = Expression.Variable(typeof(object), "readval"); var label = Expression.Label(typeof(int)); - var ret = Expression.NewArrayBounds(elementType, arrlen); return Expression.Lambda>( Expression.Block( - new[] { arr, arrlen, x }, - Expression.Assign(arr, Expression.Convert(parmExp, type)), + new[] { ret, arr, arrlen, readval, x }, + Expression.Assign(arr, Expression.TypeAs(parmExp, valueType)), Expression.Assign(arrlen, Expression.ArrayLength(arr)), Expression.Assign(x, Expression.Constant(0)), - ret, + Expression.Assign(ret, Expression.NewArrayBounds(elementType, arrlen)), Expression.Loop( Expression.IfThenElse( Expression.LessThan(x, arrlen), Expression.Block( - Expression.Assign( - Expression.ArrayAccess(ret, x), - Expression.Call( - MethodGetDataReaderValue, - Expression.Constant(elementType, typeof(Type)), - Expression.ArrayAccess(arr, x) - ) + Expression.Assign(readval, Expression.Call( + MethodGetDataReaderValue, + Expression.Constant(elementType, typeof(Type)), + Expression.Convert(Expression.ArrayAccess(arr, x), typeof(object)) + )), + Expression.IfThenElse( + Expression.Equal(readval, Expression.Constant(null)), + Expression.Assign(Expression.ArrayAccess(ret, x), Expression.Default(elementType)), + Expression.Assign(Expression.ArrayAccess(ret, x), Expression.Convert(readval, elementType)) ), Expression.PostIncrementAssign(x) ), Expression.Break(label, x) ), label - ) + ), + Expression.Return(returnTarget, ret), + Expression.Label(returnTarget, Expression.Default(typeof(object))) ), parmExp).Compile(); } if (type.FullName.StartsWith("System.Nullable`1[")) type = type.GenericTypeArguments.First(); if (type.IsEnum) return Expression.Lambda>( Expression.Call( - typeof(Enum).GetMethod("Parse", new[] { typeof(Type), typeof(string), typeof(bool) }), + MethodEnumParse, Expression.Constant(type, typeof(Type)), - Expression.Convert(parmExp, typeof(string)), + Expression.Call(MethodToString, parmExp), Expression.Constant(true, typeof(bool)) ) , parmExp).Compile(); switch (type.FullName) { case "System.Guid": - if (value.GetType() != type) return Expression.Lambda>( - Expression.Block( - Expression.TryCatch( - Expression.Return(returnTarget, Expression.Call(typeof(Guid).GetMethod("Parse"), Expression.Convert(parmExp, typeof(string)))), - Expression.Catch(typeof(Exception), - Expression.Return(returnTarget, Expression.Constant(Guid.Empty))) - ), - Expression.Label(returnTarget, Expression.Default(type)) - ), parmExp).Compile(); - + if (valueType != type) return Expression.Lambda>( + Expression.Convert(Expression.Call(MethodGuidParse, Expression.Convert(parmExp, typeof(string))), typeof(object)) + , parmExp).Compile(); return Expression.Lambda>(parmExp, parmExp).Compile(); case "MygisPoint": return Expression.Lambda>( Expression.TypeAs( - Expression.Call(typeof(MygisPoint).GetMethod("Parse"), Expression.Convert(parmExp, typeof(string))), + Expression.Call(MethodMygisGeometryParse, Expression.Convert(parmExp, typeof(string))), typeof(MygisPoint) ), parmExp).Compile(); case "MygisLineString": return Expression.Lambda>( Expression.TypeAs( - Expression.Call(typeof(MygisLineString).GetMethod("Parse"), Expression.Convert(parmExp, typeof(string))), + Expression.Call(MethodMygisGeometryParse, Expression.Convert(parmExp, typeof(string))), typeof(MygisLineString) ), parmExp).Compile(); case "MygisPolygon": return Expression.Lambda>( Expression.TypeAs( - Expression.Call(typeof(MygisPolygon).GetMethod("Parse"), Expression.Convert(parmExp, typeof(string))), + Expression.Call(MethodMygisGeometryParse, Expression.Convert(parmExp, typeof(string))), typeof(MygisPolygon) ), parmExp).Compile(); case "MygisMultiPoint": return Expression.Lambda>( Expression.TypeAs( - Expression.Call(typeof(MygisMultiPoint).GetMethod("Parse"), Expression.Convert(parmExp, typeof(string))), + Expression.Call(MethodMygisGeometryParse, Expression.Convert(parmExp, typeof(string))), typeof(MygisMultiPoint) ), parmExp).Compile(); case "MygisMultiLineString": return Expression.Lambda>( Expression.TypeAs( - Expression.Call(typeof(MygisMultiLineString).GetMethod("Parse"), Expression.Convert(parmExp, typeof(string))), + Expression.Call(MethodMygisGeometryParse, Expression.Convert(parmExp, typeof(string))), typeof(MygisMultiLineString) ), parmExp).Compile(); case "MygisMultiPolygon": return Expression.Lambda>( Expression.TypeAs( - Expression.Call(typeof(MygisMultiPolygon).GetMethod("Parse"), Expression.Convert(parmExp, typeof(string))), + Expression.Call(MethodMygisGeometryParse, Expression.Convert(parmExp, typeof(string))), typeof(MygisMultiPolygon) ), parmExp).Compile(); case "Newtonsoft.Json.Linq.JToken": return Expression.Lambda>( @@ -441,20 +533,58 @@ namespace FreeSql.Internal { ), parmExp).Compile(); case "Npgsql.LegacyPostgis.PostgisGeometry": return Expression.Lambda>(parmExp, parmExp).Compile(); } - if (type != value.GetType()) { + if (type != valueType) { if (type.FullName == "System.TimeSpan") return Expression.Lambda>( - Expression.Call( - typeof(TimeSpan).GetMethod("FromSeconds"), - Expression.Call(typeof(double).GetMethod("Parse", new[] { typeof(string) }), Expression.Convert(parmExp, typeof(string))) - ), parmExp).Compile(); + Expression.Convert(Expression.Call( + MethodTimeSpanFromSeconds, + Expression.Call(MethodDoubleParse, Expression.Call(MethodToString, parmExp)) + ), typeof(object)), parmExp).Compile(); return Expression.Lambda>( - Expression.Call(typeof(Convert).GetMethod("ChangeType", new[] { typeof(object), typeof(Type) }), parmExp, Expression.Constant(type, typeof(Type))) + Expression.Call(MethodConvertChangeType, parmExp, Expression.Constant(type, typeof(Type))) , parmExp).Compile(); } return Expression.Lambda>(parmExp, parmExp).Compile(); }); return func(value); } + internal static object GetDataReaderValue22(Type type, object value) { + if (value == null || value == DBNull.Value) return null; + if (type.FullName == "System.Byte[]") return value; + if (type.IsArray) { + var elementType = type.GetElementType(); + var valueArr = value as Array; + if (elementType == valueArr.GetType().GetElementType()) return value; + var len = valueArr.GetLength(0); + var ret = Array.CreateInstance(elementType, len); + for (var a = 0; a < len; a++) { + var item = valueArr.GetValue(a); + ret.SetValue(GetDataReaderValue(elementType, item), a); + } + return ret; + } + if (type.FullName.StartsWith("System.Nullable`1[")) type = type.GenericTypeArguments.First(); + if (type.IsEnum) return Enum.Parse(type, string.Concat(value), true); + switch (type.FullName) { + case "System.Guid": + if (value.GetType() != type) return Guid.TryParse(string.Concat(value), out var tryguid) ? tryguid : Guid.Empty; + return value; + case "MygisPoint": return MygisPoint.Parse(string.Concat(value)) as MygisPoint; + case "MygisLineString": return MygisLineString.Parse(string.Concat(value)) as MygisLineString; + case "MygisPolygon": return MygisPolygon.Parse(string.Concat(value)) as MygisPolygon; + case "MygisMultiPoint": return MygisMultiPoint.Parse(string.Concat(value)) as MygisMultiPoint; + case "MygisMultiLineString": return MygisMultiLineString.Parse(string.Concat(value)) as MygisMultiLineString; + case "MygisMultiPolygon": return MygisMultiPolygon.Parse(string.Concat(value)) as MygisMultiPolygon; + case "Newtonsoft.Json.Linq.JToken": return JToken.Parse(string.Concat(value)); + case "Newtonsoft.Json.Linq.JObject": return JObject.Parse(string.Concat(value)); + case "Newtonsoft.Json.Linq.JArray": return JArray.Parse(string.Concat(value)); + case "Npgsql.LegacyPostgis.PostgisGeometry": return value; + } + if (type != value.GetType()) { + if (type.FullName == "System.TimeSpan") return TimeSpan.FromSeconds(double.Parse(value.ToString())); + return Convert.ChangeType(value, type); + } + return value; + } internal static string GetCsName(string name) { name = Regex.Replace(name.TrimStart('@'), @"[^\w]", "_"); return char.IsLetter(name, 0) ? name : string.Concat("_", name); diff --git a/FreeSql/MySql/Curd/MySqlSelect.cs b/FreeSql/MySql/Curd/MySqlSelect.cs index 3c7660d8..9eaea0e0 100644 --- a/FreeSql/MySql/Curd/MySqlSelect.cs +++ b/FreeSql/MySql/Curd/MySqlSelect.cs @@ -78,38 +78,38 @@ namespace FreeSql.MySql.Curd { public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _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, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select9Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class MySqlSelect : FreeSql.Internal.CommonProvider.Select10Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } } diff --git a/FreeSql/Oracle/Curd/OracleSelect.cs b/FreeSql/Oracle/Curd/OracleSelect.cs index bc5050d3..0104c57b 100644 --- a/FreeSql/Oracle/Curd/OracleSelect.cs +++ b/FreeSql/Oracle/Curd/OracleSelect.cs @@ -89,38 +89,38 @@ namespace FreeSql.Oracle.Curd { public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect(_orm, _commonUtils, _commonExpression, null); OracleSelect.CopyData(this, ret); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _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, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select9Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class OracleSelect : FreeSql.Internal.CommonProvider.Select10Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class { public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => OracleSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } } diff --git a/FreeSql/PostgreSQL/Curd/PostgreSQLSelect.cs b/FreeSql/PostgreSQL/Curd/PostgreSQLSelect.cs index 42de1c7c..c8a5123e 100644 --- a/FreeSql/PostgreSQL/Curd/PostgreSQLSelect.cs +++ b/FreeSql/PostgreSQL/Curd/PostgreSQLSelect.cs @@ -80,7 +80,7 @@ namespace FreeSql.PostgreSQL.Curd { public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect.CopyData(this, ret); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _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) { } @@ -88,34 +88,34 @@ namespace FreeSql.PostgreSQL.Curd { //} 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, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select9Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class PostgreSQLSelect : FreeSql.Internal.CommonProvider.Select10Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class { public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => PostgreSQLSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } } diff --git a/FreeSql/SqlServer/Curd/SqlServerSelect.cs b/FreeSql/SqlServer/Curd/SqlServerSelect.cs index 387fc2a5..658ae0ea 100644 --- a/FreeSql/SqlServer/Curd/SqlServerSelect.cs +++ b/FreeSql/SqlServer/Curd/SqlServerSelect.cs @@ -90,7 +90,7 @@ namespace FreeSql.SqlServer.Curd { public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect(_orm, _commonUtils, _commonExpression, null); SqlServerSelect.CopyData(this, ret); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _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) { } @@ -98,34 +98,34 @@ namespace FreeSql.SqlServer.Curd { //} 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, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select9Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class SqlServerSelect : FreeSql.Internal.CommonProvider.Select10Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class { public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => SqlServerSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } } diff --git a/FreeSql/Sqlite/Curd/SqliteSelect.cs b/FreeSql/Sqlite/Curd/SqliteSelect.cs index c17938d8..4dc52769 100644 --- a/FreeSql/Sqlite/Curd/SqliteSelect.cs +++ b/FreeSql/Sqlite/Curd/SqliteSelect.cs @@ -78,38 +78,38 @@ namespace FreeSql.Sqlite.Curd { public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret); return ret; } public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect(_orm, _commonUtils, _commonExpression, null); SqliteSelect.CopyData(this, ret); return ret; } - public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _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, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select4Provider where T1 : class where T2 : class where T3 : class where T4 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select5Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select6Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select7Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select8Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select9Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } class SqliteSelect : FreeSql.Internal.CommonProvider.Select10Provider where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class { public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); + public override string ToSql(string field = null) => SqliteSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } } diff --git a/readme.md b/readme.md index a1b21351..f4c69248 100644 --- a/readme.md +++ b/readme.md @@ -162,27 +162,31 @@ List t8 = fsql.Ado.Query("select * from song"); ### FreeSql Query & Dapper Query -Elapsed: 00:00:01.6999868; Query Entity Counts: 131072; ORM: Dapper +Elapsed: 00:00:00.6807349; Query Entity Counts: 131072; ORM: Dapper -Elapsed: 00:00:00.4200430; Query Tuple Counts: 131072; ORM: Dapper +Elapsed: 00:00:00.4527258; Query Tuple Counts: 131072; ORM: Dapper -Elapsed: 00:00:00.6615716; Query Dynamic Counts: 131072; ORM: Dapper +Elapsed: 00:00:00.6895447; Query Dynamic Counts: 131072; ORM: Dapper -Elapsed: 00:00:02.4955996; Query Entity Counts: 131072; ORM: FreeSql* +Elapsed: 00:00:00.8253683; Query Entity Counts: 131072; ORM: FreeSql* -Elapsed: 00:00:01.2938320; Query Tuple Counts: 131072; ORM: FreeSql* +Elapsed: 00:00:00.6503870; Query Tuple Counts: 131072; ORM: FreeSql* -Elapsed: 00:00:00.9719682; Query Dynamic Counts: 131072; ORM: FreeSql* +Elapsed: 00:00:00.4987399; Query ToList Counts: 131072; ORM: FreeSql* + +Elapsed: 00:00:00.9402494; Query Dynamic Counts: 131072; ORM: FreeSql* ### FreeSql ToList & Dapper Query -Elapsed: 00:00:01.7446031; Query Entity Counts: 131072; ORM: Dapper +Elapsed: 00:00:00.7840409; ToList Entity Counts: 131072; ORM: FreeSql* -Elapsed: 00:00:01.2857691; ToList Entity Counts: 131072; ORM: FreeSql* +Elapsed: 00:00:00.6414674; Query Entity Counts: 131072; ORM: Dapper [查看测试代码](FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs) -FreeSql 目前使用的反射+缓存,硬碰硬比不过 Dapper Emit,真实项目使用相差无几。Emit 在单次查询记录数量越多收益越大。 +> 以上测试结果运行了两次,为第二次性能报告,避免了首个运行慢不公平的情况 + +FreeSql 目前使用的ExpressionTree+缓存,因为支持更为复杂的数据类型,所以比 Dapper Emit 慢少许,真实项目使用其实相差无几。 # Part2 添加 ```csharp