diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteCommand.cs b/src/Microsoft.Data.Sqlite.Core/SqliteCommand.cs
index f8a6e3b99ee..a6d00112b0d 100644
--- a/src/Microsoft.Data.Sqlite.Core/SqliteCommand.cs
+++ b/src/Microsoft.Data.Sqlite.Core/SqliteCommand.cs
@@ -24,8 +24,7 @@ namespace Microsoft.Data.Sqlite
/// Async Limitations
public class SqliteCommand : DbCommand
{
- private readonly Lazy _parameters = new Lazy(
- () => new SqliteParameterCollection());
+ private SqliteParameterCollection _parameters;
private readonly List _preparedStatements = new List();
private SqliteConnection _connection;
@@ -165,7 +164,7 @@ protected override DbTransaction DbTransaction
/// The collection of parameters used by the command.
/// Parameters
public new virtual SqliteParameterCollection Parameters
- => _parameters.Value;
+ => _parameters ??= new SqliteParameterCollection();
///
/// Gets the collection of parameters used by the command.
@@ -326,12 +325,7 @@ private IEnumerable GetStatements(Stopwatch timer)
? PrepareAndEnumerateStatements(timer)
: _preparedStatements)
{
- var boundParams = 0;
-
- if (_parameters.IsValueCreated)
- {
- boundParams = _parameters.Value.Bind(stmt);
- }
+ var boundParams = _parameters?.Bind(stmt) ?? 0;
var expectedParams = sqlite3_bind_parameter_count(stmt);
if (expectedParams != boundParams)
@@ -341,8 +335,8 @@ private IEnumerable GetStatements(Stopwatch timer)
{
var name = sqlite3_bind_parameter_name(stmt, i).utf8_to_string();
- if (_parameters.IsValueCreated
- && !_parameters.Value.Cast().Any(p => p.ParameterName == name))
+ if (_parameters != null
+ && !_parameters.Cast().Any(p => p.ParameterName == name))
{
unboundParams.Add(name);
}
diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteConnection.cs b/src/Microsoft.Data.Sqlite.Core/SqliteConnection.cs
index 05092a51f41..d3e8ec0d28d 100644
--- a/src/Microsoft.Data.Sqlite.Core/SqliteConnection.cs
+++ b/src/Microsoft.Data.Sqlite.Core/SqliteConnection.cs
@@ -27,18 +27,14 @@ public partial class SqliteConnection : DbConnection
private readonly List> _commands = new List>();
- private readonly Dictionary _collations
- = new Dictionary(StringComparer.OrdinalIgnoreCase);
+ private Dictionary _collations;
- private readonly Dictionary<(string name, int arity), (int flags, object state, delegate_function_scalar func)> _functions
- = new Dictionary<(string, int), (int, object, delegate_function_scalar)>(FunctionsKeyComparer.Instance);
+ private Dictionary<(string name, int arity), (int flags, object state, delegate_function_scalar func)> _functions;
- private readonly Dictionary<(string name, int arity), (int flags, object state, delegate_function_aggregate_step func_step,
- delegate_function_aggregate_final func_final)> _aggregates
- = new Dictionary<(string, int), (int, object, delegate_function_aggregate_step, delegate_function_aggregate_final)>(
- FunctionsKeyComparer.Instance);
+ private Dictionary<(string name, int arity), (int flags, object state, delegate_function_aggregate_step func_step,
+ delegate_function_aggregate_final func_final)> _aggregates;
- private readonly HashSet<(string file, string proc)> _extensions = new HashSet<(string, string)>();
+ private HashSet<(string file, string proc)> _extensions;
private string _connectionString;
private ConnectionState _state;
@@ -276,27 +272,37 @@ public override void Open()
this.ExecuteNonQuery("PRAGMA recursive_triggers = 1;");
}
- foreach (var item in _collations)
+ if (_collations != null)
{
- rc = sqlite3_create_collation(_db, item.Key, item.Value.state, item.Value.collation);
- SqliteException.ThrowExceptionForRC(rc, _db);
+ foreach (var item in _collations)
+ {
+ rc = sqlite3_create_collation(_db, item.Key, item.Value.state, item.Value.collation);
+ SqliteException.ThrowExceptionForRC(rc, _db);
+ }
}
- foreach (var item in _functions)
+ if (_functions != null)
{
- rc = sqlite3_create_function(_db, item.Key.name, item.Key.arity, item.Value.state, item.Value.func);
- SqliteException.ThrowExceptionForRC(rc, _db);
+ foreach (var item in _functions)
+ {
+ rc = sqlite3_create_function(_db, item.Key.name, item.Key.arity, item.Value.state, item.Value.func);
+ SqliteException.ThrowExceptionForRC(rc, _db);
+ }
}
- foreach (var item in _aggregates)
+ if (_aggregates != null)
{
- rc = sqlite3_create_function(
- _db, item.Key.name, item.Key.arity, item.Value.state, item.Value.func_step, item.Value.func_final);
- SqliteException.ThrowExceptionForRC(rc, _db);
+ foreach (var item in _aggregates)
+ {
+ rc = sqlite3_create_function(
+ _db, item.Key.name, item.Key.arity, item.Value.state, item.Value.func_step, item.Value.func_final);
+ SqliteException.ThrowExceptionForRC(rc, _db);
+ }
}
var extensionsEnabledForLoad = false;
- if (_extensions.Count != 0)
+ if (_extensions != null
+ && _extensions.Count != 0)
{
rc = sqlite3_enable_load_extension(_db, 1);
SqliteException.ThrowExceptionForRC(rc, _db);
@@ -449,6 +455,7 @@ public virtual void CreateCollation(string name, T state, Func(StringComparer.OrdinalIgnoreCase);
_collations[name] = (state, collation);
}
@@ -546,6 +553,7 @@ public virtual void LoadExtension(string file, string proc = null)
}
}
+ _extensions ??= new HashSet<(string, string)>();
_extensions.Add((file, proc));
}
@@ -677,6 +685,7 @@ private void CreateFunctionCore(
SqliteException.ThrowExceptionForRC(rc, _db);
}
+ _functions ??= new Dictionary<(string, int), (int, object, delegate_function_scalar)>(FunctionsKeyComparer.Instance);
_functions[(name, arity)] = (flags, state, func);
}
@@ -771,6 +780,8 @@ private void CreateAggregateCore(
SqliteException.ThrowExceptionForRC(rc, _db);
}
+ _aggregates ??= new Dictionary<(string, int), (int, object, delegate_function_aggregate_step, delegate_function_aggregate_final)>(
+ FunctionsKeyComparer.Instance);
_aggregates[(name, arity)] = (flags, state, func_step, func_final);
}
diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteDataRecord.cs b/src/Microsoft.Data.Sqlite.Core/SqliteDataRecord.cs
index a1f4cae9902..1ac1c8725a7 100644
--- a/src/Microsoft.Data.Sqlite.Core/SqliteDataRecord.cs
+++ b/src/Microsoft.Data.Sqlite.Core/SqliteDataRecord.cs
@@ -15,8 +15,8 @@ namespace Microsoft.Data.Sqlite
internal class SqliteDataRecord : SqliteValueReader, IDisposable
{
private readonly SqliteConnection _connection;
- private readonly byte[][] _blobCache;
- private readonly int?[] _typeCache;
+ private byte[][] _blobCache;
+ private int?[] _typeCache;
private bool _stepped;
private int? _rowidOrdinal;
@@ -25,8 +25,6 @@ public SqliteDataRecord(sqlite3_stmt stmt, bool hasRows, SqliteConnection connec
Handle = stmt;
HasRows = hasRows;
_connection = connection;
- _blobCache = new byte[FieldCount][];
- _typeCache = new int?[FieldCount];
}
public virtual object this[string name]
@@ -146,10 +144,11 @@ public virtual Type GetFieldType(int ordinal)
var sqliteType = GetSqliteType(ordinal);
if (sqliteType == SQLITE_NULL)
{
- sqliteType = _typeCache[ordinal] ?? Sqlite3AffinityType(GetDataTypeName(ordinal));
+ sqliteType = _typeCache?[ordinal] ?? Sqlite3AffinityType(GetDataTypeName(ordinal));
}
else
{
+ _typeCache ??= new int?[FieldCount];
_typeCache[ordinal] = sqliteType;
}
@@ -317,7 +316,10 @@ public bool Read()
var rc = sqlite3_step(Handle);
SqliteException.ThrowExceptionForRC(rc, _connection.Handle);
- Array.Clear(_blobCache, 0, _blobCache.Length);
+ if (_blobCache != null)
+ {
+ Array.Clear(_blobCache, 0, _blobCache.Length);
+ }
return rc != SQLITE_DONE;
}
@@ -334,10 +336,11 @@ private byte[] GetCachedBlob(int ordinal)
throw new ArgumentOutOfRangeException(nameof(ordinal), ordinal, message: null);
}
- var blob = _blobCache[ordinal];
+ var blob = _blobCache?[ordinal];
if (blob == null)
{
blob = GetBlob(ordinal);
+ _blobCache ??= new byte[FieldCount][];
_blobCache[ordinal] = blob;
}