diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props
index f897e55f77..9a8c0cb9f6 100644
--- a/src/Directory.Packages.props
+++ b/src/Directory.Packages.props
@@ -7,6 +7,7 @@
+
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
index d1dd14f6b7..ec18940c2a 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
@@ -201,62 +201,62 @@
Microsoft\Data\SqlClient\DataClassification\SensitivityClassification.cs
-
- Microsoft\Data\SqlClient\Diagnostics\DiagnosticScope.netcore.cs
+
+ Microsoft\Data\SqlClient\Diagnostics\DiagnosticScope.cs
-
- Microsoft\Data\SqlClient\Diagnostics\DiagnosticTransactionScope.netcore.cs
+
+ Microsoft\Data\SqlClient\Diagnostics\DiagnosticTransactionScope.cs
-
- Microsoft\Data\SqlClient\Diagnostics\SqlClientCommandAfter.netcore.cs
+
+ Microsoft\Data\SqlClient\Diagnostics\SqlClientCommandAfter.cs
-
- Microsoft\Data\SqlClient\Diagnostics\SqlClientCommandBefore.netcore.cs
+
+ Microsoft\Data\SqlClient\Diagnostics\SqlClientCommandBefore.cs
-
- Microsoft\Data\SqlClient\Diagnostics\SqlClientCommandError.netcore.cs
+
+ Microsoft\Data\SqlClient\Diagnostics\SqlClientCommandError.cs
-
- Microsoft\Data\SqlClient\Diagnostics\SqlClientConnectionCloseAfter.netcore.cs
+
+ Microsoft\Data\SqlClient\Diagnostics\SqlClientConnectionCloseAfter.cs
-
- Microsoft\Data\SqlClient\Diagnostics\SqlClientConnectionCloseBefore.netcore.cs
+
+ Microsoft\Data\SqlClient\Diagnostics\SqlClientConnectionCloseBefore.cs
-
- Microsoft\Data\SqlClient\Diagnostics\SqlClientConnectionCloseError.netcore.cs
+
+ Microsoft\Data\SqlClient\Diagnostics\SqlClientConnectionCloseError.cs
-
- Microsoft\Data\SqlClient\Diagnostics\SqlClientConnectionOpenAfter.netcore.cs
+
+ Microsoft\Data\SqlClient\Diagnostics\SqlClientConnectionOpenAfter.cs
-
- Microsoft\Data\SqlClient\Diagnostics\SqlClientConnectionOpenBefore.netcore.cs
+
+ Microsoft\Data\SqlClient\Diagnostics\SqlClientConnectionOpenBefore.cs
-
- Microsoft\Data\SqlClient\Diagnostics\SqlClientConnectionOpenError.netcore.cs
+
+ Microsoft\Data\SqlClient\Diagnostics\SqlClientConnectionOpenError.cs
Microsoft\Data\SqlClient\Diagnostics\SqlClientMetrics.cs
-
- Microsoft\Data\SqlClient\Diagnostics\SqlClientTransactionCommitAfter.netcore.cs
+
+ Microsoft\Data\SqlClient\Diagnostics\SqlClientTransactionCommitAfter.cs
-
- Microsoft\Data\SqlClient\Diagnostics\SqlClientTransactionCommitBefore.netcore.cs
+
+ Microsoft\Data\SqlClient\Diagnostics\SqlClientTransactionCommitBefore.cs
-
- Microsoft\Data\SqlClient\Diagnostics\SqlClientTransactionCommitError.netcore.cs
+
+ Microsoft\Data\SqlClient\Diagnostics\SqlClientTransactionCommitError.cs
-
- Microsoft\Data\SqlClient\Diagnostics\SqlClientTransactionRollbackAfter.netcore.cs
+
+ Microsoft\Data\SqlClient\Diagnostics\SqlClientTransactionRollbackAfter.cs
-
- Microsoft\Data\SqlClient\Diagnostics\SqlClientTransactionRollbackBefore.netcore.cs
+
+ Microsoft\Data\SqlClient\Diagnostics\SqlClientTransactionRollbackBefore.cs
-
- Microsoft\Data\SqlClient\Diagnostics\SqlClientTransactionRollbackError.netcore.cs
+
+ Microsoft\Data\SqlClient\Diagnostics\SqlClientTransactionRollbackError.cs
-
- Microsoft\Data\SqlClient\Diagnostics\SqlDiagnosticListener.netcore.cs
+
+ Microsoft\Data\SqlClient\Diagnostics\SqlDiagnosticListener.cs
Microsoft\Data\SqlClient\DisposableTemporaryOnStack.cs
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs
index d4f13efd80..7fb6462ddd 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs
@@ -61,7 +61,7 @@ public sealed partial class SqlConnection : DbConnection, ICloneable
private SqlRetryLogicBaseProvider _retryLogicProvider;
// diagnostics listener
- private static readonly SqlDiagnosticListener s_diagnosticListener = new SqlDiagnosticListener();
+ private static readonly SqlDiagnosticListener s_diagnosticListener = new();
// Transient Fault handling flag. This is needed to convey to the downstream mechanism of connection establishment, if Transient Fault handling should be used or not
// The downstream handling of Connection open is the same for idle connection resiliency. Currently we want to apply transient fault handling only to the connections opened
@@ -1458,8 +1458,8 @@ public void Open(SqlConnectionOverrides overrides)
PrepareStatisticsForNewConnection();
SqlStatistics statistics = null;
-
Exception e = null;
+
try
{
statistics = SqlStatistics.StartTimer(Statistics);
diff --git a/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.cs b/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.cs
index a3bb3b46c2..52a05a7fde 100644
--- a/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.cs
+++ b/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.cs
@@ -1960,6 +1960,417 @@ public sealed class SqlConfigurableRetryFactory
public static SqlRetryLogicBaseProvider CreateNoneRetryProvider() { throw null; }
}
}
+namespace Microsoft.Data.SqlClient.Diagnostics
+{
+ ///
+ public sealed class SqlClientCommandBefore : System.Collections.Generic.IReadOnlyList>
+ {
+ ///
+ public const string Name = "Microsoft.Data.SqlClient.WriteCommandBefore";
+ ///
+ public System.Guid OperationId => throw null;
+ ///
+ public string Operation => throw null;
+ ///
+ public long Timestamp => throw null;
+ ///
+ public System.Guid? ConnectionId => throw null;
+ ///
+ public long? TransactionId => throw null;
+ ///
+ public SqlCommand Command => throw null;
+ ///
+ public int Count => throw null;
+ ///
+ public System.Collections.Generic.KeyValuePair this[int index] => throw null;
+ ///
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
+ ///
+ public System.Collections.Generic.IEnumerator> GetEnumerator() => throw null;
+ }
+ ///
+ public sealed class SqlClientCommandAfter : System.Collections.Generic.IReadOnlyList>
+ {
+ ///
+ public const string Name = "Microsoft.Data.SqlClient.WriteCommandAfter";
+ ///
+ public System.Guid OperationId => throw null;
+ ///
+ public string Operation => throw null;
+ ///
+ public long Timestamp => throw null;
+ ///
+ public System.Guid? ConnectionId => throw null;
+ ///
+ public long? TransactionId => throw null;
+ ///
+ public SqlCommand Command => throw null;
+ ///
+ public System.Collections.IDictionary Statistics => throw null;
+ ///
+ public int Count => throw null;
+ ///
+ public System.Collections.Generic.KeyValuePair this[int index] => throw null;
+ ///
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
+ ///
+ public System.Collections.Generic.IEnumerator> GetEnumerator() => throw null;
+ }
+ ///
+ public sealed class SqlClientCommandError : System.Collections.Generic.IReadOnlyList>
+ {
+ ///
+ public const string Name = "Microsoft.Data.SqlClient.WriteCommandError";
+ ///
+ public System.Guid OperationId => throw null;
+ ///
+ public string Operation => throw null;
+ ///
+ public long Timestamp => throw null;
+ ///
+ public System.Guid? ConnectionId => throw null;
+ ///
+ public long? TransactionId => throw null;
+ ///
+ public SqlCommand Command => throw null;
+ ///
+ public System.Exception Exception { get; }
+ ///
+ public int Count => throw null;
+ /// >///
+ public System.Collections.Generic.KeyValuePair this[int index] => throw null;
+ ///
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
+ ///
+ public System.Collections.Generic.IEnumerator> GetEnumerator() => throw null;
+ }
+ ///
+ public sealed class SqlClientConnectionOpenBefore : System.Collections.Generic.IReadOnlyList>
+ {
+ ///
+ public const string Name = "Microsoft.Data.SqlClient.WriteConnectionOpenBefore";
+ ///
+ public System.Guid OperationId => throw null;
+ ///
+ public string Operation => throw null;
+ ///
+ public long Timestamp => throw null;
+ ///
+ public SqlConnection Connection => throw null;
+ ///
+ public string ClientVersion => throw null;
+ ///
+ public int Count => throw null;
+ /// >///
+ public System.Collections.Generic.KeyValuePair this[int index] => throw null;
+ ///
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
+ ///
+ public System.Collections.Generic.IEnumerator> GetEnumerator() => throw null;
+ }
+ ///
+ public sealed class SqlClientConnectionOpenAfter : System.Collections.Generic.IReadOnlyList>
+ {
+ ///
+ public const string Name = "Microsoft.Data.SqlClient.WriteConnectionOpenAfter";
+ ///
+ public System.Guid OperationId => throw null;
+ ///
+ public string Operation => throw null;
+ ///
+ public long Timestamp => throw null;
+ ///
+ public System.Guid ConnectionId => throw null;
+ ///
+ public SqlConnection Connection => throw null;
+ ///
+ public string ClientVersion => throw null;
+ ///
+ public System.Collections.IDictionary Statistics => throw null;
+ ///
+ public int Count => throw null;
+ /// >///
+ public System.Collections.Generic.KeyValuePair this[int index] => throw null;
+ ///
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
+ ///
+ public System.Collections.Generic.IEnumerator> GetEnumerator() => throw null;
+ }
+ ///
+ public sealed class SqlClientConnectionOpenError : System.Collections.Generic.IReadOnlyList>
+ {
+ ///
+ public const string Name = "Microsoft.Data.SqlClient.WriteConnectionOpenError";
+ ///
+ public System.Guid OperationId => throw null;
+ ///
+ public string Operation => throw null;
+ ///
+ public long Timestamp => throw null;
+ ///
+ public System.Guid ConnectionId => throw null;
+ ///
+ public SqlConnection Connection => throw null;
+ ///
+ public string ClientVersion => throw null;
+ ///
+ public System.Exception Exception => throw null;
+ ///
+ public int Count => throw null;
+ /// >///
+ public System.Collections.Generic.KeyValuePair this[int index] => throw null;
+ ///
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
+ ///
+ public System.Collections.Generic.IEnumerator> GetEnumerator() => throw null;
+ }
+ ///
+ public sealed class SqlClientConnectionCloseBefore : System.Collections.Generic.IReadOnlyList>
+ {
+ ///
+ public const string Name = "Microsoft.Data.SqlClient.WriteConnectionCloseBefore";
+ ///
+ public System.Guid OperationId => throw null;
+ ///
+ public string Operation => throw null;
+ ///
+ public long Timestamp => throw null;
+ ///
+ public System.Guid? ConnectionId => throw null;
+ ///
+ public SqlConnection Connection => throw null;
+ ///
+ public System.Collections.IDictionary Statistics => throw null;
+ ///
+ public int Count => throw null;
+ /// >///
+ public System.Collections.Generic.KeyValuePair this[int index] => throw null;
+ ///
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
+ ///
+ public System.Collections.Generic.IEnumerator> GetEnumerator() => throw null;
+ }
+ ///
+ public sealed class SqlClientConnectionCloseAfter : System.Collections.Generic.IReadOnlyList>
+ {
+ ///
+ public const string Name = "Microsoft.Data.SqlClient.WriteConnectionCloseAfter";
+ ///
+ public System.Guid OperationId => throw null;
+ ///
+ public string Operation => throw null;
+ ///
+ public long Timestamp => throw null;
+ ///
+ public System.Guid? ConnectionId => throw null;
+ ///
+ public SqlConnection Connection => throw null;
+ ///
+ public System.Collections.IDictionary Statistics => throw null;
+ ///
+ public int Count => throw null;
+ /// >///
+ public System.Collections.Generic.KeyValuePair this[int index] => throw null;
+ ///
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
+ ///
+ public System.Collections.Generic.IEnumerator> GetEnumerator() => throw null;
+ }
+ ///
+ public sealed class SqlClientConnectionCloseError : System.Collections.Generic.IReadOnlyList>
+ {
+ ///
+ public const string Name = "Microsoft.Data.SqlClient.WriteConnectionCloseError";
+ ///
+ public System.Guid OperationId => throw null;
+ ///
+ public string Operation => throw null;
+ ///
+ public long Timestamp => throw null;
+ ///
+ public System.Guid? ConnectionId => throw null;
+ ///
+ public SqlConnection Connection => throw null;
+ ///
+ public System.Collections.IDictionary Statistics => throw null;
+ ///
+ public System.Exception Exception => throw null;
+ ///
+ public int Count => throw null;
+ /// >///
+ public System.Collections.Generic.KeyValuePair this[int index] => throw null;
+ ///
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
+ ///
+ public System.Collections.Generic.IEnumerator> GetEnumerator() => throw null;
+ }
+ ///
+ public sealed class SqlClientTransactionCommitBefore : System.Collections.Generic.IReadOnlyList>
+ {
+ ///
+ public const string Name = "Microsoft.Data.SqlClient.WriteTransactionCommitBefore";
+ ///
+ public System.Guid OperationId => throw null;
+ ///
+ public string Operation => throw null;
+ ///
+ public long Timestamp => throw null;
+ ///
+ public System.Data.IsolationLevel IsolationLevel => throw null;
+ ///
+ public SqlConnection Connection => throw null;
+ ///
+ public long? TransactionId => throw null;
+ ///
+ public int Count => throw null;
+ /// >///
+ public System.Collections.Generic.KeyValuePair this[int index] => throw null;
+ ///
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
+ ///
+ public System.Collections.Generic.IEnumerator> GetEnumerator() => throw null;
+ }
+ ///
+ public sealed class SqlClientTransactionCommitAfter : System.Collections.Generic.IReadOnlyList>
+ {
+ ///
+ public const string Name = "Microsoft.Data.SqlClient.WriteTransactionCommitAfter";
+ ///
+ public System.Guid OperationId => throw null;
+ ///
+ public string Operation => throw null;
+ ///
+ public long Timestamp => throw null;
+ ///
+ public System.Data.IsolationLevel IsolationLevel => throw null;
+ ///
+ public SqlConnection Connection => throw null;
+ ///
+ public long? TransactionId => throw null;
+ ///
+ public int Count => throw null;
+ /// >///
+ public System.Collections.Generic.KeyValuePair this[int index] => throw null;
+ ///
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
+ ///
+ public System.Collections.Generic.IEnumerator> GetEnumerator() => throw null;
+ }
+ ///
+ public sealed class SqlClientTransactionCommitError : System.Collections.Generic.IReadOnlyList>
+ {
+ ///
+ public const string Name = "Microsoft.Data.SqlClient.WriteTransactionCommitError";
+ ///
+ public System.Guid OperationId => throw null;
+ ///
+ public string Operation => throw null;
+ ///
+ public long Timestamp => throw null;
+ ///
+ public System.Data.IsolationLevel IsolationLevel => throw null;
+ ///
+ public SqlConnection Connection => throw null;
+ ///
+ public long? TransactionId => throw null;
+ ///
+ public System.Exception Exception => throw null;
+ ///
+ public int Count => throw null;
+ /// >///
+ public System.Collections.Generic.KeyValuePair this[int index] => throw null;
+ ///
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
+ ///
+ public System.Collections.Generic.IEnumerator> GetEnumerator() => throw null;
+ }
+ ///
+ public sealed class SqlClientTransactionRollbackBefore : System.Collections.Generic.IReadOnlyList>
+ {
+ ///
+ public const string Name = "Microsoft.Data.SqlClient.WriteTransactionRollbackBefore";
+ ///
+ public System.Guid OperationId => throw null;
+ ///
+ public string Operation => throw null;
+ ///
+ public long Timestamp => throw null;
+ ///
+ public System.Data.IsolationLevel IsolationLevel => throw null;
+ ///
+ public SqlConnection Connection => throw null;
+ ///
+ public long? TransactionId => throw null;
+ ///
+ public string TransactionName => throw null;
+ ///
+ public int Count => throw null;
+ /// >///
+ public System.Collections.Generic.KeyValuePair this[int index] => throw null;
+ ///
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
+ ///
+ public System.Collections.Generic.IEnumerator> GetEnumerator() => throw null;
+ }
+ ///
+ public sealed class SqlClientTransactionRollbackAfter : System.Collections.Generic.IReadOnlyList>
+ {
+ ///
+ public const string Name = "Microsoft.Data.SqlClient.WriteTransactionRollbackAfter";
+ ///
+ public System.Guid OperationId => throw null;
+ ///
+ public string Operation => throw null;
+ ///
+ public long Timestamp => throw null;
+ ///
+ public System.Data.IsolationLevel IsolationLevel => throw null;
+ ///
+ public SqlConnection Connection => throw null;
+ ///
+ public long? TransactionId => throw null;
+ ///
+ public string TransactionName => throw null;
+ ///
+ public int Count => throw null;
+ /// >///
+ public System.Collections.Generic.KeyValuePair this[int index] => throw null;
+ ///
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
+ ///
+ public System.Collections.Generic.IEnumerator> GetEnumerator() => throw null;
+ }
+ ///
+ public sealed class SqlClientTransactionRollbackError : System.Collections.Generic.IReadOnlyList>
+ {
+ ///
+ public const string Name = "Microsoft.Data.SqlClient.WriteTransactionRollbackError";
+ ///
+ public System.Guid OperationId => throw null;
+ ///
+ public string Operation => throw null;
+ ///
+ public long Timestamp => throw null;
+ ///
+ public System.Data.IsolationLevel IsolationLevel => throw null;
+ ///
+ public SqlConnection Connection => throw null;
+ ///
+ public long? TransactionId => throw null;
+ ///
+ public string TransactionName => throw null;
+ ///
+ public System.Exception Exception => throw null;
+ ///
+ public int Count => throw null;
+ /// >///
+ public System.Collections.Generic.KeyValuePair this[int index] => throw null;
+ ///
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
+ ///
+ public System.Collections.Generic.IEnumerator> GetEnumerator() => throw null;
+ }
+}
namespace Microsoft.Data.SqlClient.Server
{
///
diff --git a/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.csproj
index 6b507b5a0a..c244a806bf 100644
--- a/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.csproj
@@ -43,6 +43,7 @@
+
diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj
index 0c2fe65f93..b2e40438d1 100644
--- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj
@@ -336,9 +336,63 @@
Microsoft\Data\SqlClient\ConnectionPool\WaitHandleDbConnectionPool.cs
+
+ Microsoft\Data\SqlClient\Diagnostics\DiagnosticScope.cs
+
+
+ Microsoft\Data\SqlClient\Diagnostics\DiagnosticTransactionScope.cs
+
+
+ Microsoft\Data\SqlClient\Diagnostics\SqlClientCommandAfter.cs
+
+
+ Microsoft\Data\SqlClient\Diagnostics\SqlClientCommandBefore.cs
+
+
+ Microsoft\Data\SqlClient\Diagnostics\SqlClientCommandError.cs
+
+
+ Microsoft\Data\SqlClient\Diagnostics\SqlClientConnectionCloseAfter.cs
+
+
+ Microsoft\Data\SqlClient\Diagnostics\SqlClientConnectionCloseBefore.cs
+
+
+ Microsoft\Data\SqlClient\Diagnostics\SqlClientConnectionCloseError.cs
+
+
+ Microsoft\Data\SqlClient\Diagnostics\SqlClientConnectionOpenAfter.cs
+
+
+ Microsoft\Data\SqlClient\Diagnostics\SqlClientConnectionOpenBefore.cs
+
+
+ Microsoft\Data\SqlClient\Diagnostics\SqlClientConnectionOpenError.cs
+
Microsoft\Data\SqlClient\Diagnostics\SqlClientMetrics.cs
+
+ Microsoft\Data\SqlClient\Diagnostics\SqlClientTransactionCommitAfter.cs
+
+
+ Microsoft\Data\SqlClient\Diagnostics\SqlClientTransactionCommitBefore.cs
+
+
+ Microsoft\Data\SqlClient\Diagnostics\SqlClientTransactionCommitError.cs
+
+
+ Microsoft\Data\SqlClient\Diagnostics\SqlClientTransactionRollbackAfter.cs
+
+
+ Microsoft\Data\SqlClient\Diagnostics\SqlClientTransactionRollbackBefore.cs
+
+
+ Microsoft\Data\SqlClient\Diagnostics\SqlClientTransactionRollbackError.cs
+
+
+ Microsoft\Data\SqlClient\Diagnostics\SqlDiagnosticListener.cs
+
Microsoft\Data\ProviderBase\DbMetaDataFactory.cs
@@ -961,6 +1015,7 @@
+
diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnection.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnection.cs
index 24cd7dbe28..7990cb041e 100644
--- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnection.cs
+++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnection.cs
@@ -25,6 +25,7 @@
using Microsoft.Data.Common.ConnectionString;
using Microsoft.Data.ProviderBase;
using Microsoft.Data.SqlClient.ConnectionPool;
+using Microsoft.Data.SqlClient.Diagnostics;
using Microsoft.SqlServer.Server;
[assembly: InternalsVisibleTo("System.Data.DataSetExtensions, PublicKey=" + Microsoft.Data.SqlClient.AssemblyRef.EcmaPublicKeyFull)] // DevDiv Bugs 92166
@@ -70,6 +71,9 @@ public sealed partial class SqlConnection : DbConnection, ICloneable
// Retry Logic
private SqlRetryLogicBaseProvider _retryLogicProvider;
+ // diagnostics listener
+ private static readonly SqlDiagnosticListener s_diagnosticListener = new();
+
// Transient Fault handling flag. This is needed to convey to the downstream mechanism of connection establishment, if Transient Fault handling should be used or not
// The downstream handling of Connection open is the same for idle connection resiliency. Currently we want to apply transient fault handling only to the connections opened
// using SqlConnection.Open() method.
@@ -113,6 +117,8 @@ private static readonly ConcurrentDictionary> _ColumnEncry
capacity: 1,
comparer: StringComparer.OrdinalIgnoreCase);
+ private static readonly Action, object> s_openAsyncComplete = OpenAsyncComplete;
+
private bool IsProviderRetriable => SqlConfigurableRetryFactory.IsRetriable(RetryLogicProvider);
///
@@ -1314,8 +1320,28 @@ public override void Close()
{
SqlClientEventSource.Log.TryCorrelationTraceEvent(" ObjectID {0}, ActivityID {1}", ObjectID, ActivityCorrelator.Current);
+ ConnectionState previousState = State;
+ Guid operationId = default(Guid);
+ Guid clientConnectionId = default(Guid);
+
+ // during the call to Dispose() there is a redundant call to
+ // Close(). because of this, the second time Close() is invoked the
+ // connection is already in a closed state. this doesn't seem to be a
+ // problem except for logging, as we'll get duplicate Before/After/Error
+ // log entries
+ if (previousState != ConnectionState.Closed)
+ {
+ operationId = s_diagnosticListener.WriteConnectionCloseBefore(this);
+ // we want to cache the ClientConnectionId for After/Error logging, as when the connection
+ // is closed then we will lose this identifier
+ //
+ // note: caching this is only for diagnostics logging purposes
+ clientConnectionId = ClientConnectionId;
+ }
+
SqlStatistics statistics = null;
TdsParser bestEffortCleanupTarget = null;
+ Exception e = null;
RuntimeHelpers.PrepareConstrainedRegions();
try
@@ -1348,20 +1374,28 @@ public override void Close()
}
catch (System.OutOfMemoryException ex)
{
+ e = ex;
Abort(ex);
throw;
}
catch (System.StackOverflowException ex)
{
+ e = ex;
Abort(ex);
throw;
}
catch (System.Threading.ThreadAbortException ex)
{
+ e = ex;
Abort(ex);
SqlInternalConnection.BestEffortCleanup(bestEffortCleanupTarget);
throw;
}
+ catch (Exception ex)
+ {
+ e = ex;
+ throw;
+ }
finally
{
SqlStatistics.StopTimer(statistics);
@@ -1370,6 +1404,20 @@ public override void Close()
{
_lastIdentity.Dispose();
}
+
+ // we only want to log this if the previous state of the
+ // connection is open, as that's the valid use-case
+ if (previousState != ConnectionState.Closed)
+ {
+ if (e != null)
+ {
+ s_diagnosticListener.WriteConnectionCloseError(operationId, clientConnectionId, this, e);
+ }
+ else
+ {
+ s_diagnosticListener.WriteConnectionCloseAfter(operationId, clientConnectionId, this);
+ }
+ }
}
}
}
@@ -1423,19 +1471,13 @@ public void Open(SqlConnectionOverrides overrides)
{
SqlClientEventSource.Log.TryCorrelationTraceEvent(" ObjectID {0}, ActivityID {1}", ObjectID, ActivityCorrelator.Current);
- if (StatisticsEnabled)
- {
- if (_statistics == null)
- {
- _statistics = new SqlStatistics();
- }
- else
- {
- _statistics.ContinueOnNewConnection();
- }
- }
+ Guid operationId = s_diagnosticListener.WriteConnectionOpenBefore(this);
+
+ PrepareStatisticsForNewConnection();
SqlStatistics statistics = null;
+ Exception e = null;
+
RuntimeHelpers.PrepareConstrainedRegions();
try
{
@@ -1446,9 +1488,23 @@ public void Open(SqlConnectionOverrides overrides)
throw ADP.InternalError(ADP.InternalErrorCode.SynchronousConnectReturnedPending);
}
}
+ catch (Exception ex)
+ {
+ e = ex;
+ throw;
+ }
finally
{
SqlStatistics.StopTimer(statistics);
+
+ if (e != null)
+ {
+ s_diagnosticListener.WriteConnectionOpenError(operationId, this, e);
+ }
+ else
+ {
+ s_diagnosticListener.WriteConnectionOpenAfter(operationId, this);
+ }
}
}
}
@@ -1696,17 +1752,9 @@ private Task InternalOpenAsync(SqlConnectionOverrides overrides, CancellationTok
try
{
- if (StatisticsEnabled)
- {
- if (_statistics == null)
- {
- _statistics = new SqlStatistics();
- }
- else
- {
- _statistics.ContinueOnNewConnection();
- }
- }
+ Guid operationId = s_diagnosticListener.WriteConnectionOpenBefore(this);
+
+ PrepareStatisticsForNewConnection();
SqlStatistics statistics = null;
RuntimeHelpers.PrepareConstrainedRegions();
@@ -1716,7 +1764,17 @@ private Task InternalOpenAsync(SqlConnectionOverrides overrides, CancellationTok
System.Transactions.Transaction transaction = ADP.GetCurrentTransaction();
TaskCompletionSource completion = new TaskCompletionSource(transaction);
- TaskCompletionSource
-
-
@@ -339,6 +337,7 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
all
+
@@ -365,9 +364,6 @@
%(Filename)%(Extension)
-
-
-
PreserveNewest
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/DiagnosticTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/DiagnosticTest.cs
index b8649d43d2..8ee8e28058 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/DiagnosticTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/DiagnosticTest.cs
@@ -21,7 +21,6 @@
namespace Microsoft.Data.SqlClient.ManualTesting.Tests
{
- [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework)]
public class DiagnosticTest
{
private const string BadConnectionString = "data source = bad; initial catalog = bad; integrated security = true; connection timeout = 1;";
@@ -241,8 +240,13 @@ public void ExecuteScalarAsyncTest()
{
CollectStatisticsDiagnosticsAsync(async connectionString =>
{
+#if NET
await using (SqlConnection conn = new SqlConnection(connectionString))
await using (SqlCommand cmd = new SqlCommand())
+#else
+ using (SqlConnection conn = new SqlConnection(connectionString))
+ using (SqlCommand cmd = new SqlCommand())
+#endif
{
cmd.Connection = conn;
cmd.CommandText = "SELECT [name], [state] FROM [sys].[databases] WHERE [name] = db_name();";
@@ -262,8 +266,13 @@ public void ExecuteScalarAsyncErrorTest()
{
CollectStatisticsDiagnosticsAsync(async connectionString =>
{
+#if NET
await using (SqlConnection conn = new SqlConnection(connectionString))
await using (SqlCommand cmd = new SqlCommand())
+#else
+ using (SqlConnection conn = new SqlConnection(connectionString))
+ using (SqlCommand cmd = new SqlCommand())
+#endif
{
cmd.Connection = conn;
cmd.CommandText = "SELECT 1 / 0;";
@@ -283,8 +292,13 @@ public void ExecuteNonQueryAsyncTest()
{
CollectStatisticsDiagnosticsAsync(async connectionString =>
{
+#if NET
await using (SqlConnection conn = new SqlConnection(connectionString))
await using (SqlCommand cmd = new SqlCommand())
+#else
+ using (SqlConnection conn = new SqlConnection(connectionString))
+ using (SqlCommand cmd = new SqlCommand())
+#endif
{
cmd.Connection = conn;
cmd.CommandText = "SELECT [name], [state] FROM [sys].[databases] WHERE [name] = db_name();";
@@ -304,8 +318,13 @@ public void ExecuteNonQueryAsyncErrorTest()
{
CollectStatisticsDiagnosticsAsync(async connectionString =>
{
+#if NET
await using (SqlConnection conn = new SqlConnection(connectionString))
await using (SqlCommand cmd = new SqlCommand())
+#else
+ using (SqlConnection conn = new SqlConnection(connectionString))
+ using (SqlCommand cmd = new SqlCommand())
+#endif
{
cmd.Connection = conn;
cmd.CommandText = "SELECT 1 / 0;";
@@ -325,8 +344,13 @@ public void ExecuteReaderAsyncTest()
{
CollectStatisticsDiagnosticsAsync(async connectionString =>
{
+#if NET
await using (SqlConnection conn = new SqlConnection(connectionString))
await using (SqlCommand cmd = new SqlCommand())
+#else
+ using (SqlConnection conn = new SqlConnection(connectionString))
+ using (SqlCommand cmd = new SqlCommand())
+#endif
{
cmd.Connection = conn;
cmd.CommandText = "SELECT [name], [state] FROM [sys].[databases] WHERE [name] = db_name();";
@@ -350,8 +374,13 @@ public void ExecuteReaderAsyncErrorTest()
{
CollectStatisticsDiagnosticsAsync(async connectionString =>
{
+#if NET
await using (SqlConnection conn = new SqlConnection(connectionString))
await using (SqlCommand cmd = new SqlCommand())
+#else
+ using (SqlConnection conn = new SqlConnection(connectionString))
+ using (SqlCommand cmd = new SqlCommand())
+#endif
{
cmd.Connection = conn;
cmd.CommandText = "SELECT 1 / 0;";
@@ -374,8 +403,13 @@ public void ExecuteXmlReaderAsyncTest()
{
CollectStatisticsDiagnosticsAsync(async _ =>
{
+#if NET
await using (SqlConnection conn = new SqlConnection(DataTestUtility.TCPConnectionString))
await using (SqlCommand cmd = new SqlCommand())
+#else
+ using (SqlConnection conn = new SqlConnection(DataTestUtility.TCPConnectionString))
+ using (SqlCommand cmd = new SqlCommand())
+#endif
{
cmd.Connection = conn;
cmd.CommandText = "SELECT TOP 10 * FROM sys.objects FOR xml auto, xmldata;";
@@ -401,8 +435,13 @@ public void ExecuteXmlReaderAsyncErrorTest()
CollectStatisticsDiagnosticsAsync(async _ =>
{
+#if NET
await using (SqlConnection conn = new SqlConnection(DataTestUtility.TCPConnectionString))
await using (SqlCommand cmd = new SqlCommand())
+#else
+ using (SqlConnection conn = new SqlConnection(DataTestUtility.TCPConnectionString))
+ using (SqlCommand cmd = new SqlCommand())
+#endif
{
cmd.Connection = conn;
cmd.CommandText = "select *, baddata = 1 / 0 from sys.objects for xml auto, xmldata;";
@@ -458,7 +497,11 @@ public void ConnectionOpenAsyncTest()
{
CollectStatisticsDiagnosticsAsync(async connectionString =>
{
+#if NET
await using (SqlConnection sqlConnection = new SqlConnection(connectionString))
+#else
+ using (SqlConnection sqlConnection = new SqlConnection(connectionString))
+#endif
{
await sqlConnection.OpenAsync();
}
@@ -474,7 +517,11 @@ public void ConnectionOpenAsyncErrorTest()
{
CollectStatisticsDiagnosticsAsync(async _ =>
{
+#if NET
await using (SqlConnection sqlConnection = new SqlConnection(BadConnectionString))
+#else
+ using (SqlConnection sqlConnection = new SqlConnection(BadConnectionString))
+#endif
{
await Assert.ThrowsAsync(() => sqlConnection.OpenAsync());
}
diff --git a/tools/specs/Microsoft.Data.SqlClient.nuspec b/tools/specs/Microsoft.Data.SqlClient.nuspec
index 0f029b4c19..4a602aceec 100644
--- a/tools/specs/Microsoft.Data.SqlClient.nuspec
+++ b/tools/specs/Microsoft.Data.SqlClient.nuspec
@@ -37,6 +37,7 @@
+