Skip to content
This repository was archived by the owner on Aug 8, 2024. It is now read-only.

Commit 6e65509

Browse files
authored
Backport SqlCommand Fix
Backport of dotnet#29614 (#368) Fixes mono/mono#14450
1 parent 49f1c45 commit 6e65509

File tree

4 files changed

+120
-2
lines changed

4 files changed

+120
-2
lines changed

src/System.Data.SqlClient/src/System/Data/SqlClient/SqlCommand.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,7 +1145,7 @@ private Task InternalExecuteNonQuery(TaskCompletionSource<object> completion, bo
11451145
Task task = null;
11461146

11471147
// only send over SQL Batch command if we are not a stored proc and have no parameters and not in batch RPC mode
1148-
if ((System.Data.CommandType.Text == this.CommandType) && (0 == GetParameterCount(_parameters)))
1148+
if (!BatchRPCMode && (System.Data.CommandType.Text == this.CommandType) && (0 == GetParameterCount(_parameters)))
11491149
{
11501150
Debug.Assert(!sendToPipe, "trying to send non-context command to pipe");
11511151
if (null != statistics)
@@ -2534,7 +2534,15 @@ private SqlDataReader RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavi
25342534
GetStateObject();
25352535
Task writeTask = null;
25362536

2537-
if ((System.Data.CommandType.Text == this.CommandType) && (0 == GetParameterCount(_parameters)))
2537+
if (BatchRPCMode)
2538+
{
2539+
Debug.Assert(inSchema == false, "Batch RPC does not support schema only command beahvior");
2540+
Debug.Assert(!IsPrepared, "Batch RPC should not be prepared!");
2541+
Debug.Assert(!IsDirty, "Batch RPC should not be marked as dirty!");
2542+
Debug.Assert(_SqlRPCBatchArray != null, "RunExecuteReader rpc array not provided");
2543+
writeTask = _stateObj.Parser.TdsExecuteRPC( _SqlRPCBatchArray, timeout, inSchema, this.Notification, _stateObj, CommandType.StoredProcedure == CommandType, sync: !asyncWrite);
2544+
}
2545+
else if ((System.Data.CommandType.Text == this.CommandType) && (0 == GetParameterCount(_parameters)))
25382546
{
25392547
// Send over SQL Batch command if we are not a stored proc and have no parameters
25402548
Debug.Assert(!IsUserPrepared, "CommandType.Text with no params should not be prepared!");

src/System.Data.SqlClient/src/System/Data/SqlClient/SqlParameterHelper.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,8 @@ internal void CopyTo(SqlParameter destination)
231231
destination._sourceVersion = _sourceVersion;
232232
destination._sourceColumnNullMapping = _sourceColumnNullMapping;
233233
destination._isNullable = _isNullable;
234+
destination._parameterName = _parameterName;
235+
destination._isNull = _isNull;
234236
}
235237
}
236238
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System.Collections.Generic;
6+
using Xunit;
7+
8+
namespace System.Data.SqlClient.ManualTesting.Tests
9+
{
10+
public class SqlAdapterUpdateBatch
11+
{
12+
[CheckConnStrSetupFact]
13+
public void SqlAdapterTest()
14+
{
15+
string tableName = "BatchDemoTable";
16+
try
17+
{
18+
var createTableQuery = "IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='BatchDemoTable' AND xtype='U')" +
19+
" CREATE TABLE [dbo].[" + tableName + "]([TransactionNumber][int] IDENTITY(1, 1) NOT NULL,[Level] [nvarchar] (50) NOT NULL," +
20+
"[Message] [nvarchar] (500) NOT NULL,[EventTime] [datetime]NOT NULL,CONSTRAINT[PK_BatchDemoTable] " +
21+
"PRIMARY KEY CLUSTERED([TransactionNumber] ASC)WITH(PAD_INDEX = OFF,STATISTICS_NORECOMPUTE = OFF, " +
22+
"IGNORE_DUP_KEY = OFF,ALLOW_ROW_LOCKS = ON,ALLOW_PAGE_LOCKS = ON,FILLFACTOR = 90) ON[PRIMARY]) ON[PRIMARY]";
23+
24+
using (var connection = new SqlConnection(DataTestUtility.TcpConnStr))
25+
using (var cmd = new SqlCommand(createTableQuery, connection))
26+
{
27+
connection.Open();
28+
cmd.ExecuteNonQuery();
29+
}
30+
ExecuteNonQueries();
31+
}
32+
catch (Exception ex)
33+
{
34+
Console.WriteLine(ex.Message);
35+
Console.WriteLine(ex.StackTrace);
36+
}
37+
finally
38+
{
39+
var dropTableQuery = "DROP TABLE IF EXISTS " + tableName;
40+
using (var connection = new SqlConnection(DataTestUtility.TcpConnStr))
41+
using (var cmd = new SqlCommand(dropTableQuery, connection))
42+
{
43+
connection.Open();
44+
cmd.ExecuteNonQuery();
45+
}
46+
}
47+
}
48+
49+
50+
public class EventInfo
51+
{
52+
public string Level { get; set; }
53+
public string Message { get; set; }
54+
public DateTime EventTime { get; set; }
55+
56+
public EventInfo()
57+
{
58+
EventTime = DateTime.Now;
59+
}
60+
}
61+
62+
public static void ExecuteNonQueries()
63+
{
64+
List<EventInfo> entities = new List<EventInfo>
65+
{
66+
new EventInfo {Level = "L1", Message = "Message 1"},
67+
new EventInfo {Level = "L2", Message = "Message 2"},
68+
new EventInfo {Level = "L3", Message = "Message 3"},
69+
new EventInfo {Level = "L4", Message = "Message 4"},
70+
};
71+
72+
var sql = "INSERT INTO BatchDemoTable(Level, Message, EventTime) VALUES(@Level, @Message, @EventTime)";
73+
using (var connection = new SqlConnection(DataTestUtility.TcpConnStr))
74+
using (var adapter = new SqlDataAdapter())
75+
using (var cmd = new SqlCommand(sql, connection))
76+
{
77+
cmd.Parameters.Add(new SqlParameter("@Level", System.Data.SqlDbType.NVarChar, 50, "Level"));
78+
cmd.Parameters.Add(new SqlParameter("@Message", SqlDbType.NVarChar, 500, "Message"));
79+
cmd.Parameters.Add(new SqlParameter("@EventTime", SqlDbType.DateTime, 0, "EventTime"));
80+
cmd.UpdatedRowSource = UpdateRowSource.None;
81+
82+
adapter.InsertCommand = cmd;
83+
adapter.UpdateBatchSize = 2;
84+
85+
adapter.Update(ConvertToTable(entities));
86+
}
87+
}
88+
private static DataTable ConvertToTable(List<EventInfo> entities)
89+
{
90+
var table = new DataTable(typeof(EventInfo).Name);
91+
92+
table.Columns.Add("Level", typeof(string));
93+
table.Columns.Add("Message", typeof(string));
94+
table.Columns.Add("EventTime", typeof(DateTime));
95+
96+
foreach (var entity in entities)
97+
{
98+
var row = table.NewRow();
99+
row["Level"] = entity.Level;
100+
row["Message"] = entity.Message;
101+
row["EventTime"] = entity.EventTime;
102+
table.Rows.Add(row);
103+
}
104+
return table;
105+
}
106+
}
107+
}

src/System.Data.SqlClient/tests/ManualTests/System.Data.SqlClient.ManualTesting.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
<Compile Include="SQL\ParameterTest\DateTimeVariantTest.cs" />
3434
<Compile Include="SQL\ParameterTest\OutputParameter.cs" />
3535
<Compile Include="SQL\ParameterTest\ParametersTest.cs" />
36+
<Compile Include="SQL\ParameterTest\SqlAdapterUpdateBatch.cs" />
3637
<Compile Include="SQL\ParameterTest\SqlVariantParam.cs" />
3738
<Compile Include="SQL\ParameterTest\SteAttribute.cs" />
3839
<Compile Include="SQL\ParameterTest\SteParam.cs" />

0 commit comments

Comments
 (0)