From 3cb7bd74bd796c4dcb45073ab14ddd212c5106a0 Mon Sep 17 00:00:00 2001 From: Fabio Nascimento Date: Fri, 26 Aug 2022 17:32:45 -0300 Subject: [PATCH 1/4] Otimize consulting by remove DataTable Dependency --- .gitignore | 2 + .../Data/Dialects/ScriptAnsiBuilder.cs | 5 + src/SimpleQuery/Data/Dialects/ScriptCommon.cs | 7 + .../Data/Dialects/ScriptHanaBuilder.cs | 14 +- .../Data/Dialects/ScriptMySqlBuilder.cs | 7 +- .../Data/Dialects/ScriptPostGresBuilder.cs | 7 +- .../Data/Dialects/ScriptSqlServerBuilder.cs | 21 +- .../Data/Dialects/ScriptSqliteBuilder.cs | 5 + .../Domain/Data/Dialects/IScriptBuilder.cs | 9 + src/SimpleQuery/Extentions.cs | 193 ++++++++++-------- src/SimpleQuery/ExtentionsLinq.cs | 99 +++------ 11 files changed, 210 insertions(+), 159 deletions(-) diff --git a/.gitignore b/.gitignore index 7aaf335..2ef901e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ packages/ .vscode/ .vs/ *.exe +/src/.idea +/src/SimpleQuery.sln.DotSettings.user diff --git a/src/SimpleQuery/Data/Dialects/ScriptAnsiBuilder.cs b/src/SimpleQuery/Data/Dialects/ScriptAnsiBuilder.cs index b3bf089..8851204 100644 --- a/src/SimpleQuery/Data/Dialects/ScriptAnsiBuilder.cs +++ b/src/SimpleQuery/Data/Dialects/ScriptAnsiBuilder.cs @@ -82,6 +82,11 @@ private string GetSequenceName(string entityName, string columnName) return $"sequence_{entityName}_{columnName}".ToLower(); } + public string GetCountCommand(T obj, Expression> expression = null) where T : class, new() + { + throw new NotImplementedException(); + } + public string GetDeleteCommand(T obj, object key) where T : class, new() { var allProperties = obj.GetType().GetProperties(); diff --git a/src/SimpleQuery/Data/Dialects/ScriptCommon.cs b/src/SimpleQuery/Data/Dialects/ScriptCommon.cs index b891055..ae0517a 100644 --- a/src/SimpleQuery/Data/Dialects/ScriptCommon.cs +++ b/src/SimpleQuery/Data/Dialects/ScriptCommon.cs @@ -126,5 +126,12 @@ internal static bool IsPrimitive(Type t) typeof(DateTime?) }.Contains(t); } + + protected string GetCountqueryComand(T obj) where T : class, new() + { + var entityName = GetEntityName(); + + return $"select * from \"{entityName}\" "; + } } } diff --git a/src/SimpleQuery/Data/Dialects/ScriptHanaBuilder.cs b/src/SimpleQuery/Data/Dialects/ScriptHanaBuilder.cs index e86fbc4..f886ba3 100644 --- a/src/SimpleQuery/Data/Dialects/ScriptHanaBuilder.cs +++ b/src/SimpleQuery/Data/Dialects/ScriptHanaBuilder.cs @@ -45,7 +45,7 @@ public void Execute(string commandText, IDbConnection dbConnection, IDbTransacti var wasClosed = dbConnection.State == ConnectionState.Closed; if (wasClosed) dbConnection.Open(); var rowsCount = command.ExecuteNonQuery(); - var dataTable = new DataTable(); + Console.WriteLine($"{rowsCount} affected rows"); if (wasClosed) dbConnection.Close(); } @@ -272,6 +272,18 @@ public object GetLastId(T model, IDbConnection dbConnection, IDbTransaction t var where = GetWhereCommand(expression); return select + " " + where; } + + public string GetCountCommand(T obj, Expression> expression = null) where T : class, new() + { + var select = GetCountqueryComand(obj); + + if (expression is null) + { + return select; + } + + return select + " " + GetWhereCommand(expression);; + } public Tuple> GetInsertCommandParameters(T obj, bool includeKey = false) where T : class, new() { diff --git a/src/SimpleQuery/Data/Dialects/ScriptMySqlBuilder.cs b/src/SimpleQuery/Data/Dialects/ScriptMySqlBuilder.cs index f843826..a48ca12 100644 --- a/src/SimpleQuery/Data/Dialects/ScriptMySqlBuilder.cs +++ b/src/SimpleQuery/Data/Dialects/ScriptMySqlBuilder.cs @@ -26,7 +26,7 @@ public void Execute(string commandText, IDbConnection dbConnection, IDbTransacti var wasClosed = dbConnection.State == ConnectionState.Closed; if (wasClosed) dbConnection.Open(); var rowsCount = command.ExecuteNonQuery(); - var dataTable = new DataTable(); + Console.WriteLine($"{rowsCount} affected rows"); if (wasClosed) dbConnection.Close(); } @@ -116,6 +116,11 @@ private object GetTypeMySql(PropertyInfo item) } } + public string GetCountCommand(T obj, Expression> expression = null) where T : class, new() + { + throw new NotImplementedException(); + } + public string GetDeleteCommand(T obj, object key) where T : class, new() { var allProperties = obj.GetType().GetProperties(); diff --git a/src/SimpleQuery/Data/Dialects/ScriptPostGresBuilder.cs b/src/SimpleQuery/Data/Dialects/ScriptPostGresBuilder.cs index f066c8f..0509522 100644 --- a/src/SimpleQuery/Data/Dialects/ScriptPostGresBuilder.cs +++ b/src/SimpleQuery/Data/Dialects/ScriptPostGresBuilder.cs @@ -28,7 +28,7 @@ public void Execute(string commandText, IDbConnection dbConnection, IDbTransacti var wasClosed = dbConnection.State == ConnectionState.Closed; if (wasClosed) dbConnection.Open(); var rowsCount = command.ExecuteNonQuery(); - var dataTable = new DataTable(); + Console.WriteLine($"{rowsCount} affected rows"); if (wasClosed) dbConnection.Close(); } @@ -91,6 +91,11 @@ private string GetSequenceName(string entityName, string columnName) return $"sequence_{entityName}_{columnName}".ToLower(); } + public string GetCountCommand(T obj, Expression> expression = null) where T : class, new() + { + throw new NotImplementedException(); + } + public string GetDeleteCommand(T obj, object key) where T : class, new() { var allProperties = obj.GetType().GetProperties(); diff --git a/src/SimpleQuery/Data/Dialects/ScriptSqlServerBuilder.cs b/src/SimpleQuery/Data/Dialects/ScriptSqlServerBuilder.cs index 67cafeb..341f528 100644 --- a/src/SimpleQuery/Data/Dialects/ScriptSqlServerBuilder.cs +++ b/src/SimpleQuery/Data/Dialects/ScriptSqlServerBuilder.cs @@ -40,14 +40,19 @@ public IDataReader ExecuteReader(string commandText, IDbConnection dbConnection, public void Execute(string commandText, IDbConnection dbConnection, IDbTransaction dbTransaction = null) { var command = dbConnection.CreateCommand(); + if (dbTransaction != null) command.Transaction = dbTransaction; + command.CommandText = commandText; var wasClosed = dbConnection.State == ConnectionState.Closed; - if (wasClosed) dbConnection.Open(); + + if (wasClosed) + dbConnection.Open(); + var rowsCount = command.ExecuteNonQuery(); - var dataTable = new DataTable(); + Console.WriteLine($"{rowsCount} affected rows"); if (wasClosed) dbConnection.Close(); } @@ -158,6 +163,18 @@ public object GetLastId(T model, IDbConnection dbConnection, IDbTransaction t return sql; } + public string GetCountCommand(T obj, Expression> expression = null) where T : class, new() + { + var select = GetCountqueryComand(obj); + + if (expression is null) + { + return select; + } + + return select + " " + GetWhereCommand(expression);; + } + public string GetUpdateCommand(T obj) where T : class, new() { var allProperties = ScriptCommon.GetValidProperty(); diff --git a/src/SimpleQuery/Data/Dialects/ScriptSqliteBuilder.cs b/src/SimpleQuery/Data/Dialects/ScriptSqliteBuilder.cs index 2da7963..dd8684a 100644 --- a/src/SimpleQuery/Data/Dialects/ScriptSqliteBuilder.cs +++ b/src/SimpleQuery/Data/Dialects/ScriptSqliteBuilder.cs @@ -108,6 +108,11 @@ private string GetTypeSqlite(PropertyInfo item) } } + public string GetCountCommand(T obj, Expression> expression = null) where T : class, new() + { + throw new NotImplementedException(); + } + public string GetDeleteCommand(T obj, object key) where T : class, new() { var allProperties = obj.GetType().GetProperties(); diff --git a/src/SimpleQuery/Domain/Data/Dialects/IScriptBuilder.cs b/src/SimpleQuery/Domain/Data/Dialects/IScriptBuilder.cs index 2bf3818..44da7c6 100644 --- a/src/SimpleQuery/Domain/Data/Dialects/IScriptBuilder.cs +++ b/src/SimpleQuery/Domain/Data/Dialects/IScriptBuilder.cs @@ -40,6 +40,7 @@ public interface IScriptBuilder /// Instance model /// string GetSelectCommand(T obj) where T : class, new(); + /// /// Return table name based in Table Attribute or Class name @@ -55,6 +56,14 @@ public interface IScriptBuilder /// Instance model /// string GetSelectCommand(T obj, Expression> expression) where T : class, new(); + + /// + /// Return count from instance model + /// + /// Class type + /// Instance model + /// + string GetCountCommand(T obj, Expression> expression = null) where T : class, new(); /// /// Return delete command from instance model diff --git a/src/SimpleQuery/Extentions.cs b/src/SimpleQuery/Extentions.cs index 1dc7204..b91609a 100644 --- a/src/SimpleQuery/Extentions.cs +++ b/src/SimpleQuery/Extentions.cs @@ -4,18 +4,16 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Data; -using System.Dynamic; using System.Linq; -using System.Linq.Expressions; using System.Reflection; -using System.Text; -using System.Transactions; namespace SimpleQuery { public static partial class Extentions { - private static readonly ConcurrentDictionary GetQueries = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary GetQueries = + new ConcurrentDictionary(); + /// /// Insert model and return last id /// @@ -24,7 +22,8 @@ public static partial class Extentions /// Instance model /// Transaction database /// - public static int InsertReturningId(this IDbConnection dbConnection, T model, IDbTransaction dbTransaction = null) + public static int InsertReturningId(this IDbConnection dbConnection, T model, + IDbTransaction dbTransaction = null) where T : class, new() { var wasClosed = dbConnection.State == ConnectionState.Closed; @@ -48,6 +47,7 @@ public static int InsertReturningId(this IDbConnection dbConnection, T model, return Convert.ToInt32(lastId); } + /// /// Insert model in the database /// @@ -56,8 +56,9 @@ public static int InsertReturningId(this IDbConnection dbConnection, T model, /// Instance model /// Transaction database /// - public static T Insert(this IDbConnection dbConnection, T model, bool includeKey = false, IDbTransaction dbTransaction = null) - where T : class, new() + public static T Insert(this IDbConnection dbConnection, T model, bool includeKey = false, + IDbTransaction dbTransaction = null) + where T : class, new() { var wasClosed = dbConnection.State == ConnectionState.Closed; @@ -80,10 +81,12 @@ public static T Insert(this IDbConnection dbConnection, T model, bool include if (convertedValue != null) keyProperty.SetValue(model, convertedValue); } + return model; } - private static IDbCommand GetCommandInsert(IDbConnection dbConnection, T model, IDbTransaction dbTransaction, IScriptBuilder scripBuilder, bool includeKey = false) where T : class, new() + private static IDbCommand GetCommandInsert(IDbConnection dbConnection, T model, IDbTransaction dbTransaction, + IScriptBuilder scripBuilder, bool includeKey = false) where T : class, new() { var command = dbConnection.CreateCommand(); @@ -118,6 +121,7 @@ public static T Insert(this IDbConnection dbConnection, T model, bool include return command; } } + /// /// Update data model /// @@ -126,7 +130,7 @@ public static T Insert(this IDbConnection dbConnection, T model, bool include /// /// public static void Update(this IDbConnection dbConnection, T model, IDbTransaction dbTransaction = null) - where T : class, new() + where T : class, new() { var wasClosed = dbConnection.State == ConnectionState.Closed; @@ -142,10 +146,10 @@ public static void Update(this IDbConnection dbConnection, T model, IDbTransa Console.WriteLine($"{rowsCount} affected rows"); if (wasClosed) dbConnection.Close(); - } - private static IDbCommand GetCommandUpdate(IDbConnection dbConnection, T model, IDbTransaction dbTransaction, IScriptBuilder scripBuilder) where T : class, new() + private static IDbCommand GetCommandUpdate(IDbConnection dbConnection, T model, IDbTransaction dbTransaction, + IScriptBuilder scripBuilder) where T : class, new() { var command = dbConnection.CreateCommand(); @@ -163,6 +167,7 @@ public static void Update(this IDbConnection dbConnection, T model, IDbTransa command.Parameters.Add(param); } + if (dbTransaction != null) command.Transaction = dbTransaction; command.CommandText = updateCommand.Item1; @@ -180,6 +185,7 @@ public static void Update(this IDbConnection dbConnection, T model, IDbTransa return command; } } + /// /// Delete model from database /// @@ -188,7 +194,7 @@ public static void Update(this IDbConnection dbConnection, T model, IDbTransa /// Instance model /// Transaction database public static void Delete(this IDbConnection dbConnection, T model, IDbTransaction dbTransaction = null) - where T : class, new() + where T : class, new() { var wasClosed = dbConnection.State == ConnectionState.Closed; @@ -210,7 +216,6 @@ public static void Delete(this IDbConnection dbConnection, T model, IDbTransa Console.WriteLine($"{rowsCount} affected rows"); if (wasClosed) dbConnection.Close(); - } /// @@ -219,7 +224,8 @@ public static void Delete(this IDbConnection dbConnection, T model, IDbTransa /// Connection /// sql text command /// - public static int Execute(this IDbConnection dbConnection, string commandText, IDbTransaction transaction = null) + public static int Execute(this IDbConnection dbConnection, string commandText, + IDbTransaction transaction = null) { var wasClosed = dbConnection.State == ConnectionState.Closed; @@ -227,7 +233,8 @@ public static int Execute(this IDbConnection dbConnection, string commandText, I IScriptBuilder scripBuilder = GetScriptBuild(dbConnection); - var command = dbConnection.CreateCommand(); if (transaction != null) command.Transaction = transaction; + var command = dbConnection.CreateCommand(); + if (transaction != null) command.Transaction = transaction; command.CommandText = commandText; var rowsCount = command.ExecuteNonQuery(); @@ -235,97 +242,118 @@ public static int Execute(this IDbConnection dbConnection, string commandText, I return rowsCount; } - + /// - /// Get all + /// Get all records from database in typed model /// - /// - /// + /// Model type + /// DbConnection + /// Instance model + /// Transaction database /// - public static IEnumerable GetAll(this IDbConnection dbConnection) - where T : class, new() + public static IEnumerable GetAll(this IDbConnection dbConnection, T model = null, IDbTransaction dbTransaction = null) + where T : class, new() { var wasClosed = dbConnection.State == ConnectionState.Closed; - if (wasClosed) dbConnection.Open(); - - var type = typeof(T); - var cacheType = typeof(List); - - IScriptBuilder scriptBuilder = GetScriptBuild(dbConnection); - var selectScript = scriptBuilder.GetSelectCommand(new T()); - - var reader = scriptBuilder.ExecuteReader(selectScript, dbConnection); - var list = GetTypedList(reader); - if (wasClosed) dbConnection.Close(); - - reader.Close(); - - return list; + if (wasClosed) + dbConnection.Open(); + + var scripBuilder = GetScriptBuild(dbConnection); + var selectScript = scripBuilder.GetSelectCommand(new T()); + + var elements = QueryOptionmized(dbConnection, selectScript, GetModel); + + if (wasClosed) + dbConnection.Close(); + + return elements; } - static IEnumerable GetTypedList(IDataReader reader) where T : class, new() + static TModel[] QueryOptionmized( + IDbConnection connection, + string command, + Func, TModel> toObject) where TModel : class, new() { + var quantidadeDeRegistros = QueryCount(connection, command); + + var elementos = new TModel[quantidadeDeRegistros]; + var scripBuilder = GetScriptBuild(connection); - var listModel = new List(); + using (var rdr = scripBuilder.ExecuteReader(command, connection)) + { + var cachedOrdinal = new Dictionary(rdr.FieldCount); - var dataTable = new DataTable(); - dataTable.Load(reader); + for (var i = 0; i < rdr.FieldCount; i++) + { + try + { + var name = rdr.GetName(i); + cachedOrdinal.Add(rdr.GetName(i), rdr.GetOrdinal(name)); + } + catch (Exception e) + { + Console.WriteLine(e); + throw; + } + } - foreach (DataRow row in dataTable.Rows) - { - var newModel = GetModelByDataRow(row); - listModel.Add(newModel); - } + var elemnto = 0; - return listModel; - } + while (rdr.Read()) + { + var novoRegistro = toObject(rdr, cachedOrdinal); - /// - /// Get all records from database in typed model - /// - /// Model type - /// DbConnection - /// Instance model - /// Transaction database - /// - public static IEnumerable GetAll(this IDbConnection dbConnection, T model, IDbTransaction dbTransaction) - where T : class, new() - { - var wasClosed = dbConnection.State == ConnectionState.Closed; + elementos[elemnto] = novoRegistro; + elemnto++; + } - if (wasClosed) dbConnection.Open(); + rdr.Close(); + } - var type = typeof(T); - var cacheType = typeof(List); + return elementos; + } - IScriptBuilder scripBuilder = GetScriptBuild(dbConnection); - var selectScript = scripBuilder.GetSelectCommand(model); + private static int QueryCount(IDbConnection dbConnection, string command) + { + var commandCount = "SELECT COUNT(1) FROM ({command}) as a"; - var reader = scripBuilder.ExecuteReader(selectScript, dbConnection); - var listModel = new List(); + var qtd = dbConnection.Scalar(command); - var dataTable = new DataTable(); - dataTable.Load(reader); + return qtd.FirstOrDefault(); + } - foreach (DataRow row in dataTable.Rows) - { - var newModel = GetModelByDataRow(row); - listModel.Add(newModel); - } + private static T GetModel(IDataReader dataReader, Dictionary record) where T : class, new() + { + var model = new T(); - if (wasClosed) dbConnection.Close(); + var properties = model + .GetType() + .GetProperties(BindingFlags.Instance | BindingFlags.Public); - reader.Close(); + foreach (var item in properties) + { + if (!record.TryGetValue(item.Name, out var fieldIndex)) + { + continue; + } + + var rowValue = dataReader[fieldIndex]; + var value = ChangeType(rowValue, item.PropertyType); - return listModel; - } + item.SetValue(model, dataReader.IsDBNull(fieldIndex) ? null : value); + } + return model; + } + private static T GetModelByDataRow(DataRow row) where T : class, new() { var model = new T(); - var properties = model.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); + var properties = model + .GetType() + .GetProperties(BindingFlags.Instance | BindingFlags.Public); foreach (var item in properties) { @@ -339,8 +367,8 @@ public static IEnumerable GetAll(this IDbConnection dbConnection, T model, } return model; - } + /// /// Convert a type object to another /// @@ -360,6 +388,7 @@ public static object ChangeType(object value, Type conversion) t = Nullable.GetUnderlyingType(t); } + if (value is DBNull) { if (conversion.AssemblyQualifiedName.Contains("System.DateTime") || @@ -374,6 +403,7 @@ public static object ChangeType(object value, Type conversion) else throw new Exception("Type value is not mapped"); } + return Convert.ChangeType(value, t); } @@ -399,4 +429,5 @@ public static IScriptBuilder GetScriptBuild(this IDbConnection dbConnection) return new ScriptAnsiBuilder(); } } -} + +} \ No newline at end of file diff --git a/src/SimpleQuery/ExtentionsLinq.cs b/src/SimpleQuery/ExtentionsLinq.cs index 8636058..ef25b64 100644 --- a/src/SimpleQuery/ExtentionsLinq.cs +++ b/src/SimpleQuery/ExtentionsLinq.cs @@ -1,11 +1,7 @@ -using SimpleQuery.Domain.Data.Dialects; -using System; +using System; using System.Collections.Generic; using System.Data; -using System.Linq; using System.Linq.Expressions; -using System.Text; -using System.Threading.Tasks; namespace SimpleQuery { @@ -24,32 +20,18 @@ public static IEnumerable Select(this IDbConnection dbConnection, Expressi var wasClosed = dbConnection.State == ConnectionState.Closed; if (wasClosed) dbConnection.Open(); - - var type = typeof(T); - var cacheType = typeof(List); + var instanceModel = new T(); - IScriptBuilder scripBuilder = GetScriptBuild(dbConnection); - var selectScript = scripBuilder.GetSelectCommand(instanceModel); - var whereScript = scripBuilder.GetWhereCommand(whereExpression); - var selectAndWhere = selectScript + " " + whereScript; - var reader = scripBuilder.ExecuteReader(selectAndWhere, dbConnection); - var listModel = new List(); - - var dataTable = new DataTable(); - dataTable.Load(reader); - - foreach (DataRow row in dataTable.Rows) - { - var newModel = GetModelByDataRow(row); - listModel.Add(newModel); - } + var scripBuilder = GetScriptBuild(dbConnection); + var selectScript = scripBuilder.GetSelectCommand(instanceModel, whereExpression); - if (wasClosed) dbConnection.Close(); - - reader.Close(); + var elements = QueryOptionmized(dbConnection, selectScript, GetModel); + + if (wasClosed) + dbConnection.Close(); - return listModel; + return elements; } /// /// Get type list model @@ -65,29 +47,12 @@ public static IEnumerable Select(this IDbConnection dbConnection, string s if (wasClosed) dbConnection.Open(); - var type = typeof(T); - var cacheType = typeof(List); - var instanceModel = new T(); - - var command = dbConnection.CreateCommand(); - command.CommandText = sqlCommandText; - var reader = command.ExecuteReader(); - var listModel = new List(); - - var dataTable = new DataTable(); - dataTable.Load(reader); - - foreach (DataRow row in dataTable.Rows) - { - var newModel = GetModelByDataRow(row); - listModel.Add(newModel); - } - - if (wasClosed) dbConnection.Close(); + var elements = QueryOptionmized(dbConnection, sqlCommandText, GetModel); - reader.Close(); + if (wasClosed) + dbConnection.Close(); - return listModel; + return elements; } /// /// Get typed list model @@ -101,30 +66,15 @@ public static IEnumerable Query(this IDbConnection dbConnection, string co { var wasClosed = dbConnection.State == ConnectionState.Closed; - if (wasClosed) dbConnection.Open(); - - var type = typeof(T); - var cacheType = typeof(List); - var instanceModel = new T(); - - IScriptBuilder scripBuilder = GetScriptBuild(dbConnection); - var reader = scripBuilder.ExecuteReader(commandText, dbConnection); - var listModel = new List(); + if (wasClosed) + dbConnection.Open(); + + var elements = QueryOptionmized(dbConnection, commandText, GetModel); - var dataTable = new DataTable(); - dataTable.Load(reader); + if (wasClosed) + dbConnection.Close(); - foreach (DataRow row in dataTable.Rows) - { - var newModel = GetModelByDataRow(row); - listModel.Add(newModel); - } - - if (wasClosed) dbConnection.Close(); - - reader.Close(); - - return listModel; + return elements; } /// /// Get primitive types as List @@ -139,13 +89,15 @@ public static IEnumerable Scalar(this IDbConnection dbConnection, string c { var wasClosed = dbConnection.State == ConnectionState.Closed; - if (wasClosed) dbConnection.Open(); + if (wasClosed) + dbConnection.Open(); var type = typeof(T); var list = new List< T>(); - IScriptBuilder scripBuilder = GetScriptBuild(dbConnection); + var scripBuilder = GetScriptBuild(dbConnection); var reader = scripBuilder.ExecuteReader(commandText, dbConnection); + while (reader.Read()) { @@ -177,7 +129,8 @@ public static IEnumerable Scalar(this IDbConnection dbConnection, string c list.Add((T)objectRead); } - if (wasClosed) dbConnection.Close(); + if (wasClosed) + dbConnection.Close(); reader.Close(); From 92630ca304e7840707a65b658be7b1631856eced Mon Sep 17 00:00:00 2001 From: Fabio Nascimento Date: Fri, 26 Aug 2022 18:34:10 -0300 Subject: [PATCH 2/4] Corrigido Erro na consulta e na quantidade --- src/SimpleQuery.Tests/UnitTestDialectHana.cs | 13 +++- src/SimpleQuery/Extentions.cs | 76 ++++++++++---------- 2 files changed, 51 insertions(+), 38 deletions(-) diff --git a/src/SimpleQuery.Tests/UnitTestDialectHana.cs b/src/SimpleQuery.Tests/UnitTestDialectHana.cs index 00c881f..ac79a3b 100644 --- a/src/SimpleQuery.Tests/UnitTestDialectHana.cs +++ b/src/SimpleQuery.Tests/UnitTestDialectHana.cs @@ -171,13 +171,24 @@ public void TestInsertOperationHana() [TestMethod] public void TestSelectOperationHana() { + IScriptBuilder builder = new ScriptHanaBuilder(); var hanaConnection = System.Data.Common.DbProviderFactories.GetFactory("Sap.Data.Hana").CreateConnection(); hanaConnection.ConnectionString = ConfigurationManager.ConnectionStrings["hana"].ConnectionString; hanaConnection.Open(); + + try + { + builder.Execute("drop table \"Cliente\"", hanaConnection); + } + catch (Exception) + { + + } + var trans = hanaConnection.BeginTransaction(); using (var conn = hanaConnection) { - IScriptBuilder builder = new ScriptHanaBuilder(); + var cliente = new Cliente() { Id = 1, Nome = "Moisés", Ativo = true }; var cliente2 = new Cliente() { Id = 2, Nome = "José", Ativo = true }; diff --git a/src/SimpleQuery/Extentions.cs b/src/SimpleQuery/Extentions.cs index b91609a..e2cef82 100644 --- a/src/SimpleQuery/Extentions.cs +++ b/src/SimpleQuery/Extentions.cs @@ -242,7 +242,7 @@ public static int Execute(this IDbConnection dbConnection, string commandText, return rowsCount; } - + /// /// Get all records from database in typed model /// @@ -258,25 +258,25 @@ public static IEnumerable GetAll(this IDbConnection dbConnection, T model if (wasClosed) dbConnection.Open(); - + var scripBuilder = GetScriptBuild(dbConnection); var selectScript = scripBuilder.GetSelectCommand(new T()); - + var elements = QueryOptionmized(dbConnection, selectScript, GetModel); - + if (wasClosed) dbConnection.Close(); return elements; } - static TModel[] QueryOptionmized( - IDbConnection connection, - string command, - Func, TModel> toObject) where TModel : class, new() + static TModel[] QueryOptionmized( + IDbConnection connection, + string command, + Func, TModel> toObject) where TModel : class, new() { var quantidadeDeRegistros = QueryCount(connection, command); - + var elementos = new TModel[quantidadeDeRegistros]; var scripBuilder = GetScriptBuild(connection); @@ -289,7 +289,9 @@ static TModel[] QueryOptionmized( try { var name = rdr.GetName(i); - cachedOrdinal.Add(rdr.GetName(i), rdr.GetOrdinal(name)); + + if (!cachedOrdinal.TryGetValue(name, out var _)) + cachedOrdinal.Add(rdr.GetName(i), rdr.GetOrdinal(name)); } catch (Exception e) { @@ -314,39 +316,39 @@ static TModel[] QueryOptionmized( return elementos; } - private static int QueryCount(IDbConnection dbConnection, string command) - { - var commandCount = "SELECT COUNT(1) FROM ({command}) as a"; + private static int QueryCount(IDbConnection dbConnection, string command) + { + var commandCount = $"SELECT COUNT(1) FROM ({command}) as a"; - var qtd = dbConnection.Scalar(command); + var qtd = dbConnection.Scalar(commandCount); - return qtd.FirstOrDefault(); - } + return qtd.FirstOrDefault(); + } - private static T GetModel(IDataReader dataReader, Dictionary record) where T : class, new() - { - var model = new T(); + private static T GetModel(IDataReader dataReader, Dictionary record) where T : class, new() + { + var model = new T(); - var properties = model - .GetType() - .GetProperties(BindingFlags.Instance | BindingFlags.Public); + var properties = model + .GetType() + .GetProperties(BindingFlags.Instance | BindingFlags.Public); - foreach (var item in properties) - { - if (!record.TryGetValue(item.Name, out var fieldIndex)) - { - continue; - } - - var rowValue = dataReader[fieldIndex]; - var value = ChangeType(rowValue, item.PropertyType); + foreach (var item in properties) + { + if (!record.TryGetValue(item.Name, out var fieldIndex)) + { + continue; + } - item.SetValue(model, dataReader.IsDBNull(fieldIndex) ? null : value); - } + var rowValue = dataReader[fieldIndex]; + var value = ChangeType(rowValue, item.PropertyType); + + item.SetValue(model, dataReader.IsDBNull(fieldIndex) ? null : value); + } + + return model; + } - return model; - } - private static T GetModelByDataRow(DataRow row) where T : class, new() { var model = new T(); @@ -429,5 +431,5 @@ public static IScriptBuilder GetScriptBuild(this IDbConnection dbConnection) return new ScriptAnsiBuilder(); } } - + } \ No newline at end of file From 154ebd5008a52dcc719788ed9a19380e3bab6cea Mon Sep 17 00:00:00 2001 From: Fabio Nascimento Date: Mon, 5 Sep 2022 11:56:07 -0300 Subject: [PATCH 3/4] Add Tests With Order By --- src/SimpleQuery.Tests/UnitTestDialectHana.cs | 43 ++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/SimpleQuery.Tests/UnitTestDialectHana.cs b/src/SimpleQuery.Tests/UnitTestDialectHana.cs index ac79a3b..5f5782c 100644 --- a/src/SimpleQuery.Tests/UnitTestDialectHana.cs +++ b/src/SimpleQuery.Tests/UnitTestDialectHana.cs @@ -211,6 +211,49 @@ public void TestSelectOperationHana() } [TestMethod] + public void TestSelectOperationHanaWithQuery() + { + IScriptBuilder builder = new ScriptHanaBuilder(); + var hanaConnection = System.Data.Common.DbProviderFactories.GetFactory("Sap.Data.Hana").CreateConnection(); + hanaConnection.ConnectionString = ConfigurationManager.ConnectionStrings["hana"].ConnectionString; + hanaConnection.Open(); + + try + { + builder.Execute("drop table \"Cliente\"", hanaConnection); + } + catch (Exception) + { + + } + + var trans = hanaConnection.BeginTransaction(); + using (var conn = hanaConnection) + { + + + var cliente = new Cliente() { Id = 1, Nome = "Moisés", Ativo = true }; + var cliente2 = new Cliente() { Id = 2, Nome = "José", Ativo = true }; + + var createTableScript = builder.GetCreateTableCommand(); + var insertScript1 = builder.GetInsertCommand(cliente); + var insertScript2 = builder.GetInsertCommand(cliente2); + builder.Execute(createTableScript, conn); + builder.Execute(insertScript1, conn); + builder.Execute(insertScript2, conn); + + var clientes = conn.Select("Select * From \"Cliente\" Order By \"Id\""); + Assert.AreEqual(2, clientes.Count()); + Assert.AreEqual("Moisés", clientes.ToList()[0].Nome); + Assert.AreEqual("José", clientes.ToList()[1].Nome); + + trans.Rollback(); + builder.Execute("drop table \"Cliente\"", hanaConnection); + } + } + + + [TestMethod] public void TestHanaCreateTableScript() { IScriptBuilder builder = new ScriptHanaBuilder(); From 06e270dace9e5f8e25f5dde34d134f871a9a8813 Mon Sep 17 00:00:00 2001 From: Fabio Nascimento Date: Mon, 5 Sep 2022 14:54:52 -0300 Subject: [PATCH 4/4] Tentativa de remover Order By das queries --- src/SimpleQuery.Tests/App.config | 2 +- .../UnitTestDialectSQLServer.cs | 42 +++++++++++++++++++ .../UnitTestExtentionsSQLServer.cs | 9 ++++ src/SimpleQuery/Extentions.cs | 26 +++++++++++- 4 files changed, 77 insertions(+), 2 deletions(-) diff --git a/src/SimpleQuery.Tests/App.config b/src/SimpleQuery.Tests/App.config index 0fddf06..7fb2ef4 100644 --- a/src/SimpleQuery.Tests/App.config +++ b/src/SimpleQuery.Tests/App.config @@ -6,7 +6,7 @@ - + diff --git a/src/SimpleQuery.Tests/UnitTestDialectSQLServer.cs b/src/SimpleQuery.Tests/UnitTestDialectSQLServer.cs index a14cbf1..df2e93d 100644 --- a/src/SimpleQuery.Tests/UnitTestDialectSQLServer.cs +++ b/src/SimpleQuery.Tests/UnitTestDialectSQLServer.cs @@ -284,6 +284,48 @@ public void TestSelectOperationSqlServer() } } } + + + + [TestMethod] + public void TestSelectOperationHanaWithQuery() + { + IScriptBuilder builder = new ScriptSqlServerBuilder(); + var sqlConnection = new SqlConnection(connstring); + sqlConnection.Open(); + + try + { + builder.Execute("drop table \"Cliente\"", sqlConnection); + } + catch (Exception) + { + + } + + using (var conn = sqlConnection) + { + + + var cliente = new Cliente() { Id = 1, Nome = "Moisés", Ativo = true }; + var cliente2 = new Cliente() { Id = 2, Nome = "José", Ativo = true }; + + var createTableScript = builder.GetCreateTableCommand(); + var insertScript1 = builder.GetInsertCommand(cliente); + var insertScript2 = builder.GetInsertCommand(cliente2); + builder.Execute(createTableScript, conn); + builder.Execute(insertScript1, conn); + builder.Execute(insertScript2, conn); + + var clientes = conn.Select("Select * From \"Cliente\" Order By \"Id\""); + Assert.AreEqual(2, clientes.Count()); + Assert.AreEqual("Moisés", clientes.ToList()[0].Nome); + Assert.AreEqual("José", clientes.ToList()[1].Nome); + + builder.Execute("drop table \"Cliente\"", sqlConnection); + } + } + public string connstring => ConfigurationManager.ConnectionStrings["sqlserver"].ConnectionString; diff --git a/src/SimpleQuery.Tests/UnitTestExtentionsSQLServer.cs b/src/SimpleQuery.Tests/UnitTestExtentionsSQLServer.cs index 9da56fb..ac73975 100644 --- a/src/SimpleQuery.Tests/UnitTestExtentionsSQLServer.cs +++ b/src/SimpleQuery.Tests/UnitTestExtentionsSQLServer.cs @@ -17,6 +17,15 @@ public void SQLServerUpdateModel() var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["SQLServer"].ConnectionString); var scriptBuilder = conn.GetScriptBuild(); + try + { + scriptBuilder.Execute("drop table \"Cliente\"", conn); + } + catch (Exception) + { + + } + var cliente = new Cliente() { Nome = "Miranda" }; var createTableScript = scriptBuilder.GetCreateTableCommand(); diff --git a/src/SimpleQuery/Extentions.cs b/src/SimpleQuery/Extentions.cs index e2cef82..7ab35e1 100644 --- a/src/SimpleQuery/Extentions.cs +++ b/src/SimpleQuery/Extentions.cs @@ -6,6 +6,7 @@ using System.Data; using System.Linq; using System.Reflection; +using System.Text.RegularExpressions; namespace SimpleQuery { @@ -318,12 +319,35 @@ static TModel[] QueryOptionmized( private static int QueryCount(IDbConnection dbConnection, string command) { - var commandCount = $"SELECT COUNT(1) FROM ({command}) as a"; + var semOrderBy = SubStringInicioAte(command, "ORDER BY"); + var commandCount = $"SELECT COUNT(1) FROM ({semOrderBy}) as a"; var qtd = dbConnection.Scalar(commandCount); return qtd.FirstOrDefault(); } + + public static string SubStringInicioAte(this string valor, string textoDoIndice) + { + var indiceFinal = valor?.IndexOf(textoDoIndice, StringComparison.InvariantCultureIgnoreCase) ?? -1; + + return indiceFinal == -1 ? valor : SubStringInicioAte(valor, indiceFinal); + } + + public static string SubStringInicioAte(this string valor, int indiceFinal) + { + if (string.IsNullOrWhiteSpace(valor)) + return string.Empty; + + if (indiceFinal == -1) + { + return valor; + } + + return valor + .Substring(0, indiceFinal) + .Trim(); + } private static T GetModel(IDataReader dataReader, Dictionary record) where T : class, new() {