diff --git a/src/Serenity.Net.Data/Serenity.Net.Data.csproj b/src/Serenity.Net.Data/Serenity.Net.Data.csproj
index 4efa8ce3e5..44fbc9b6b6 100644
--- a/src/Serenity.Net.Data/Serenity.Net.Data.csproj
+++ b/src/Serenity.Net.Data/Serenity.Net.Data.csproj
@@ -9,6 +9,5 @@
-
\ No newline at end of file
diff --git a/src/Serenity.Net.Data/SqlHelpers/SqlCommandDumper.cs b/src/Serenity.Net.Data/SqlHelpers/SqlCommandDumper.cs
index 9ddc6d9002..01ebf3dcb1 100644
--- a/src/Serenity.Net.Data/SqlHelpers/SqlCommandDumper.cs
+++ b/src/Serenity.Net.Data/SqlHelpers/SqlCommandDumper.cs
@@ -1,5 +1,3 @@
-using Microsoft.Data.SqlClient;
-
namespace Serenity.Data;
///
@@ -12,13 +10,30 @@ public class SqlCommandDumper
///
/// The SQL command.
///
- public static string GetCommandText(SqlCommand sqc)
+ public static string GetCommandText(IDbCommand sqc)
{
var sbCommandText = new StringBuilder();
+ bool initialized = false;
+ PropertyInfo sqlDbTypeProperty = null;
+ PropertyInfo sizeProperty = null;
+
// params
- for (int i = 0; i < sqc.Parameters.Count; i++)
- LogParameterToSqlBatch(sqc.Parameters[i], sbCommandText);
+ foreach (IDbDataParameter parameter in sqc.Parameters)
+ {
+ if (!initialized)
+ {
+ initialized = true;
+ var isSqlServer = parameter.GetType().FullName == "Microsoft.Data.SqlClient.SqlParameter" ||
+ parameter.GetType().FullName == "System.Data.SqlClient.SqlParameter";
+ if (!isSqlServer)
+ {
+ sqlDbTypeProperty = parameter.GetType().GetProperty("SqlDbType");
+ sizeProperty = parameter.GetType().GetProperty("Size");
+ }
+ }
+ LogParameterToSqlBatch(parameter, sbCommandText, sqlDbTypeProperty, sizeProperty);
+ }
sbCommandText.AppendLine("");
@@ -28,9 +43,9 @@ public static string GetCommandText(SqlCommand sqc)
sbCommandText.Append("EXEC ");
bool hasReturnValue = false;
- for (int i = 0; i < sqc.Parameters.Count; i++)
+ foreach (IDbDataParameter param in sqc.Parameters)
{
- if (sqc.Parameters[i].Direction == ParameterDirection.ReturnValue)
+ if (param.Direction == ParameterDirection.ReturnValue)
hasReturnValue = true;
}
if (hasReturnValue)
@@ -41,9 +56,8 @@ public static string GetCommandText(SqlCommand sqc)
sbCommandText.Append(sqc.CommandText);
bool hasPrev = false;
- for (int i = 0; i < sqc.Parameters.Count; i++)
+ foreach (IDataParameter cParam in sqc.Parameters)
{
- var cParam = sqc.Parameters[i];
if (cParam.Direction != ParameterDirection.ReturnValue)
{
if (hasPrev)
@@ -66,7 +80,7 @@ public static string GetCommandText(SqlCommand sqc)
}
bool anyOut = false;
- foreach (SqlParameter p in sqc.Parameters)
+ foreach (IDataParameter p in sqc.Parameters)
if (p.Direction == ParameterDirection.ReturnValue ||
p.Direction == ParameterDirection.Output)
{
@@ -78,10 +92,8 @@ public static string GetCommandText(SqlCommand sqc)
{
sbCommandText.AppendLine("-- RESULTS");
sbCommandText.Append("SELECT 1 as Executed");
- for (int i = 0; i < sqc.Parameters.Count; i++)
+ foreach (IDataParameter cParam in sqc.Parameters)
{
- var cParam = sqc.Parameters[i];
-
if (cParam.Direction == ParameterDirection.ReturnValue)
{
sbCommandText.Append(", @returnValue as ReturnValue");
@@ -101,7 +113,8 @@ public static string GetCommandText(SqlCommand sqc)
return sbCommandText.ToString();
}
- private static void LogParameterToSqlBatch(SqlParameter param, StringBuilder sbCommandText)
+ private static void LogParameterToSqlBatch(IDbDataParameter param, StringBuilder sbCommandText,
+ PropertyInfo sqlDbTypeProperty, PropertyInfo sizeProperty)
{
sbCommandText.Append("DECLARE ");
if (param.Direction == ParameterDirection.ReturnValue)
@@ -113,18 +126,41 @@ private static void LogParameterToSqlBatch(SqlParameter param, StringBuilder sbC
sbCommandText.Append(param.ParameterName);
sbCommandText.Append(' ');
- if (param.SqlDbType != SqlDbType.Structured)
+ SqlDbType? sqlDbType = null;
+ int? size = null;
+ if (sqlDbTypeProperty != null)
{
- LogParameterType(param, sbCommandText);
- sbCommandText.Append(" = ");
- LogQuotedParameterValue(param.Value, sbCommandText);
+ try
+ {
+ sqlDbType = sqlDbTypeProperty.GetValue(param) as SqlDbType?;
+ }
+ catch
+ {
+ }
+ }
+ if (sizeProperty != null)
+ {
+ try
+ {
+ size = sizeProperty.GetValue(param) as int?;
+ }
+ catch
+ {
+ }
+ }
- sbCommandText.AppendLine(";");
+ if (sqlDbType != null)
+ {
+ LogParamSqlDbType(sqlDbType.Value, size ?? 0, sbCommandText);
}
else
{
- throw new NotImplementedException();
+ LogParamDbType(param, sbCommandText);
}
+
+ sbCommandText.Append(" = ");
+ LogQuotedParameterValue(param.Value, sbCommandText);
+ sbCommandText.AppendLine(";");
}
}
@@ -215,29 +251,27 @@ private static void LogQuotedParameterValue(object value, StringBuilder sbComman
}
}
- private static void LogParameterType(SqlParameter param, StringBuilder sbCommandText)
+ private static void LogParamDbType(IDataParameter param, StringBuilder sbCommandText)
+ {
+ sbCommandText.Append(param.DbType.ToString());
+ }
+
+ private static void LogParamSqlDbType(SqlDbType sqlDbType, int size, StringBuilder sbCommandText)
{
- switch (param.SqlDbType)
+ switch (sqlDbType)
{
// variable length
case SqlDbType.Char:
case SqlDbType.NChar:
case SqlDbType.Binary:
- {
- sbCommandText.Append(param.SqlDbType.ToString().ToUpperInvariant());
- sbCommandText.Append('(');
- sbCommandText.Append(param.Size == 0 ? 1 : param.Size);
- sbCommandText.Append(')');
- }
- break;
case SqlDbType.VarChar:
case SqlDbType.NVarChar:
case SqlDbType.VarBinary:
{
- sbCommandText.Append(param.SqlDbType.ToString().ToUpperInvariant());
- sbCommandText.Append("(");
- sbCommandText.Append(param.Size == 0 ? 1 : param.Size);
- sbCommandText.Append(")");
+ sbCommandText.Append(sqlDbType.ToString().ToUpperInvariant());
+ sbCommandText.Append('(');
+ sbCommandText.Append(size == 0 ? 1 : size);
+ sbCommandText.Append(')');
}
break;
// fixed length
@@ -260,7 +294,7 @@ private static void LogParameterType(SqlParameter param, StringBuilder sbCommand
case SqlDbType.UniqueIdentifier:
case SqlDbType.Image:
{
- sbCommandText.Append(param.SqlDbType.ToString().ToUpperInvariant());
+ sbCommandText.Append(sqlDbType.ToString().ToUpperInvariant());
}
break;
// Unknown
@@ -268,9 +302,9 @@ private static void LogParameterType(SqlParameter param, StringBuilder sbCommand
default:
{
sbCommandText.Append("/* UNKNOWN DATATYPE: ");
- sbCommandText.Append(param.SqlDbType.ToString().ToUpperInvariant());
+ sbCommandText.Append(sqlDbType.ToString().ToUpperInvariant());
sbCommandText.Append(" *" + "/ ");
- sbCommandText.Append(param.SqlDbType.ToString().ToUpperInvariant());
+ sbCommandText.Append(sqlDbType.ToString().ToUpperInvariant());
}
break;
}
diff --git a/src/Serenity.Net.Data/SqlHelpers/SqlHelper.cs b/src/Serenity.Net.Data/SqlHelpers/SqlHelper.cs
index e10f283669..6925b23266 100644
--- a/src/Serenity.Net.Data/SqlHelpers/SqlHelper.cs
+++ b/src/Serenity.Net.Data/SqlHelpers/SqlHelper.cs
@@ -1,6 +1,4 @@
-using Microsoft.Data.SqlClient;
using Microsoft.Extensions.Logging;
-using System.Data.Common;
using System.IO;
using Dictionary = System.Collections.Generic.Dictionary;
@@ -70,31 +68,7 @@ public static void LogCommand(string method, IDbCommand command, ILogger logger)
try
{
- if (command is SqlCommand sqlCmd)
- {
- logger.LogDebug("SQL - {method}[{uid}] - START\n{sql}", method, command.GetHashCode(), SqlCommandDumper.GetCommandText(sqlCmd));
- return;
- }
-
- if (command.Parameters?.Count <= 0)
- {
- logger.LogDebug("SQL - {method}[{uid}] - START\n{sql}", method, command.GetHashCode(), command.CommandText);
- return;
- }
-
- StringBuilder sb = new("");
- foreach (DbParameter p in command.Parameters)
- {
- sb.Append(p.ParameterName);
- sb.Append("=");
- if (p.Value == null || p.Value == DBNull.Value)
- sb.Append("");
- else
- sb.Append(p.Value.ToString());
- sb.Append("; ");
- }
-
- logger.LogDebug("SQL - {method}[{uid}] - START\n{sql}\n--PARAMS--\n{params}", method, command.GetHashCode(), command.CommandText, sb.ToString());
+ logger.LogDebug("SQL - {method}[{uid}] - START\n{sql}", method, command.GetHashCode(), SqlCommandDumper.GetCommandText(command));
}
catch (Exception ex)
{
@@ -222,19 +196,25 @@ public static IDbCommand NewCommand(IDbConnection connection, string commandText
/// True if exception is 10054, e.g. connection pool.
private static bool CheckConnectionPoolException(IDbConnection connection, Exception exception)
{
- if (exception is SqlException ex && ex.Number == 10054)
- {
- if ((connection is IHasOpenedOnce hoo && hoo.OpenedOnce) ||
- (connection is IHasCurrentTransaction hct && hct.CurrentTransaction != null))
- return false;
+ var exceptionType = exception.GetType();
- SqlConnection.ClearAllPools();
+ if ((connection is IHasOpenedOnce hoo && hoo.OpenedOnce) ||
+ (connection is IHasCurrentTransaction hct && hct.CurrentTransaction != null))
+ return false;
+
+ if (exceptionType.FullName == "Microsoft.Data.SqlException" ||
+ exceptionType.FullName == "System.Data.SqlException" &&
+ exceptionType.GetProperty("Number")?.GetValue(exception) is 10054)
+ {
+ var sqlConnectionType = exceptionType.Assembly.GetType(exceptionType.FullName.Replace("Exception", "Connection"));
+ var clearAllPools = sqlConnectionType?.GetMethod("ClearAllPools", BindingFlags.Static | BindingFlags.Public);
+ clearAllPools?.Invoke(null, null);
connection.Close();
connection.Open();
return true;
}
- else
- return false;
+
+ return false;
}
///
@@ -268,7 +248,7 @@ public static int ExecuteNonQuery(IDbCommand command, ILogger logger = null)
result = command.ExecuteNonQuery();
}
- catch (SqlException ex)
+ catch (Exception ex)
{
if (CheckConnectionPoolException(command.Connection, ex))
return command.ExecuteNonQuery();
@@ -477,7 +457,7 @@ public static IDataReader ExecuteReader(IDbConnection connection, string command
try
{
logger ??= connection.GetLogger();
-
+
if (logger?.IsEnabled(LogLevel.Debug) == true)
LogCommand("ExecuteReader", command, logger);
@@ -489,7 +469,7 @@ public static IDataReader ExecuteReader(IDbConnection connection, string command
return result;
}
- catch (SqlException ex)
+ catch (Exception ex)
{
if (CheckConnectionPoolException(connection, ex))
return command.ExecuteReader();
@@ -564,7 +544,7 @@ public static object ExecuteScalar(IDbConnection connection, string commandText,
return result;
}
- catch (SqlException ex)
+ catch (Exception ex)
{
if (CheckConnectionPoolException(connection, ex))
return command.ExecuteScalar();