diff --git a/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs b/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs
index f118c68a2b8..e26f46931dc 100644
--- a/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs
+++ b/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs
@@ -1152,7 +1152,7 @@ static Expression PruneOwnedIncludes(IncludeExpression includeExpression)
///
/// The lambda expression containing
///
+ /// cref="SetPropertyCalls{TSource}.SetProperty{TProperty}(Func{TSource, TProperty}, Func{TSource, TProperty})" />
/// statements.
///
/// The non query after translation.
@@ -1160,7 +1160,7 @@ static Expression PruneOwnedIncludes(IncludeExpression includeExpression)
ShapedQueryExpression source,
LambdaExpression setPropertyCalls)
{
- var propertyValueLambdaExpressions = new List<(LambdaExpression, LambdaExpression)>();
+ var propertyValueLambdaExpressions = new List<(LambdaExpression, Expression)>();
PopulateSetPropertyCalls(setPropertyCalls.Body, propertyValueLambdaExpressions, setPropertyCalls.Parameters[0]);
if (TranslationErrorDetails != null)
{
@@ -1174,7 +1174,7 @@ static Expression PruneOwnedIncludes(IncludeExpression includeExpression)
}
EntityShaperExpression? entityShaperExpression = null;
- var remappedUnwrappeLeftExpressions = new List();
+ var remappedUnwrappedLeftExpressions = new List();
foreach (var (propertyExpression, _) in propertyValueLambdaExpressions)
{
var left = RemapLambdaBody(source, propertyExpression);
@@ -1197,7 +1197,7 @@ static Expression PruneOwnedIncludes(IncludeExpression includeExpression)
return null;
}
- remappedUnwrappeLeftExpressions.Add(left);
+ remappedUnwrappedLeftExpressions.Add(left);
}
Check.DebugAssert(entityShaperExpression != null, "EntityShaperExpression should have a value.");
@@ -1233,7 +1233,7 @@ static Expression PruneOwnedIncludes(IncludeExpression includeExpression)
{
return TranslateSetPropertyExpressions(
this, source, selectExpression, tableExpression,
- propertyValueLambdaExpressions, remappedUnwrappeLeftExpressions);
+ propertyValueLambdaExpressions, remappedUnwrappedLeftExpressions);
}
// We need to convert to join with original query using PK
@@ -1279,9 +1279,13 @@ static Expression PruneOwnedIncludes(IncludeExpression includeExpression)
entitySource),
propertyReplacement, propertyExpression.Body),
transparentIdentifierParameter);
- valueExpression = Expression.Lambda(
- ReplacingExpressionVisitor.Replace(valueExpression.Parameters[0], valueReplacement, valueExpression.Body),
- transparentIdentifierParameter);
+
+ valueExpression = valueExpression is LambdaExpression lambdaExpression
+ ? Expression.Lambda(
+ ReplacingExpressionVisitor.Replace(lambdaExpression.Parameters[0], valueReplacement, lambdaExpression.Body),
+ transparentIdentifierParameter)
+ : valueExpression;
+
propertyValueLambdaExpressions[i] = (propertyExpression, valueExpression);
}
@@ -1294,7 +1298,7 @@ static Expression PruneOwnedIncludes(IncludeExpression includeExpression)
ShapedQueryExpression source,
SelectExpression selectExpression,
TableExpression tableExpression,
- List<(LambdaExpression, LambdaExpression)> propertyValueLambdaExpressions,
+ List<(LambdaExpression, Expression)> propertyValueLambdaExpressions,
List? leftExpressions)
{
var columnValueSetters = new List();
@@ -1312,7 +1316,10 @@ static Expression PruneOwnedIncludes(IncludeExpression includeExpression)
left = left.UnwrapTypeConversion(out _);
}
- var right = visitor.RemapLambdaBody(source, valueExpression);
+ var right = valueExpression is LambdaExpression lambdaExpression
+ ? visitor.RemapLambdaBody(source, lambdaExpression)
+ : valueExpression;
+
if (right.Type != left.Type)
{
right = Expression.Convert(right, left.Type);
@@ -1348,7 +1355,7 @@ static Expression PruneOwnedIncludes(IncludeExpression includeExpression)
void PopulateSetPropertyCalls(
Expression expression,
- List<(LambdaExpression, LambdaExpression)> list,
+ List<(LambdaExpression, Expression)> list,
ParameterExpression parameter)
{
switch (expression)
@@ -1363,9 +1370,8 @@ when methodCallExpression.Method.IsGenericMethod
&& methodCallExpression.Method.DeclaringType!.IsGenericType
&& methodCallExpression.Method.DeclaringType.GetGenericTypeDefinition() == typeof(SetPropertyCalls<>):
- list.Add(
- (methodCallExpression.Arguments[0].UnwrapLambdaFromQuote(),
- methodCallExpression.Arguments[1].UnwrapLambdaFromQuote()));
+ list.Add(((LambdaExpression)methodCallExpression.Arguments[0], methodCallExpression.Arguments[1]));
+
PopulateSetPropertyCalls(methodCallExpression.Object!, list, parameter);
break;
diff --git a/src/EFCore.Relational/Query/SetPropertyCalls.cs b/src/EFCore.Relational/Query/SetPropertyCalls.cs
index cbd60a922ef..6508452059c 100644
--- a/src/EFCore.Relational/Query/SetPropertyCalls.cs
+++ b/src/EFCore.Relational/Query/SetPropertyCalls.cs
@@ -34,11 +34,27 @@ private SetPropertyCalls()
/// A value expression.
///
/// The same instance so that multiple calls to
- /// can be chained.
+ ///
+ /// can be chained.
///
public SetPropertyCalls SetProperty(
- Expression> propertyExpression,
- Expression> valueExpression)
+ Func propertyExpression,
+ Func valueExpression)
+ => throw new InvalidOperationException(RelationalStrings.SetPropertyMethodInvoked);
+
+ ///
+ /// Specifies a property and corresponding value it should be updated to in ExecuteUpdate method.
+ ///
+ /// The type of property.
+ /// A property access expression.
+ /// A value expression.
+ ///
+ /// The same instance so that multiple calls to
+ /// can be chained.
+ ///
+ public SetPropertyCalls SetProperty(
+ Func propertyExpression,
+ TProperty valueExpression)
=> throw new InvalidOperationException(RelationalStrings.SetPropertyMethodInvoked);
#region Hidden System.Object members
diff --git a/test/EFCore.Relational.Specification.Tests/BulkUpdates/FiltersInheritanceBulkUpdatesTestBase.cs b/test/EFCore.Relational.Specification.Tests/BulkUpdates/FiltersInheritanceBulkUpdatesTestBase.cs
index 0752cec0e17..686fb24805d 100644
--- a/test/EFCore.Relational.Specification.Tests/BulkUpdates/FiltersInheritanceBulkUpdatesTestBase.cs
+++ b/test/EFCore.Relational.Specification.Tests/BulkUpdates/FiltersInheritanceBulkUpdatesTestBase.cs
@@ -102,7 +102,7 @@ public virtual Task Update_where_hierarchy(bool async)
async,
ss => ss.Set().Where(e => e.Name == "Great spotted kiwi"),
e => e,
- s => s.SetProperty(e => e.Name, e => "Animal"),
+ s => s.SetProperty(e => e.Name, "Animal"),
rowsAffectedCount: 1,
(b, a) => a.ForEach(e => Assert.Equal("Animal", e.Name)));
@@ -113,7 +113,7 @@ public virtual Task Update_where_hierarchy_subquery(bool async)
async,
ss => ss.Set().Where(e => e.Name == "Great spotted kiwi").OrderBy(e => e.Name).Skip(0).Take(3),
e => e,
- s => s.SetProperty(e => e.Name, e => "Animal"),
+ s => s.SetProperty(e => e.Name, "Animal"),
rowsAffectedCount: 1);
[ConditionalTheory]
@@ -123,7 +123,7 @@ public virtual Task Update_where_hierarchy_derived(bool async)
async,
ss => ss.Set().Where(e => e.Name == "Great spotted kiwi"),
e => e,
- s => s.SetProperty(e => e.Name, e => "Kiwi"),
+ s => s.SetProperty(e => e.Name, "Kiwi"),
rowsAffectedCount: 1);
[ConditionalTheory]
@@ -133,7 +133,7 @@ public virtual Task Update_where_using_hierarchy(bool async)
async,
ss => ss.Set().Where(e => e.Animals.Where(a => a.CountryId > 0).Count() > 0),
e => e,
- s => s.SetProperty(e => e.Name, e => "Monovia"),
+ s => s.SetProperty(e => e.Name, "Monovia"),
rowsAffectedCount: 1);
[ConditionalTheory]
@@ -143,7 +143,7 @@ public virtual Task Update_where_using_hierarchy_derived(bool async)
async,
ss => ss.Set().Where(e => e.Animals.OfType().Where(a => a.CountryId > 0).Count() > 0),
e => e,
- s => s.SetProperty(e => e.Name, e => "Monovia"),
+ s => s.SetProperty(e => e.Name, "Monovia"),
rowsAffectedCount: 1);
[ConditionalTheory]
@@ -155,7 +155,7 @@ public virtual Task Update_where_keyless_entity_mapped_to_sql_query(bool async)
async,
ss => ss.Set().Where(e => e.CountryId > 0),
e => e,
- s => s.SetProperty(e => e.Name, e => "Eagle"),
+ s => s.SetProperty(e => e.Name, "Eagle"),
rowsAffectedCount: 1));
protected abstract void ClearLog();
diff --git a/test/EFCore.Relational.Specification.Tests/BulkUpdates/InheritanceBulkUpdatesTestBase.cs b/test/EFCore.Relational.Specification.Tests/BulkUpdates/InheritanceBulkUpdatesTestBase.cs
index f7beaa7aeed..08b871a55d8 100644
--- a/test/EFCore.Relational.Specification.Tests/BulkUpdates/InheritanceBulkUpdatesTestBase.cs
+++ b/test/EFCore.Relational.Specification.Tests/BulkUpdates/InheritanceBulkUpdatesTestBase.cs
@@ -102,7 +102,7 @@ public virtual Task Update_where_hierarchy(bool async)
async,
ss => ss.Set().Where(e => e.Name == "Great spotted kiwi"),
e => e,
- s => s.SetProperty(e => e.Name, e => "Animal"),
+ s => s.SetProperty(e => e.Name, "Animal"),
rowsAffectedCount: 1,
(b, a) => a.ForEach(e => Assert.Equal("Animal", e.Name)));
@@ -113,7 +113,7 @@ public virtual Task Update_where_hierarchy_subquery(bool async)
async,
ss => ss.Set().Where(e => e.Name == "Great spotted kiwi").OrderBy(e => e.Name).Skip(0).Take(3),
e => e,
- s => s.SetProperty(e => e.Name, e => "Animal"),
+ s => s.SetProperty(e => e.Name, "Animal"),
rowsAffectedCount: 1);
[ConditionalTheory]
@@ -123,7 +123,7 @@ public virtual Task Update_where_hierarchy_derived(bool async)
async,
ss => ss.Set().Where(e => e.Name == "Great spotted kiwi"),
e => e,
- s => s.SetProperty(e => e.Name, e => "Kiwi"),
+ s => s.SetProperty(e => e.Name, "Kiwi"),
rowsAffectedCount: 1);
[ConditionalTheory]
@@ -133,7 +133,7 @@ public virtual Task Update_where_using_hierarchy(bool async)
async,
ss => ss.Set().Where(e => e.Animals.Where(a => a.CountryId > 0).Count() > 0),
e => e,
- s => s.SetProperty(e => e.Name, e => "Monovia"),
+ s => s.SetProperty(e => e.Name, "Monovia"),
rowsAffectedCount: 2);
[ConditionalTheory]
@@ -143,7 +143,7 @@ public virtual Task Update_where_using_hierarchy_derived(bool async)
async,
ss => ss.Set().Where(e => e.Animals.OfType().Where(a => a.CountryId > 0).Count() > 0),
e => e,
- s => s.SetProperty(e => e.Name, e => "Monovia"),
+ s => s.SetProperty(e => e.Name, "Monovia"),
rowsAffectedCount: 1);
[ConditionalTheory]
@@ -155,7 +155,7 @@ public virtual Task Update_where_keyless_entity_mapped_to_sql_query(bool async)
async,
ss => ss.Set().Where(e => e.CountryId > 0),
e => e,
- s => s.SetProperty(e => e.Name, e => "Eagle"),
+ s => s.SetProperty(e => e.Name, "Eagle"),
rowsAffectedCount: 1));
protected abstract void ClearLog();
diff --git a/test/EFCore.Relational.Specification.Tests/BulkUpdates/NorthwindBulkUpdatesTestBase.cs b/test/EFCore.Relational.Specification.Tests/BulkUpdates/NorthwindBulkUpdatesTestBase.cs
index 1d5f6adbdb2..ff708de6c77 100644
--- a/test/EFCore.Relational.Specification.Tests/BulkUpdates/NorthwindBulkUpdatesTestBase.cs
+++ b/test/EFCore.Relational.Specification.Tests/BulkUpdates/NorthwindBulkUpdatesTestBase.cs
@@ -371,7 +371,7 @@ public virtual Task Update_Where_set_constant_TagWith(bool async)
async,
ss => ss.Set().Where(c => c.CustomerID.StartsWith("F")).TagWith("MyUpdate"),
e => e,
- s => s.SetProperty(c => c.ContactName, c => "Updated"),
+ s => s.SetProperty(c => c.ContactName, "Updated"),
rowsAffectedCount: 8,
(b, a) => Assert.All(a, c => Assert.Equal("Updated", c.ContactName)));
@@ -382,7 +382,7 @@ public virtual Task Update_Where_set_constant(bool async)
async,
ss => ss.Set().Where(c => c.CustomerID.StartsWith("F")),
e => e,
- s => s.SetProperty(c => c.ContactName, c => "Updated"),
+ s => s.SetProperty(c => c.ContactName, "Updated"),
rowsAffectedCount: 8,
(b, a) => Assert.All(a, c => Assert.Equal("Updated", c.ContactName)));
@@ -395,7 +395,7 @@ await AssertUpdate(
async,
ss => ss.Set().Where(c => c.CustomerID == customer),
e => e,
- s => s.SetProperty(c => c.ContactName, c => "Updated"),
+ s => s.SetProperty(c => c.ContactName, "Updated"),
rowsAffectedCount: 1,
(b, a) => Assert.All(a, c => Assert.Equal("Updated", c.ContactName)));
@@ -404,7 +404,7 @@ await AssertUpdate(
async,
ss => ss.Set().Where(c => c.CustomerID == customer),
e => e,
- s => s.SetProperty(c => c.ContactName, c => "Updated"),
+ s => s.SetProperty(c => c.ContactName, "Updated"),
rowsAffectedCount: 0,
(b, a) => Assert.All(a, c => Assert.Equal("Updated", c.ContactName)));
}
@@ -418,11 +418,61 @@ public virtual Task Update_Where_set_parameter(bool async)
async,
ss => ss.Set().Where(c => c.CustomerID.StartsWith("F")),
e => e,
- s => s.SetProperty(c => c.ContactName, c => value),
+ s => s.SetProperty(c => c.ContactName, value),
rowsAffectedCount: 8,
(b, a) => Assert.All(a, c => Assert.Equal("Abc", c.ContactName)));
}
+ [ConditionalTheory]
+ [MemberData(nameof(IsAsyncData))]
+ public virtual Task Update_Where_set_parameter_from_closure_array(bool async)
+ {
+ var array = new[] { "Abc", "Def" };
+ return AssertUpdate(
+ async,
+ ss => ss.Set().Where(c => c.CustomerID.StartsWith("F")),
+ e => e,
+ s => s.SetProperty(c => c.ContactName, array[0]),
+ rowsAffectedCount: 8,
+ (b, a) => Assert.All(a, c => Assert.Equal("Abc", c.ContactName)));
+ }
+
+ [ConditionalTheory]
+ [MemberData(nameof(IsAsyncData))]
+ public virtual Task Update_Where_set_parameter_from_inline_list(bool async)
+ => AssertUpdate(
+ async,
+ ss => ss.Set().Where(c => c.CustomerID.StartsWith("F")),
+ e => e,
+ s => s.SetProperty(c => c.ContactName, new List { "Abc", "Def" }[0]),
+ rowsAffectedCount: 8,
+ (b, a) => Assert.All(a, c => Assert.Equal("Abc", c.ContactName)));
+
+ [ConditionalTheory]
+ [MemberData(nameof(IsAsyncData))]
+ public virtual Task Update_Where_set_parameter_from_multilevel_property_access(bool async)
+ {
+ var container = new Container { Containee = new() { Property = "Abc" } };
+
+ return AssertUpdate(
+ async,
+ ss => ss.Set().Where(c => c.CustomerID.StartsWith("F")),
+ e => e,
+ s => s.SetProperty(c => c.ContactName, container.Containee.Property),
+ rowsAffectedCount: 8,
+ (b, a) => Assert.All(a, c => Assert.Equal("Abc", c.ContactName)));
+ }
+
+ class Container
+ {
+ public Containee Containee { get; set; }
+ }
+
+ class Containee
+ {
+ public string Property { get; set; }
+ }
+
[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Update_Where_Skip_set_constant(bool async)
@@ -430,7 +480,7 @@ public virtual Task Update_Where_Skip_set_constant(bool async)
async,
ss => ss.Set().Where(c => c.CustomerID.StartsWith("F")).Skip(4),
e => e,
- s => s.SetProperty(c => c.ContactName, c => "Updated"),
+ s => s.SetProperty(c => c.ContactName, "Updated"),
rowsAffectedCount: 4,
(b, a) => Assert.All(a, c => Assert.Equal("Updated", c.ContactName)));
@@ -441,7 +491,7 @@ public virtual Task Update_Where_Take_set_constant(bool async)
async,
ss => ss.Set().Where(c => c.CustomerID.StartsWith("F")).Take(4),
e => e,
- s => s.SetProperty(c => c.ContactName, c => "Updated"),
+ s => s.SetProperty(c => c.ContactName, "Updated"),
rowsAffectedCount: 4,
(b, a) => Assert.All(a, c => Assert.Equal("Updated", c.ContactName)));
@@ -452,7 +502,7 @@ public virtual Task Update_Where_Skip_Take_set_constant(bool async)
async,
ss => ss.Set().Where(c => c.CustomerID.StartsWith("F")).Skip(2).Take(4),
e => e,
- s => s.SetProperty(c => c.ContactName, c => "Updated"),
+ s => s.SetProperty(c => c.ContactName, "Updated"),
rowsAffectedCount: 4,
(b, a) => Assert.All(a, c => Assert.Equal("Updated", c.ContactName)));
@@ -463,7 +513,7 @@ public virtual Task Update_Where_OrderBy_set_constant(bool async)
async,
ss => ss.Set().Where(c => c.CustomerID.StartsWith("F")).OrderBy(c => c.City),
e => e,
- s => s.SetProperty(c => c.ContactName, c => "Updated"),
+ s => s.SetProperty(c => c.ContactName, "Updated"),
rowsAffectedCount: 8,
(b, a) => Assert.All(a, c => Assert.Equal("Updated", c.ContactName)));
@@ -474,7 +524,7 @@ public virtual Task Update_Where_OrderBy_Skip_set_constant(bool async)
async,
ss => ss.Set().Where(c => c.CustomerID.StartsWith("F")).OrderBy(c => c.City).Skip(4),
e => e,
- s => s.SetProperty(c => c.ContactName, c => "Updated"),
+ s => s.SetProperty(c => c.ContactName, "Updated"),
rowsAffectedCount: 4,
(b, a) => Assert.All(a, c => Assert.Equal("Updated", c.ContactName)));
@@ -485,7 +535,7 @@ public virtual Task Update_Where_OrderBy_Take_set_constant(bool async)
async,
ss => ss.Set().Where(c => c.CustomerID.StartsWith("F")).OrderBy(c => c.City).Take(4),
e => e,
- s => s.SetProperty(c => c.ContactName, c => "Updated"),
+ s => s.SetProperty(c => c.ContactName, "Updated"),
rowsAffectedCount: 4,
(b, a) => Assert.All(a, c => Assert.Equal("Updated", c.ContactName)));
@@ -496,7 +546,7 @@ public virtual Task Update_Where_OrderBy_Skip_Take_set_constant(bool async)
async,
ss => ss.Set().Where(c => c.CustomerID.StartsWith("F")).OrderBy(c => c.City).Skip(2).Take(4),
e => e,
- s => s.SetProperty(c => c.ContactName, c => "Updated"),
+ s => s.SetProperty(c => c.ContactName, "Updated"),
rowsAffectedCount: 4,
(b, a) => Assert.All(a, c => Assert.Equal("Updated", c.ContactName)));
@@ -507,7 +557,7 @@ public virtual Task Update_Where_OrderBy_Skip_Take_Skip_Take_set_constant(bool a
async,
ss => ss.Set().Where(c => c.CustomerID.StartsWith("F")).OrderBy(c => c.City).Skip(2).Take(6).Skip(2).Take(2),
e => e,
- s => s.SetProperty(c => c.ContactName, c => "Updated"),
+ s => s.SetProperty(c => c.ContactName, "Updated"),
rowsAffectedCount: 2,
(b, a) => Assert.All(a, c => Assert.Equal("Updated", c.ContactName)));
@@ -522,7 +572,7 @@ public virtual Task Update_Where_GroupBy_aggregate_set_constant(bool async)
== ss.Set()
.GroupBy(e => e.CustomerID).Where(g => g.Count() > 11).Select(e => e.Key).FirstOrDefault()),
e => e,
- s => s.SetProperty(c => c.ContactName, c => "Updated"),
+ s => s.SetProperty(c => c.ContactName, "Updated"),
rowsAffectedCount: 1,
(b, a) => Assert.All(a, c => Assert.Equal("Updated", c.ContactName)));
@@ -537,7 +587,7 @@ public virtual Task Update_Where_GroupBy_First_set_constant(bool async)
== ss.Set()
.GroupBy(e => e.CustomerID).Where(g => g.Count() > 11).Select(e => e.First().CustomerID).FirstOrDefault()),
e => e,
- s => s.SetProperty(c => c.ContactName, c => "Updated"),
+ s => s.SetProperty(c => c.ContactName, "Updated"),
rowsAffectedCount: 1,
(b, a) => Assert.All(a, c => Assert.Equal("Updated", c.ContactName)));
@@ -552,7 +602,7 @@ public virtual Task Update_Where_GroupBy_First_set_constant_2(bool async)
== ss.Set()
.GroupBy(e => e.CustomerID).Where(g => g.Count() > 11).Select(e => e.First().Customer).FirstOrDefault()),
e => e,
- s => s.SetProperty(c => c.ContactName, c => "Updated"),
+ s => s.SetProperty(c => c.ContactName, "Updated"),
rowsAffectedCount: 1,
(b, a) => Assert.All(a, c => Assert.Equal("Updated", c.ContactName)));
@@ -566,7 +616,7 @@ public virtual Task Update_Where_GroupBy_First_set_constant_3(bool async)
c => ss.Set()
.GroupBy(e => e.CustomerID).Where(g => g.Count() > 11).Select(e => e.First().Customer).Contains(c)),
e => e,
- s => s.SetProperty(c => c.ContactName, c => "Updated"),
+ s => s.SetProperty(c => c.ContactName, "Updated"),
rowsAffectedCount: 24,
(b, a) => Assert.All(a, c => Assert.Equal("Updated", c.ContactName)));
@@ -577,7 +627,7 @@ public virtual Task Update_Where_Distinct_set_constant(bool async)
async,
ss => ss.Set().Where(c => c.CustomerID.StartsWith("F")).Distinct(),
e => e,
- s => s.SetProperty(c => c.ContactName, c => "Updated"),
+ s => s.SetProperty(c => c.ContactName, "Updated"),
rowsAffectedCount: 8,
(b, a) => Assert.All(a, c => Assert.Equal("Updated", c.ContactName)));
@@ -588,7 +638,7 @@ public virtual Task Update_Where_using_navigation_set_null(bool async)
async,
ss => ss.Set().Where(o => o.Customer.City == "Seattle"),
e => e,
- s => s.SetProperty(c => c.OrderDate, c => null),
+ s => s.SetProperty(c => c.OrderDate, (DateTime?)null),
rowsAffectedCount: 14,
(b, a) => Assert.All(a, c => Assert.Null(c.OrderDate)));
@@ -599,7 +649,7 @@ public virtual Task Update_Where_using_navigation_2_set_constant(bool async)
async,
ss => ss.Set().Where(od => od.Order.Customer.City == "Seattle"),
e => e,
- s => s.SetProperty(c => c.Quantity, c => 1),
+ s => s.SetProperty(c => c.Quantity, 1),
rowsAffectedCount: 40,
(b, a) => Assert.All(a, c => Assert.Equal(1, c.Quantity)));
@@ -610,7 +660,7 @@ public virtual Task Update_Where_SelectMany_set_null(bool async)
async,
ss => ss.Set().Where(c => c.CustomerID.StartsWith("F")).SelectMany(c => c.Orders),
e => e,
- s => s.SetProperty(c => c.OrderDate, c => null),
+ s => s.SetProperty(c => c.OrderDate, (DateTime?)null),
rowsAffectedCount: 63,
(b, a) => Assert.All(a, c => Assert.Null(c.OrderDate)));
@@ -657,7 +707,7 @@ public virtual Task Update_Where_set_constant_using_ef_property(bool async)
async,
ss => ss.Set().Where(c => c.CustomerID.StartsWith("F")),
e => e,
- s => s.SetProperty(c => EF.Property(c, "ContactName"), c => "Updated"),
+ s => s.SetProperty(c => EF.Property(c, "ContactName"), "Updated"),
rowsAffectedCount: 8,
(b, a) => Assert.All(a, c => Assert.Equal("Updated", c.ContactName)));
@@ -668,7 +718,7 @@ public virtual Task Update_Where_set_null(bool async)
async,
ss => ss.Set().Where(c => c.CustomerID.StartsWith("F")),
e => e,
- s => s.SetProperty(c => c.ContactName, c => null),
+ s => s.SetProperty(c => c.ContactName, (string)null),
rowsAffectedCount: 8,
(b, a) => Assert.All(a, c => Assert.Null(c.ContactName)));
@@ -705,7 +755,7 @@ public virtual Task Update_Where_multiple_set(bool async)
async,
ss => ss.Set().Where(c => c.CustomerID.StartsWith("F")),
e => e,
- s => s.SetProperty(c => c.ContactName, c => value).SetProperty(c => c.City, c => "Seattle"),
+ s => s.SetProperty(c => c.ContactName, c => value).SetProperty(c => c.City, "Seattle"),
rowsAffectedCount: 8,
(b, a) => Assert.All(
a, c =>
@@ -724,7 +774,7 @@ public virtual Task Update_with_invalid_lambda_in_set_property_throws(bool async
async,
ss => ss.Set().Where(od => od.OrderID < 10250),
e => e,
- s => s.SetProperty(e => e.MaybeScalar(e => e.OrderID), e => 10300),
+ s => s.SetProperty(e => e.MaybeScalar(e => e.OrderID), 10300),
rowsAffectedCount: 0));
[ConditionalTheory]
@@ -737,7 +787,7 @@ public virtual Task Update_multiple_entity_throws(bool async)
ss => ss.Set().Where(o => o.CustomerID.StartsWith("F"))
.Select(e => new { e, e.Customer }),
e => e.Customer,
- s => s.SetProperty(c => c.Customer.ContactName, c => "Name").SetProperty(c => c.e.OrderDate, e => new DateTime(2020, 1, 1)),
+ s => s.SetProperty(c => c.Customer.ContactName, "Name").SetProperty(c => c.e.OrderDate, new DateTime(2020, 1, 1)),
rowsAffectedCount: 0));
[ConditionalTheory]
@@ -745,13 +795,13 @@ public virtual Task Update_multiple_entity_throws(bool async)
public virtual Task Update_unmapped_property_throws(bool async)
=> AssertTranslationFailed(
RelationalStrings.UnableToTranslateSetProperty(
- "c => c.IsLondon", "c => True",
+ "c => c.IsLondon", "True",
CoreStrings.QueryUnableToTranslateMember("IsLondon", "Customer")),
() => AssertUpdate(
async,
ss => ss.Set().Where(c => c.CustomerID.StartsWith("F")),
e => e,
- s => s.SetProperty(c => c.IsLondon, c => true),
+ s => s.SetProperty(c => c.IsLondon, true),
rowsAffectedCount: 0));
[ConditionalTheory]
@@ -762,7 +812,7 @@ public virtual Task Update_Union_set_constant(bool async)
ss => ss.Set().Where(c => c.CustomerID.StartsWith("F"))
.Union(ss.Set().Where(c => c.CustomerID.StartsWith("A"))),
e => e,
- s => s.SetProperty(c => c.ContactName, c => "Updated"),
+ s => s.SetProperty(c => c.ContactName, "Updated"),
rowsAffectedCount: 12,
(b, a) => Assert.All(a, c => Assert.Equal("Updated", c.ContactName)));
@@ -774,7 +824,7 @@ public virtual Task Update_Concat_set_constant(bool async)
ss => ss.Set().Where(c => c.CustomerID.StartsWith("F"))
.Concat(ss.Set().Where(c => c.CustomerID.StartsWith("A"))),
e => e,
- s => s.SetProperty(c => c.ContactName, c => "Updated"),
+ s => s.SetProperty(c => c.ContactName, "Updated"),
rowsAffectedCount: 12,
(b, a) => Assert.All(a, c => Assert.Equal("Updated", c.ContactName)));
@@ -786,7 +836,7 @@ public virtual Task Update_Except_set_constant(bool async)
ss => ss.Set().Where(c => c.CustomerID.StartsWith("F"))
.Except(ss.Set().Where(c => c.CustomerID.StartsWith("A"))),
e => e,
- s => s.SetProperty(c => c.ContactName, c => "Updated"),
+ s => s.SetProperty(c => c.ContactName, "Updated"),
rowsAffectedCount: 8,
(b, a) => Assert.All(a, c => Assert.Equal("Updated", c.ContactName)));
@@ -798,7 +848,7 @@ public virtual Task Update_Intersect_set_constant(bool async)
ss => ss.Set().Where(c => c.CustomerID.StartsWith("F"))
.Intersect(ss.Set().Where(c => c.CustomerID.StartsWith("A"))),
e => e,
- s => s.SetProperty(c => c.ContactName, c => "Updated"),
+ s => s.SetProperty(c => c.ContactName, "Updated"),
rowsAffectedCount: 0,
(b, a) => Assert.All(a, c => Assert.Equal("Updated", c.ContactName)));
@@ -812,7 +862,7 @@ join o in ss.Set().Where(o => o.OrderID < 10300)
on c.CustomerID equals o.CustomerID
select new { c, o },
e => e.c,
- s => s.SetProperty(c => c.c.ContactName, c => "Updated"),
+ s => s.SetProperty(c => c.c.ContactName, "Updated"),
rowsAffectedCount: 2,
(b, a) => Assert.All(a, c => Assert.Equal("Updated", c.ContactName)));
@@ -827,7 +877,7 @@ on c.CustomerID equals o.CustomerID into grouping
from o in grouping.DefaultIfEmpty()
select new { c, o },
e => e.c,
- s => s.SetProperty(c => c.c.ContactName, c => "Updated"),
+ s => s.SetProperty(c => c.c.ContactName, "Updated"),
rowsAffectedCount: 8,
(b, a) => Assert.All(a, c => Assert.Equal("Updated", c.ContactName)));
@@ -840,7 +890,7 @@ public virtual Task Update_with_cross_join_set_constant(bool async)
from o in ss.Set().Where(o => o.OrderID < 10300)
select new { c, o },
e => e.c,
- s => s.SetProperty(c => c.c.ContactName, c => "Updated"),
+ s => s.SetProperty(c => c.c.ContactName, "Updated"),
rowsAffectedCount: 8,
(b, a) => Assert.All(a, c => Assert.Equal("Updated", c.ContactName)));
@@ -853,7 +903,7 @@ public virtual Task Update_with_cross_apply_set_constant(bool async)
from o in ss.Set().Where(o => o.OrderID < 10300 && o.OrderDate.Value.Year < c.ContactName.Length)
select new { c, o },
e => e.c,
- s => s.SetProperty(c => c.c.ContactName, c => "Updated"),
+ s => s.SetProperty(c => c.c.ContactName, "Updated"),
rowsAffectedCount: 0,
(b, a) => Assert.All(a, c => Assert.Equal("Updated", c.ContactName)));
@@ -866,7 +916,7 @@ public virtual Task Update_with_outer_apply_set_constant(bool async)
from o in ss.Set().Where(o => o.OrderID < 10300 && o.OrderDate.Value.Year < c.ContactName.Length).DefaultIfEmpty()
select new { c, o },
e => e.c,
- s => s.SetProperty(c => c.c.ContactName, c => "Updated"),
+ s => s.SetProperty(c => c.c.ContactName, "Updated"),
rowsAffectedCount: 8,
(b, a) => Assert.All(a, c => Assert.Equal("Updated", c.ContactName)));
@@ -887,7 +937,7 @@ from o in grouping.DefaultIfEmpty()
o
},
e => e.c,
- s => s.SetProperty(c => c.c.ContactName, c => "Updated"),
+ s => s.SetProperty(c => c.c.ContactName, "Updated"),
rowsAffectedCount: 8,
(b, a) => Assert.All(a, c => Assert.Equal("Updated", c.ContactName)));
@@ -901,7 +951,7 @@ from c2 in ss.Set().Where(c => c.City.StartsWith("S"))
from o in ss.Set().Where(o => o.OrderID < 10300 && o.OrderDate.Value.Year < c.ContactName.Length)
select new { c, o },
e => e.c,
- s => s.SetProperty(c => c.c.ContactName, c => "Updated"),
+ s => s.SetProperty(c => c.c.ContactName, "Updated"),
rowsAffectedCount: 0,
(b, a) => Assert.All(a, c => Assert.Equal("Updated", c.ContactName)));
@@ -920,7 +970,7 @@ from o in ss.Set().Where(o => o.OrderID < 10300 && o.OrderDate.Value.Year
o
},
e => e.c,
- s => s.SetProperty(c => c.c.ContactName, c => "Updated"),
+ s => s.SetProperty(c => c.c.ContactName, "Updated"),
rowsAffectedCount: 8,
(b, a) => Assert.All(a, c => Assert.Equal("Updated", c.ContactName)));
@@ -938,7 +988,7 @@ await TestHelpers.ExecuteWithStrategyInTransactionAsync(
@"SELECT [Region], [PostalCode], [Phone], [Fax], [CustomerID], [Country], [ContactTitle], [ContactName], [CompanyName], [City], [Address]
FROM [Customers]
WHERE [CustomerID] LIKE 'A%'"))
- .ExecuteUpdateAsync(s => s.SetProperty(c => c.ContactName, c => "Updated")));
+ .ExecuteUpdateAsync(s => s.SetProperty(c => c.ContactName, "Updated")));
}
else
{
@@ -950,7 +1000,7 @@ FROM [Customers]
@"SELECT [Region], [PostalCode], [Phone], [Fax], [CustomerID], [Country], [ContactTitle], [ContactName], [CompanyName], [City], [Address]
FROM [Customers]
WHERE [CustomerID] LIKE 'A%'"))
- .ExecuteUpdate(s => s.SetProperty(c => c.ContactName, c => "Updated")));
+ .ExecuteUpdate(s => s.SetProperty(c => c.ContactName, "Updated")));
}
}
@@ -962,7 +1012,7 @@ public virtual Task Update_Where_SelectMany_subquery_set_null(bool async)
ss => ss.Set().Where(c => c.CustomerID.StartsWith("F"))
.SelectMany(c => c.Orders.Where(o => o.OrderDate.Value.Year == 1997)),
e => e,
- s => s.SetProperty(c => c.OrderDate, c => null),
+ s => s.SetProperty(c => c.OrderDate, (DateTime?)null),
rowsAffectedCount: 35,
(b, a) => Assert.All(a, c => Assert.Null(c.OrderDate)));
diff --git a/test/EFCore.Relational.Specification.Tests/EntitySplittingTestBase.cs b/test/EFCore.Relational.Specification.Tests/EntitySplittingTestBase.cs
index ca6458f53f1..f4d530fe10a 100644
--- a/test/EFCore.Relational.Specification.Tests/EntitySplittingTestBase.cs
+++ b/test/EFCore.Relational.Specification.Tests/EntitySplittingTestBase.cs
@@ -82,7 +82,7 @@ await TestHelpers.ExecuteWithStrategyInTransactionAsync(
RelationalStrings.NonQueryTranslationFailedWithDetails(
"", RelationalStrings.ExecuteOperationOnEntitySplitting("ExecuteUpdate", "MeterReading"))[21..],
(await Assert.ThrowsAsync(
- () => context.MeterReadings.ExecuteUpdateAsync(s => s.SetProperty(m => m.CurrentRead, m => "Value")))).Message));
+ () => context.MeterReadings.ExecuteUpdateAsync(s => s.SetProperty(m => m.CurrentRead, "Value")))).Message));
}
else
{
@@ -93,7 +93,7 @@ await TestHelpers.ExecuteWithStrategyInTransactionAsync(
RelationalStrings.NonQueryTranslationFailedWithDetails(
"", RelationalStrings.ExecuteOperationOnEntitySplitting("ExecuteUpdate", "MeterReading"))[21..],
Assert.Throws(
- () => context.MeterReadings.ExecuteUpdate(s => s.SetProperty(m => m.CurrentRead, m => "Value"))).Message));
+ () => context.MeterReadings.ExecuteUpdate(s => s.SetProperty(m => m.CurrentRead, "Value"))).Message));
}
}
diff --git a/test/EFCore.Relational.Specification.Tests/TableSplittingTestBase.cs b/test/EFCore.Relational.Specification.Tests/TableSplittingTestBase.cs
index e5045b7e722..fc9ee20b3ff 100644
--- a/test/EFCore.Relational.Specification.Tests/TableSplittingTestBase.cs
+++ b/test/EFCore.Relational.Specification.Tests/TableSplittingTestBase.cs
@@ -657,7 +657,7 @@ public virtual async Task ExecuteUpdate_works_for_table_sharing(bool async)
await TestHelpers.ExecuteWithStrategyInTransactionAsync(
CreateContext,
UseTransaction,
- async context => await context.Set().ExecuteUpdateAsync(s => s.SetProperty(e => e.SeatingCapacity, e => 1)),
+ async context => await context.Set().ExecuteUpdateAsync(s => s.SetProperty(e => e.SeatingCapacity, 1)),
context =>
{
Assert.True(context.Set().All(e => e.SeatingCapacity == 1));
@@ -670,7 +670,7 @@ await TestHelpers.ExecuteWithStrategyInTransactionAsync(
TestHelpers.ExecuteWithStrategyInTransaction(
CreateContext,
UseTransaction,
- context => context.Set().ExecuteUpdate(s => s.SetProperty(e => e.SeatingCapacity, e => 1)),
+ context => context.Set().ExecuteUpdate(s => s.SetProperty(e => e.SeatingCapacity, 1)),
context => Assert.True(context.Set().All(e => e.SeatingCapacity == 1)));
}
}
diff --git a/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqlServerTest.cs
index 503e5eaf819..3efcc5a797e 100644
--- a/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqlServerTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqlServerTest.cs
@@ -5,9 +5,13 @@ namespace Microsoft.EntityFrameworkCore.BulkUpdates;
public class NorthwindBulkUpdatesSqlServerTest : NorthwindBulkUpdatesTestBase>
{
- public NorthwindBulkUpdatesSqlServerTest(NorthwindBulkUpdatesSqlServerFixture fixture)
+ public NorthwindBulkUpdatesSqlServerTest(
+ NorthwindBulkUpdatesSqlServerFixture fixture,
+ ITestOutputHelper testOutputHelper)
: base(fixture)
{
+ ClearLog();
+ // Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper);
}
[ConditionalFact]
@@ -609,6 +613,43 @@ FROM [Customers] AS [c]
WHERE [c].[CustomerID] LIKE N'F%'");
}
+ public override async Task Update_Where_set_parameter_from_closure_array(bool async)
+ {
+ await base.Update_Where_set_parameter_from_closure_array(async);
+
+ AssertExecuteUpdateSql(
+ @"@__p_0='Abc' (Size = 4000)
+
+UPDATE [c]
+SET [c].[ContactName] = @__p_0
+FROM [Customers] AS [c]
+WHERE [c].[CustomerID] LIKE N'F%'");
+ }
+
+ public override async Task Update_Where_set_parameter_from_inline_list(bool async)
+ {
+ await base.Update_Where_set_parameter_from_inline_list(async);
+
+ AssertExecuteUpdateSql(
+ @"UPDATE [c]
+SET [c].[ContactName] = N'Abc'
+FROM [Customers] AS [c]
+WHERE [c].[CustomerID] LIKE N'F%'");
+ }
+
+ public override async Task Update_Where_set_parameter_from_multilevel_property_access(bool async)
+ {
+ await base.Update_Where_set_parameter_from_multilevel_property_access(async);
+
+ AssertExecuteUpdateSql(
+ @"@__container_Containee_Property_0='Abc' (Size = 4000)
+
+UPDATE [c]
+SET [c].[ContactName] = @__container_Containee_Property_0
+FROM [Customers] AS [c]
+WHERE [c].[CustomerID] LIKE N'F%'");
+ }
+
public override async Task Update_Where_Skip_set_constant(bool async)
{
await base.Update_Where_Skip_set_constant(async);
diff --git a/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqliteTest.cs
index fbd9b9c4572..1795ff9fa90 100644
--- a/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqliteTest.cs
+++ b/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqliteTest.cs
@@ -7,9 +7,13 @@ namespace Microsoft.EntityFrameworkCore.BulkUpdates;
public class NorthwindBulkUpdatesSqliteTest : NorthwindBulkUpdatesTestBase>
{
- public NorthwindBulkUpdatesSqliteTest(NorthwindBulkUpdatesSqliteFixture fixture)
+ public NorthwindBulkUpdatesSqliteTest(
+ NorthwindBulkUpdatesSqliteFixture fixture,
+ ITestOutputHelper testOutputHelper)
: base(fixture)
{
+ ClearLog();
+ // Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper);
}
[ConditionalFact]
@@ -587,6 +591,40 @@ public override async Task Update_Where_set_parameter(bool async)
WHERE ""c"".""CustomerID"" LIKE 'F%'");
}
+ public override async Task Update_Where_set_parameter_from_closure_array(bool async)
+ {
+ await base.Update_Where_set_parameter_from_closure_array(async);
+
+ AssertExecuteUpdateSql(
+ @"@__p_0='Abc' (Size = 3)
+
+UPDATE ""Customers"" AS ""c""
+SET ""ContactName"" = @__p_0
+WHERE ""c"".""CustomerID"" LIKE 'F%'");
+ }
+
+ public override async Task Update_Where_set_parameter_from_inline_list(bool async)
+ {
+ await base.Update_Where_set_parameter_from_inline_list(async);
+
+ AssertExecuteUpdateSql(
+ @"UPDATE ""Customers"" AS ""c""
+SET ""ContactName"" = 'Abc'
+WHERE ""c"".""CustomerID"" LIKE 'F%'");
+ }
+
+ public override async Task Update_Where_set_parameter_from_multilevel_property_access(bool async)
+ {
+ await base.Update_Where_set_parameter_from_multilevel_property_access(async);
+
+ AssertExecuteUpdateSql(
+ @"@__container_Containee_Property_0='Abc' (Size = 3)
+
+UPDATE ""Customers"" AS ""c""
+SET ""ContactName"" = @__container_Containee_Property_0
+WHERE ""c"".""CustomerID"" LIKE 'F%'");
+ }
+
public override async Task Update_Where_Skip_set_constant(bool async)
{
await base.Update_Where_Skip_set_constant(async);