diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs index 0ff4877afd..86cc1fd328 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -2792,6 +2792,11 @@ private bool TryProcessDone(SqlCommand cmd, SqlDataReader reader, ref RunBehavio cmd.InternalRecordsAffected = count; } } + // Skip the bogus DONE counts sent by the server + if (stateObj._receivedColMetaData || (curCmd != TdsEnums.SELECT)) + { + cmd.OnStatementCompleted(count); + } } stateObj._receivedColMetaData = false; diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj index 2e1f03fef6..b3b0d846a6 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj @@ -76,8 +76,9 @@ - - + + + diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/CommandCancelTest/CommandCancelTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlCommand/SqlCommandCancelTest.cs similarity index 99% rename from src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/CommandCancelTest/CommandCancelTest.cs rename to src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlCommand/SqlCommandCancelTest.cs index e6a43c2833..7d8c233904 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/CommandCancelTest/CommandCancelTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlCommand/SqlCommandCancelTest.cs @@ -10,7 +10,7 @@ namespace Microsoft.Data.SqlClient.ManualTesting.Tests { - public static class CommandCancelTest + public static class SqlCommandCancelTest { // Shrink the packet size - this should make timeouts more likely private static readonly string s_connStr = (new SqlConnectionStringBuilder(DataTestUtility.TcpConnStr) { PacketSize = 512 }).ConnectionString; @@ -139,7 +139,7 @@ private static void MultiThreadedCancel(string constr, bool async) Task.WaitAll(tasks, 15 * 1000); - CommandCancelTest.VerifyConnection(command); + SqlCommandCancelTest.VerifyConnection(command); } } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlCommand/SqlCommandCompletedTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlCommand/SqlCommandCompletedTest.cs new file mode 100644 index 0000000000..d8deedf683 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlCommand/SqlCommandCompletedTest.cs @@ -0,0 +1,55 @@ +using System.Data; +using Xunit; + +namespace Microsoft.Data.SqlClient.ManualTesting.Tests +{ + public static class SqlCommandCompletedTest + { + private static readonly string s_connStr = (new SqlConnectionStringBuilder(DataTestUtility.TcpConnStr) { PacketSize = 512 }).ConnectionString; + private static int completedHandlerExecuted = 0; + + [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] + public static void VerifyStatmentCompletedCalled() + { + string tableName = DataTestUtility.GetUniqueNameForSqlServer("stmt"); + + using (var conn = new SqlConnection(s_connStr)) + using (var cmd = conn.CreateCommand()) + { + try + { + cmd.StatementCompleted += StatementCompletedHandler; + conn.Open(); + + cmd.CommandText = $"CREATE TABLE {tableName} (c1 int)"; + var res = cmd.ExecuteScalar(); + + cmd.CommandText = $"INSERT {tableName} VALUES(1)"; //DML (+1) + res = cmd.ExecuteScalar(); + + cmd.CommandText = $"Update {tableName} set c1=2"; //DML (+1) + res = cmd.ExecuteScalar(); + + cmd.CommandText = $"SELECT * from {tableName}"; //DQL (+1) + res = cmd.ExecuteScalar(); + + cmd.CommandText = $"DELETE FROM {tableName}"; //DML (+1) + res = cmd.ExecuteScalar(); + } + finally + { + cmd.CommandText = $"DROP TABLE {tableName}"; + var res = cmd.ExecuteScalar(); + } + } + // DDL and DQL queries that return DoneRowCount are accounted here. + Assert.True(completedHandlerExecuted == 4); + } + + private static void StatementCompletedHandler(object sender, StatementCompletedEventArgs args) + { + // Increment on event pass through + completedHandlerExecuted++; + } + } +}