Skip to content

Commit 9ca89a2

Browse files
committed
Lazily allocate MySqlParameterCollection.
This improves the performance of creating MySqlCommand objects with no parameters.
1 parent d3242c3 commit 9ca89a2

File tree

4 files changed

+16
-13
lines changed

4 files changed

+16
-13
lines changed

src/MySqlConnector/Core/CachedProcedure.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ private CachedProcedure(string schema, string component, ReadOnlyCollection<Cach
6363
internal MySqlParameterCollection AlignParamsWithDb(MySqlParameterCollection parameterCollection)
6464
{
6565
var alignedParams = new MySqlParameterCollection();
66-
var returnParam = parameterCollection.FirstOrDefault(x => x.Direction == ParameterDirection.ReturnValue);
66+
var returnParam = parameterCollection?.FirstOrDefault(x => x.Direction == ParameterDirection.ReturnValue);
6767

6868
foreach (var cachedParam in Parameters)
6969
{
@@ -74,7 +74,7 @@ internal MySqlParameterCollection AlignParamsWithDb(MySqlParameterCollection par
7474
}
7575
else
7676
{
77-
var index = parameterCollection.NormalizedIndexOf(cachedParam.Name);
77+
var index = parameterCollection?.NormalizedIndexOf(cachedParam.Name) ?? -1;
7878
alignParam = index >= 0 ? parameterCollection[index] : throw new ArgumentException($"Parameter '{cachedParam.Name}' not found in the collection.");
7979
}
8080

src/MySqlConnector/Core/PreparedStatementCommandExecutor.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,11 @@ private PayloadData CreateQueryPayload(PreparedStatement preparedStatement, MySq
6767
for (var i = 0; i < preparedStatement.Statement.ParameterNames.Count; i++)
6868
{
6969
var parameterName = preparedStatement.Statement.ParameterNames[i];
70-
var parameterIndex = parameterName != null ? parameterCollection.NormalizedIndexOf(parameterName) : preparedStatement.Statement.ParameterIndexes[i];
70+
var parameterIndex = parameterName != null ? (parameterCollection?.NormalizedIndexOf(parameterName) ?? -1) : preparedStatement.Statement.ParameterIndexes[i];
7171
if (parameterIndex == -1 && parameterName != null)
7272
throw new MySqlException("Parameter '{0}' must be defined.".FormatInvariant(parameterName));
73-
else if (parameterIndex < 0 || parameterIndex >= parameterCollection.Count)
74-
throw new MySqlException("Parameter index {0} is invalid when only {1} parameter{2} defined.".FormatInvariant(parameterIndex, parameterCollection.Count, parameterCollection.Count == 1 ? " is" : "s are"));
73+
else if (parameterIndex < 0 || parameterIndex >= (parameterCollection?.Count ?? 0))
74+
throw new MySqlException("Parameter index {0} is invalid when only {1} parameter{2} defined.".FormatInvariant(parameterIndex, parameterCollection?.Count ?? 0, parameterCollection?.Count == 1 ? " is" : "s are"));
7575
parameters[i] = parameterCollection[parameterIndex];
7676
}
7777

src/MySqlConnector/Core/StatementPreparer.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,16 @@ public ArraySegment<byte> ParseAndBindParameters()
4545

4646
private int GetParameterIndex(string name)
4747
{
48-
var index = m_parameters.NormalizedIndexOf(name);
48+
var index = m_parameters?.NormalizedIndexOf(name) ?? -1;
4949
if (index == -1 && (m_options & StatementPreparerOptions.AllowUserVariables) == 0)
5050
throw new MySqlException("Parameter '{0}' must be defined. To use this as a variable, set 'Allow User Variables=true' in the connection string.".FormatInvariant(name));
5151
return index;
5252
}
5353

5454
private MySqlParameter GetInputParameter(int index)
5555
{
56-
if (index >= m_parameters.Count)
57-
throw new MySqlException("Parameter index {0} is invalid when only {1} parameter{2} defined.".FormatInvariant(index, m_parameters.Count, m_parameters.Count == 1 ? " is" : "s are"));
56+
if (index >= (m_parameters?.Count ?? 0))
57+
throw new MySqlException("Parameter index {0} is invalid when only {1} parameter{2} defined.".FormatInvariant(index, m_parameters?.Count ?? 0, m_parameters?.Count == 1 ? " is" : "s are"));
5858
var parameter = m_parameters[index];
5959
if (parameter.Direction != ParameterDirection.Input && (m_options & StatementPreparerOptions.AllowOutputParameters) == 0)
6060
throw new MySqlException("Only ParameterDirection.Input is supported when CommandType is Text (parameter name: {0})".FormatInvariant(parameter.ParameterName));

src/MySqlConnector/MySql.Data.MySqlClient/MySqlCommand.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ public MySqlCommand(string commandText, MySqlConnection connection, MySqlTransac
4141
CommandText = commandText;
4242
Connection = connection;
4343
Transaction = transaction;
44-
m_parameterCollection = new MySqlParameterCollection();
4544
CommandType = CommandType.Text;
4645
}
4746

@@ -50,6 +49,8 @@ public MySqlCommand(string commandText, MySqlConnection connection, MySqlTransac
5049
get
5150
{
5251
VerifyNotDisposed();
52+
if (m_parameterCollection == null)
53+
m_parameterCollection = new MySqlParameterCollection();
5354
return m_parameterCollection;
5455
}
5556
}
@@ -116,7 +117,7 @@ private bool NeedsPrepare(out Exception exception)
116117

117118
private async Task DoPrepareAsync(IOBehavior ioBehavior, CancellationToken cancellationToken)
118119
{
119-
var statementPreparer = new StatementPreparer(CommandText, Parameters, CreateStatementPreparerOptions());
120+
var statementPreparer = new StatementPreparer(CommandText, m_parameterCollection, CreateStatementPreparerOptions());
120121
var parsedStatements = statementPreparer.SplitStatements();
121122

122123
if (parsedStatements.Statements.Count > 1)
@@ -231,7 +232,7 @@ protected override DbConnection DbConnection
231232
set => Connection = (MySqlConnection) value;
232233
}
233234

234-
protected override DbParameterCollection DbParameterCollection => m_parameterCollection;
235+
protected override DbParameterCollection DbParameterCollection => Parameters;
235236

236237
protected override DbTransaction DbTransaction
237238
{
@@ -326,6 +327,7 @@ protected override void Dispose(bool disposing)
326327
{
327328
base.Dispose(disposing);
328329
}
330+
m_isDisposed = true;
329331
}
330332

331333
/// <summary>
@@ -403,14 +405,14 @@ internal StatementPreparerOptions CreateStatementPreparerOptions()
403405

404406
private void VerifyNotDisposed()
405407
{
406-
if (m_parameterCollection == null)
408+
if (m_isDisposed)
407409
throw new ObjectDisposedException(GetType().Name);
408410
}
409411

410412
private bool IsValid(out Exception exception)
411413
{
412414
exception = null;
413-
if (m_parameterCollection == null)
415+
if (m_isDisposed)
414416
exception = new ObjectDisposedException(GetType().Name);
415417
else if (Connection == null)
416418
exception = new InvalidOperationException("Connection property must be non-null.");
@@ -429,6 +431,7 @@ private bool IsValid(out Exception exception)
429431

430432
static int s_commandId = 1;
431433

434+
bool m_isDisposed;
432435
MySqlConnection m_connection;
433436
string m_commandText;
434437
MySqlParameterCollection m_parameterCollection;

0 commit comments

Comments
 (0)