Skip to content

Commit

Permalink
Clone DbParameter when adding to command if ICloneable (#22485)
Browse files Browse the repository at this point in the history
Resolves #22483
  • Loading branch information
smitpatel committed Sep 11, 2020
1 parent 844587e commit 3eeb676
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Utilities;
Expand Down Expand Up @@ -62,6 +64,13 @@ public override void AddDbParameter(DbCommand command, IReadOnlyDictionary<strin
/// </summary>
public override void AddDbParameter(DbCommand command, object value)
{
if (value is DbParameter dbParameter
&& dbParameter.Direction == ParameterDirection.Input
&& value is ICloneable cloneable)
{
value = cloneable.Clone();
}

command.Parameters.Add(value);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -987,6 +987,24 @@ public virtual void Line_endings_after_Select()
Assert.NotNull(actual);
}

[ConditionalFact]
public virtual void FromSql_with_db_parameter_in_split_query()
{
using var context = CreateContext();

var actual = context.Set<Customer>()
.FromSqlRaw(NormalizeDelimitersInRawString("SELECT * FROM [Customers] WHERE [CustomerID] = {0}"),
CreateDbParameter("customerID", "ALFKI"))
.Include(e => e.Orders)
.ThenInclude(o => o.OrderDetails)
.AsSplitQuery()
.ToArray();

var customer = Assert.Single(actual);
Assert.Equal(6, customer.Orders.Count);
Assert.Equal(12, customer.Orders.SelectMany(e => e.OrderDetails).Count());
}

protected string NormalizeDelimitersInRawString(string sql)
=> Fixture.TestStore.NormalizeDelimitersInRawString(sql);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,39 @@ public override void Line_endings_after_Select()
WHERE [c].[City] = N'Seattle'");
}

public override void FromSql_with_db_parameter_in_split_query()
{
base.FromSql_with_db_parameter_in_split_query();

AssertSql(
@"customerID='ALFKI' (Nullable = false) (Size = 5)
SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region]
FROM (
SELECT * FROM ""Customers"" WHERE ""CustomerID"" = @customerID
) AS [c]
ORDER BY [c].[CustomerID]",
//
@"customerID='ALFKI' (Nullable = false) (Size = 5)
SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate], [c].[CustomerID]
FROM (
SELECT * FROM ""Customers"" WHERE ""CustomerID"" = @customerID
) AS [c]
INNER JOIN [Orders] AS [o] ON [c].[CustomerID] = [o].[CustomerID]
ORDER BY [c].[CustomerID], [o].[OrderID]",
//
@"customerID='ALFKI' (Nullable = false) (Size = 5)
SELECT [o0].[OrderID], [o0].[ProductID], [o0].[Discount], [o0].[Quantity], [o0].[UnitPrice], [c].[CustomerID], [o].[OrderID]
FROM (
SELECT * FROM ""Customers"" WHERE ""CustomerID"" = @customerID
) AS [c]
INNER JOIN [Orders] AS [o] ON [c].[CustomerID] = [o].[CustomerID]
INNER JOIN [Order Details] AS [o0] ON [o].[OrderID] = [o0].[OrderID]
ORDER BY [c].[CustomerID], [o].[OrderID]");
}

protected override DbParameter CreateDbParameter(string name, object value)
=> new SqlParameter { ParameterName = name, Value = value };

Expand Down

0 comments on commit 3eeb676

Please sign in to comment.