diff --git a/Directory.Build.props b/Directory.Build.props
index 80858aaddfc..27589f30050 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -55,9 +55,6 @@
$(NoWarn.Replace(';1591', ''))
-
-
-
diff --git a/Directory.Packages.props b/Directory.Packages.props
new file mode 100644
index 00000000000..b54137363c7
--- /dev/null
+++ b/Directory.Packages.props
@@ -0,0 +1,62 @@
+
+
+
+
+
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/NuGet.config b/NuGet.config
index d1a8a417e43..21b746fb5ac 100644
--- a/NuGet.config
+++ b/NuGet.config
@@ -16,6 +16,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/benchmark/Directory.Build.props b/benchmark/Directory.Build.props
index d92102a50e8..acb8c8be1b6 100644
--- a/benchmark/Directory.Build.props
+++ b/benchmark/Directory.Build.props
@@ -6,10 +6,10 @@
-
-
-
-
+
+
+
+
diff --git a/benchmark/Directory.Packages.props b/benchmark/Directory.Packages.props
new file mode 100644
index 00000000000..7d6fb856d91
--- /dev/null
+++ b/benchmark/Directory.Packages.props
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/benchmark/EFCore.Benchmarks/EFCore.Benchmarks.csproj b/benchmark/EFCore.Benchmarks/EFCore.Benchmarks.csproj
index f0bd47ad2fd..271d03e2cb8 100644
--- a/benchmark/EFCore.Benchmarks/EFCore.Benchmarks.csproj
+++ b/benchmark/EFCore.Benchmarks/EFCore.Benchmarks.csproj
@@ -12,7 +12,7 @@
-
+
diff --git a/benchmark/EFCore.Sqlite.Benchmarks/EFCore.Sqlite.Benchmarks.csproj b/benchmark/EFCore.Sqlite.Benchmarks/EFCore.Sqlite.Benchmarks.csproj
index a936d82679a..2eb2534dfb2 100644
--- a/benchmark/EFCore.Sqlite.Benchmarks/EFCore.Sqlite.Benchmarks.csproj
+++ b/benchmark/EFCore.Sqlite.Benchmarks/EFCore.Sqlite.Benchmarks.csproj
@@ -17,7 +17,7 @@
-
+
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index 8f32a0581e9..826298a1d62 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -1,57 +1,65 @@
-
+
https://github.com/dotnet/runtime
- d0f3235d312f7cf9683012b3fe96b2c6f20a1743
+ dec716d1c4651b70e4710e781e832a64be1e713b
-
+
https://github.com/dotnet/runtime
- d0f3235d312f7cf9683012b3fe96b2c6f20a1743
+ dec716d1c4651b70e4710e781e832a64be1e713b
-
+
https://github.com/dotnet/runtime
- d0f3235d312f7cf9683012b3fe96b2c6f20a1743
+ dec716d1c4651b70e4710e781e832a64be1e713b
-
+
https://github.com/dotnet/runtime
- d0f3235d312f7cf9683012b3fe96b2c6f20a1743
+ dec716d1c4651b70e4710e781e832a64be1e713b
-
+
https://github.com/dotnet/runtime
- d0f3235d312f7cf9683012b3fe96b2c6f20a1743
+ dec716d1c4651b70e4710e781e832a64be1e713b
-
+
https://github.com/dotnet/runtime
- d0f3235d312f7cf9683012b3fe96b2c6f20a1743
+ dec716d1c4651b70e4710e781e832a64be1e713b
-
+
https://github.com/dotnet/runtime
- d0f3235d312f7cf9683012b3fe96b2c6f20a1743
+ dec716d1c4651b70e4710e781e832a64be1e713b
-
+
https://github.com/dotnet/runtime
- d0f3235d312f7cf9683012b3fe96b2c6f20a1743
+ dec716d1c4651b70e4710e781e832a64be1e713b
-
+
https://github.com/dotnet/runtime
- d0f3235d312f7cf9683012b3fe96b2c6f20a1743
+ dec716d1c4651b70e4710e781e832a64be1e713b
-
+
https://github.com/dotnet/runtime
- d0f3235d312f7cf9683012b3fe96b2c6f20a1743
+ dec716d1c4651b70e4710e781e832a64be1e713b
-
+
https://github.com/dotnet/runtime
- d0f3235d312f7cf9683012b3fe96b2c6f20a1743
+ dec716d1c4651b70e4710e781e832a64be1e713b
-
+
https://github.com/dotnet/runtime
- d0f3235d312f7cf9683012b3fe96b2c6f20a1743
+ dec716d1c4651b70e4710e781e832a64be1e713b
+
+
+ https://github.com/dotnet/runtime
+ dec716d1c4651b70e4710e781e832a64be1e713b
+
+
+ https://github.com/dotnet/runtime
+ dec716d1c4651b70e4710e781e832a64be1e713b
diff --git a/eng/Versions.props b/eng/Versions.props
index a32db59af50..ae71e1ac801 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -16,31 +16,33 @@
False
- 9.0.0-rc.2.24429.19
- 9.0.0-rc.2.24429.19
- 9.0.0-rc.2.24429.19
- 9.0.0-rc.2.24429.19
- 9.0.0-rc.2.24429.19
- 9.0.0-rc.2.24429.19
- 9.0.0-rc.2.24429.19
- 9.0.0-rc.2.24429.19
- 9.0.0-rc.2.24429.19
- 9.0.0-rc.2.24429.19
- 9.0.0-rc.2.24429.19
- 9.0.0-rc.2.24429.19
+ 9.0.0-rc.2.24456.9
+ 9.0.0-rc.2.24456.9
+ 9.0.0-rc.2.24456.9
+ 9.0.0-rc.2.24456.9
+ 9.0.0-rc.2.24456.9
+ 9.0.0-rc.2.24456.9
+ 9.0.0-rc.2.24456.9
+ 9.0.0-rc.2.24456.9
+ 9.0.0-rc.2.24456.9
+ 9.0.0-rc.2.24456.9
+ 9.0.0-rc.2.24456.9
+ 9.0.0-rc.2.24456.9
+ 9.0.0-rc.2.24456.9
+ 9.0.0-rc.2.24456.9
10.0.0-beta.24459.1
- 17.9.5
- 17.9.5
- 17.9.5
-
+ 17.8.3
+ 17.8.3
+
4.8.0
- 1.1.2-beta1.24121.1
+ 1.1.2
1.12.0
1.3.2
1.8.1
+ 2.1.10
diff --git a/global.json b/global.json
index 70f39f854e8..b8e91cabfe6 100644
--- a/global.json
+++ b/global.json
@@ -1,11 +1,11 @@
{
"sdk": {
- "version": "9.0.100-preview.7.24407.12",
+ "version": "9.0.100-rc.1.24452.12",
"allowPrerelease": true,
"rollForward": "latestMajor"
},
"tools": {
- "dotnet": "9.0.100-preview.7.24407.12",
+ "dotnet": "9.0.100-rc.1.24452.12",
"runtimes": {
"dotnet": [
"$(MicrosoftNETCoreAppRuntimewinx64Version)"
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index f202e2801f2..e65be73b154 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -10,7 +10,7 @@
-
+
diff --git a/src/EFCore.Analyzers/EFCore.Analyzers.csproj b/src/EFCore.Analyzers/EFCore.Analyzers.csproj
index beacecfce80..90c28c46a19 100644
--- a/src/EFCore.Analyzers/EFCore.Analyzers.csproj
+++ b/src/EFCore.Analyzers/EFCore.Analyzers.csproj
@@ -29,8 +29,7 @@
-
-
+
diff --git a/src/EFCore.Cosmos/EFCore.Cosmos.csproj b/src/EFCore.Cosmos/EFCore.Cosmos.csproj
index 783a083e626..e5189d571d3 100644
--- a/src/EFCore.Cosmos/EFCore.Cosmos.csproj
+++ b/src/EFCore.Cosmos/EFCore.Cosmos.csproj
@@ -48,7 +48,7 @@
-
+
diff --git a/src/EFCore.Cosmos/Extensions/CosmosEntityTypeExtensions.cs b/src/EFCore.Cosmos/Extensions/CosmosEntityTypeExtensions.cs
index ad0dcabff9e..f162fb711ef 100644
--- a/src/EFCore.Cosmos/Extensions/CosmosEntityTypeExtensions.cs
+++ b/src/EFCore.Cosmos/Extensions/CosmosEntityTypeExtensions.cs
@@ -72,8 +72,12 @@ public static void SetContainer(this IMutableEntityType entityType, string? name
/// The entity type to get the containing property name for.
/// The name of the parent property to which the entity type is mapped.
public static string? GetContainingPropertyName(this IReadOnlyEntityType entityType)
- => entityType[CosmosAnnotationNames.PropertyName] as string
- ?? GetDefaultContainingPropertyName(entityType);
+ {
+ var propertyName = entityType.FindAnnotation(CosmosAnnotationNames.PropertyName);
+ return propertyName == null
+ ? GetDefaultContainingPropertyName(entityType)
+ : (string?)propertyName.Value;
+ }
private static string? GetDefaultContainingPropertyName(IReadOnlyEntityType entityType)
=> entityType.FindOwnership() is IReadOnlyForeignKey ownership
@@ -198,7 +202,7 @@ public static void SetPartitionKeyPropertyName(this IMutableEntityType entityTyp
public static IReadOnlyList GetPartitionKeyPropertyNames(this IReadOnlyEntityType entityType)
=> entityType[CosmosAnnotationNames.PartitionKeyNames] as IReadOnlyList
?? entityType.BaseType?.GetPartitionKeyPropertyNames()
- ?? Array.Empty();
+ ?? [];
///
/// Sets the names of the properties that are used to store the hierarchical partition key.
diff --git a/src/EFCore.Design/EFCore.Design.csproj b/src/EFCore.Design/EFCore.Design.csproj
index cfb2ac7b165..9fb32f5f722 100644
--- a/src/EFCore.Design/EFCore.Design.csproj
+++ b/src/EFCore.Design/EFCore.Design.csproj
@@ -56,13 +56,13 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/src/EFCore.Proxies/EFCore.Proxies.csproj b/src/EFCore.Proxies/EFCore.Proxies.csproj
index 212bda63217..4e4ef839666 100644
--- a/src/EFCore.Proxies/EFCore.Proxies.csproj
+++ b/src/EFCore.Proxies/EFCore.Proxies.csproj
@@ -39,7 +39,7 @@
-
+
diff --git a/src/EFCore.Relational/EFCore.Relational.csproj b/src/EFCore.Relational/EFCore.Relational.csproj
index bac04d23a8f..bf707817d73 100644
--- a/src/EFCore.Relational/EFCore.Relational.csproj
+++ b/src/EFCore.Relational/EFCore.Relational.csproj
@@ -50,7 +50,7 @@
-
+
diff --git a/src/EFCore.Relational/Extensions/RelationalEntityTypeExtensions.cs b/src/EFCore.Relational/Extensions/RelationalEntityTypeExtensions.cs
index 93beae7be86..8cee65a5187 100644
--- a/src/EFCore.Relational/Extensions/RelationalEntityTypeExtensions.cs
+++ b/src/EFCore.Relational/Extensions/RelationalEntityTypeExtensions.cs
@@ -1606,8 +1606,12 @@ public static void SetContainerColumnName(this IMutableEntityType entityType, st
/// The entity type to get the container column name for.
/// The container column name to which the entity type is mapped.
public static string? GetContainerColumnName(this IReadOnlyEntityType entityType)
- => entityType.FindAnnotation(RelationalAnnotationNames.ContainerColumnName)?.Value as string
- ?? entityType.FindOwnership()?.PrincipalEntityType.GetContainerColumnName();
+ {
+ var containerColumnName = entityType.FindAnnotation(RelationalAnnotationNames.ContainerColumnName);
+ return containerColumnName == null
+ ? entityType.FindOwnership()?.PrincipalEntityType.GetContainerColumnName()
+ : (string?)containerColumnName.Value;
+ }
///
/// Sets the column type to use for the container column to which the entity type is mapped.
@@ -1720,8 +1724,14 @@ public static void SetContainerColumnTypeMapping(this IMutableEntityType entityT
/// is returned for entities that are not mapped to a JSON column.
///
public static string? GetJsonPropertyName(this IReadOnlyEntityType entityType)
- => (string?)entityType.FindAnnotation(RelationalAnnotationNames.JsonPropertyName)?.Value
- ?? (!entityType.IsMappedToJson() ? null : entityType.FindOwnership()!.GetNavigation(pointsToPrincipal: false)!.Name);
+ {
+ var propertyName = entityType.FindAnnotation(RelationalAnnotationNames.JsonPropertyName);
+ return propertyName == null
+ ? (entityType.IsMappedToJson()
+ ? entityType.FindOwnership()!.GetNavigation(pointsToPrincipal: false)!.Name
+ : null)
+ : (string?)propertyName.Value;
+ }
///
/// Sets the value of JSON property name used for the given entity mapped to a JSON column.
diff --git a/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs b/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs
index ebd72d633df..69ed1618137 100644
--- a/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs
+++ b/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs
@@ -2833,8 +2833,13 @@ protected virtual void ValidateJsonEntityProperties(
IEntityType jsonEntityType)
{
var jsonPropertyNames = new List();
- foreach (var property in jsonEntityType.GetDeclaredProperties().Where(p => !string.IsNullOrEmpty(p.GetJsonPropertyName())))
+ foreach (var property in jsonEntityType.GetDeclaredProperties())
{
+ if (string.IsNullOrEmpty(property.GetJsonPropertyName()))
+ {
+ continue;
+ }
+
if (property.TryGetDefaultValue(out var _))
{
throw new InvalidOperationException(
@@ -2857,6 +2862,12 @@ protected virtual void ValidateJsonEntityProperties(
foreach (var navigation in jsonEntityType.GetDeclaredNavigations())
{
+ if (!navigation.TargetEntityType.IsMappedToJson()
+ || navigation.IsOnDependent)
+ {
+ continue;
+ }
+
var jsonPropertyName = navigation.TargetEntityType.GetJsonPropertyName()!;
if (!jsonPropertyNames.Contains(jsonPropertyName))
{
diff --git a/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitor.cs b/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitor.cs
index 17d34a94a4a..79f1b03e845 100644
--- a/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitor.cs
+++ b/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitor.cs
@@ -484,7 +484,7 @@ protected override Expression VisitConditional(ConditionalExpression conditional
|| TranslationFailed(conditionalExpression.IfTrue, ifTrue, out var sqlIfTrue)
|| TranslationFailed(conditionalExpression.IfFalse, ifFalse, out var sqlIfFalse)
? QueryCompilationContext.NotTranslatedExpression
- : _sqlExpressionFactory.Case(new[] { new CaseWhenClause(sqlTest!, sqlIfTrue!) }, sqlIfFalse);
+ : _sqlExpressionFactory.Case([new CaseWhenClause(sqlTest!, sqlIfTrue!)], sqlIfFalse);
}
///
diff --git a/src/EFCore.Relational/Query/SqlExpressionFactory.cs b/src/EFCore.Relational/Query/SqlExpressionFactory.cs
index 2cd1673607f..47f94f1d78b 100644
--- a/src/EFCore.Relational/Query/SqlExpressionFactory.cs
+++ b/src/EFCore.Relational/Query/SqlExpressionFactory.cs
@@ -357,7 +357,7 @@ private InExpression ApplyTypeMappingOnIn(InExpression inExpression)
private SqlExpression ApplyTypeMappingOnJsonScalar(
JsonScalarExpression jsonScalarExpression,
- RelationalTypeMapping? typeMapping)
+ RelationalTypeMapping? elementMapping)
{
if (jsonScalarExpression is not { Json: var array, Path: [{ ArrayIndex: { } index }] })
{
@@ -369,24 +369,28 @@ private SqlExpression ApplyTypeMappingOnJsonScalar(
var newPath = indexWithTypeMapping == index ? jsonScalarExpression.Path : [new PathSegment(indexWithTypeMapping)];
// If a type mapping is being applied from the outside, it applies to the element resulting from the array indexing operation;
- // we can infer the array's type mapping from it. Otherwise there's nothing to do but apply the default type mapping to the array.
- if (typeMapping is null)
+ // we can infer the array's type mapping from it.
+ if (elementMapping is null)
{
return new JsonScalarExpression(
- ApplyDefaultTypeMapping(array),
+ array,
newPath,
jsonScalarExpression.Type,
- _typeMappingSource.FindMapping(jsonScalarExpression.Type, Dependencies.Model),
+ jsonScalarExpression.TypeMapping,
jsonScalarExpression.IsNullable);
}
- // TODO: blocked on #30730: we need to be able to construct a JSON collection type mapping based on the element's.
- // For now, hacking to apply the default type mapping instead.
+ // Resolve the array type mapping for the given element mapping.
+ if (_typeMappingSource.FindMapping(array.Type, Dependencies.Model, elementMapping) is not RelationalTypeMapping arrayMapping)
+ {
+ throw new UnreachableException($"Couldn't find collection type mapping for element type mapping {elementMapping.ClrType.Name}");
+ }
+
return new JsonScalarExpression(
- ApplyDefaultTypeMapping(array), // Hack, until #30730
+ ApplyTypeMapping(array, arrayMapping),
newPath,
jsonScalarExpression.Type,
- typeMapping,
+ elementMapping,
jsonScalarExpression.IsNullable);
}
diff --git a/src/EFCore.Relational/Update/Internal/CommandBatchPreparer.cs b/src/EFCore.Relational/Update/Internal/CommandBatchPreparer.cs
index 23b83ce061e..fdf3c302b19 100644
--- a/src/EFCore.Relational/Update/Internal/CommandBatchPreparer.cs
+++ b/src/EFCore.Relational/Update/Internal/CommandBatchPreparer.cs
@@ -993,18 +993,30 @@ private static bool IsModified(IReadOnlyList columns, IReadOnlyModifica
var entry = command.Entries[entryIndex];
var columnMapping = column.FindColumnMapping(entry.EntityType);
var property = columnMapping?.Property;
- if (property != null
- && (property.GetAfterSaveBehavior() == PropertySaveBehavior.Save
- || (!property.IsPrimaryKey() && entry.EntityState != EntityState.Modified)))
+ if (property != null)
{
switch (entry.EntityState)
{
case EntityState.Added:
currentValue = entry.GetCurrentProviderValue(property);
+ if (entry.SharedIdentityEntry != null)
+ {
+ var sharedProperty = entry.SharedIdentityEntry.EntityType == entry.EntityType
+ ? property
+ : column.FindColumnMapping(entry.SharedIdentityEntry.EntityType)?.Property;
+
+ if (sharedProperty != null)
+ {
+ originalValue ??= entry.SharedIdentityEntry.GetOriginalProviderValue(sharedProperty);
+ }
+ }
+
break;
case EntityState.Deleted:
case EntityState.Unchanged:
originalValue ??= entry.GetOriginalProviderValue(property);
+ Check.DebugAssert(entry.SharedIdentityEntry == null, "entry.SharedIdentityEntry != null");
+
break;
case EntityState.Modified:
if (entry.IsModified(property))
diff --git a/src/EFCore.SqlServer.Abstractions/EFCore.SqlServer.Abstractions.csproj b/src/EFCore.SqlServer.Abstractions/EFCore.SqlServer.Abstractions.csproj
index 0a63e98053e..9cc5060b7f0 100644
--- a/src/EFCore.SqlServer.Abstractions/EFCore.SqlServer.Abstractions.csproj
+++ b/src/EFCore.SqlServer.Abstractions/EFCore.SqlServer.Abstractions.csproj
@@ -16,8 +16,8 @@
-
-
+
+
diff --git a/src/EFCore.SqlServer.NTS/EFCore.SqlServer.NTS.csproj b/src/EFCore.SqlServer.NTS/EFCore.SqlServer.NTS.csproj
index 68d80529ee4..9a775d6e018 100644
--- a/src/EFCore.SqlServer.NTS/EFCore.SqlServer.NTS.csproj
+++ b/src/EFCore.SqlServer.NTS/EFCore.SqlServer.NTS.csproj
@@ -56,8 +56,7 @@
-
-
+
diff --git a/src/EFCore.SqlServer/EFCore.SqlServer.csproj b/src/EFCore.SqlServer/EFCore.SqlServer.csproj
index 9e602e50ecd..9c55dc8c9bf 100644
--- a/src/EFCore.SqlServer/EFCore.SqlServer.csproj
+++ b/src/EFCore.SqlServer/EFCore.SqlServer.csproj
@@ -49,7 +49,7 @@
-
+
diff --git a/src/EFCore.Sqlite.Core/EFCore.Sqlite.Core.csproj b/src/EFCore.Sqlite.Core/EFCore.Sqlite.Core.csproj
index 82672a9741f..ce21537a399 100644
--- a/src/EFCore.Sqlite.Core/EFCore.Sqlite.Core.csproj
+++ b/src/EFCore.Sqlite.Core/EFCore.Sqlite.Core.csproj
@@ -51,7 +51,7 @@
-
+
diff --git a/src/EFCore.Sqlite.NTS/EFCore.Sqlite.NTS.csproj b/src/EFCore.Sqlite.NTS/EFCore.Sqlite.NTS.csproj
index fea05f25c06..c15872f5600 100644
--- a/src/EFCore.Sqlite.NTS/EFCore.Sqlite.NTS.csproj
+++ b/src/EFCore.Sqlite.NTS/EFCore.Sqlite.NTS.csproj
@@ -57,9 +57,8 @@
-
-
-
+
+
diff --git a/src/EFCore.Sqlite/EFCore.Sqlite.csproj b/src/EFCore.Sqlite/EFCore.Sqlite.csproj
index 4fd1cb6bce5..5e7afc5b865 100644
--- a/src/EFCore.Sqlite/EFCore.Sqlite.csproj
+++ b/src/EFCore.Sqlite/EFCore.Sqlite.csproj
@@ -47,7 +47,7 @@
-
+
diff --git a/src/EFCore.Tasks/EFCore.Tasks.csproj b/src/EFCore.Tasks/EFCore.Tasks.csproj
index 45ac5587a10..a84046e613c 100644
--- a/src/EFCore.Tasks/EFCore.Tasks.csproj
+++ b/src/EFCore.Tasks/EFCore.Tasks.csproj
@@ -49,16 +49,14 @@
-
-
-
+
+
-
+
-
diff --git a/src/EFCore.Tools/EFCore.Tools.csproj b/src/EFCore.Tools/EFCore.Tools.csproj
index 779f77df29a..1bd9cc8930a 100644
--- a/src/EFCore.Tools/EFCore.Tools.csproj
+++ b/src/EFCore.Tools/EFCore.Tools.csproj
@@ -35,7 +35,7 @@ Update-Database
-
+
diff --git a/src/EFCore/EFCore.csproj b/src/EFCore/EFCore.csproj
index f8ba3e739d9..722676f7c1c 100644
--- a/src/EFCore/EFCore.csproj
+++ b/src/EFCore/EFCore.csproj
@@ -46,8 +46,8 @@ Microsoft.EntityFrameworkCore.DbSet
-
-
+
+
diff --git a/src/EFCore/Metadata/Internal/EntityType.cs b/src/EFCore/Metadata/Internal/EntityType.cs
index 2fc7085df50..7cadc45f845 100644
--- a/src/EFCore/Metadata/Internal/EntityType.cs
+++ b/src/EFCore/Metadata/Internal/EntityType.cs
@@ -990,7 +990,7 @@ public virtual void OnForeignKeyUpdating(ForeignKey foreignKey)
removed = foreignKey.PrincipalKey.ReferencingForeignKeys!.Remove(foreignKey);
Check.DebugAssert(removed, "removed is false");
- removed = foreignKey.PrincipalEntityType.DeclaredReferencingForeignKeys!.Remove(foreignKey);
+ removed = foreignKey.PrincipalEntityType._declaredReferencingForeignKeys!.Remove(foreignKey);
Check.DebugAssert(removed, "removed is false");
}
@@ -1029,13 +1029,13 @@ public virtual void OnForeignKeyUpdated(ForeignKey foreignKey)
}
var principalEntityType = foreignKey.PrincipalEntityType;
- if (principalEntityType.DeclaredReferencingForeignKeys == null)
+ if (principalEntityType._declaredReferencingForeignKeys == null)
{
- principalEntityType.DeclaredReferencingForeignKeys = new SortedSet(ForeignKeyComparer.Instance) { foreignKey };
+ principalEntityType._declaredReferencingForeignKeys = new SortedSet(ForeignKeyComparer.Instance) { foreignKey };
}
else
{
- added = principalEntityType.DeclaredReferencingForeignKeys.Add(foreignKey);
+ added = principalEntityType._declaredReferencingForeignKeys.Add(foreignKey);
Check.DebugAssert(added, "added is false");
}
}
@@ -1371,7 +1371,7 @@ public virtual IEnumerable FindForeignKeysInHierarchy(
///
public virtual IEnumerable GetReferencingForeignKeys()
=> BaseType != null
- ? (DeclaredReferencingForeignKeys?.Count ?? 0) == 0
+ ? (_declaredReferencingForeignKeys?.Count ?? 0) == 0
? BaseType.GetReferencingForeignKeys()
: BaseType.GetReferencingForeignKeys().Concat(GetDeclaredReferencingForeignKeys())
: GetDeclaredReferencingForeignKeys();
@@ -1383,9 +1383,9 @@ public virtual IEnumerable GetReferencingForeignKeys()
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public virtual IEnumerable GetDeclaredReferencingForeignKeys()
- => DeclaredReferencingForeignKeys ?? Enumerable.Empty();
+ => _declaredReferencingForeignKeys ?? Enumerable.Empty();
- private SortedSet? DeclaredReferencingForeignKeys { get; set; }
+ private SortedSet? _declaredReferencingForeignKeys;
#endregion
@@ -1673,14 +1673,14 @@ public virtual IEnumerable GetNavigations()
_skipNavigations.Add(name, skipNavigation);
- if (targetEntityType.DeclaredReferencingSkipNavigations == null)
+ if (targetEntityType._declaredReferencingSkipNavigations == null)
{
- targetEntityType.DeclaredReferencingSkipNavigations =
+ targetEntityType._declaredReferencingSkipNavigations =
new SortedSet(SkipNavigationComparer.Instance) { skipNavigation };
}
else
{
- var added = targetEntityType.DeclaredReferencingSkipNavigations.Add(skipNavigation);
+ var added = targetEntityType._declaredReferencingSkipNavigations.Add(skipNavigation);
Check.DebugAssert(added, "added is false");
}
@@ -1826,7 +1826,7 @@ public virtual IEnumerable FindSkipNavigationsInHierarchy(string
|| foreignKey.ReferencingSkipNavigations!.Remove(navigation);
Check.DebugAssert(removed, "removed is false");
- removed = navigation.TargetEntityType.DeclaredReferencingSkipNavigations!.Remove(navigation);
+ removed = navigation.TargetEntityType._declaredReferencingSkipNavigations!.Remove(navigation);
Check.DebugAssert(removed, "removed is false");
navigation.SetRemovedFromModel();
@@ -1855,7 +1855,7 @@ public virtual IEnumerable GetSkipNavigations()
///
public virtual IEnumerable GetReferencingSkipNavigations()
=> BaseType != null
- ? (DeclaredReferencingSkipNavigations?.Count ?? 0) == 0
+ ? (_declaredReferencingSkipNavigations?.Count ?? 0) == 0
? BaseType.GetReferencingSkipNavigations()
: BaseType.GetReferencingSkipNavigations().Concat(GetDeclaredReferencingSkipNavigations())
: GetDeclaredReferencingSkipNavigations();
@@ -1867,7 +1867,7 @@ public virtual IEnumerable GetReferencingSkipNavigations()
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public virtual IEnumerable GetDeclaredReferencingSkipNavigations()
- => DeclaredReferencingSkipNavigations ?? Enumerable.Empty();
+ => _declaredReferencingSkipNavigations ?? Enumerable.Empty();
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -1880,7 +1880,7 @@ public virtual IEnumerable GetDerivedReferencingSkipNavigations(
? Enumerable.Empty()
: GetDerivedTypes().SelectMany(et => et.GetDeclaredReferencingSkipNavigations());
- private SortedSet? DeclaredReferencingSkipNavigations { get; set; }
+ private SortedSet? _declaredReferencingSkipNavigations;
#endregion
diff --git a/src/EFCore/Metadata/Internal/InternalModelBuilder.cs b/src/EFCore/Metadata/Internal/InternalModelBuilder.cs
index 69c2235a753..8f32abaa469 100644
--- a/src/EFCore/Metadata/Internal/InternalModelBuilder.cs
+++ b/src/EFCore/Metadata/Internal/InternalModelBuilder.cs
@@ -687,6 +687,11 @@ private bool CanIgnore(in TypeIdentity type, ConfigurationSource configurationSo
{
foreach (var foreignKey in entityType.GetDeclaredReferencingForeignKeys().ToList())
{
+ if (!foreignKey.IsInModel)
+ {
+ continue;
+ }
+
if (foreignKey.IsOwnership
&& configurationSource.Overrides(foreignKey.DeclaringEntityType.GetConfigurationSource()))
{
diff --git a/src/EFCore/Metadata/Internal/InternalTypeBaseBuilder.cs b/src/EFCore/Metadata/Internal/InternalTypeBaseBuilder.cs
index 2183bbce984..0e889e243f4 100644
--- a/src/EFCore/Metadata/Internal/InternalTypeBaseBuilder.cs
+++ b/src/EFCore/Metadata/Internal/InternalTypeBaseBuilder.cs
@@ -774,7 +774,7 @@ public virtual void RemoveMembersInHierarchy(string propertyName, ConfigurationS
{
if (conflictingProperty.GetConfigurationSource() != ConfigurationSource.Explicit)
{
- conflictingProperty.DeclaringType.RemoveProperty(conflictingProperty);
+ conflictingProperty.DeclaringType.Builder.RemoveProperty(conflictingProperty, configurationSource);
}
}
diff --git a/src/Microsoft.Data.Sqlite.Core/Microsoft.Data.Sqlite.Core.csproj b/src/Microsoft.Data.Sqlite.Core/Microsoft.Data.Sqlite.Core.csproj
index dffe87f8b55..30212d7d239 100644
--- a/src/Microsoft.Data.Sqlite.Core/Microsoft.Data.Sqlite.Core.csproj
+++ b/src/Microsoft.Data.Sqlite.Core/Microsoft.Data.Sqlite.Core.csproj
@@ -40,7 +40,7 @@ Microsoft.Data.Sqlite.SqliteTransaction
-
+
diff --git a/src/Microsoft.Data.Sqlite/Microsoft.Data.Sqlite.csproj b/src/Microsoft.Data.Sqlite/Microsoft.Data.Sqlite.csproj
index 985d0a28c80..90b848797e7 100644
--- a/src/Microsoft.Data.Sqlite/Microsoft.Data.Sqlite.csproj
+++ b/src/Microsoft.Data.Sqlite/Microsoft.Data.Sqlite.csproj
@@ -24,7 +24,7 @@ Microsoft.Data.Sqlite.SqliteTransaction
-
+
diff --git a/src/ef/ef.csproj b/src/ef/ef.csproj
index 2e08b452408..36f668682e5 100644
--- a/src/ef/ef.csproj
+++ b/src/ef/ef.csproj
@@ -29,6 +29,11 @@
+
+
+
+
+
diff --git a/test/Directory.Packages.props b/test/Directory.Packages.props
new file mode 100644
index 00000000000..aa5a1eb3f5a
--- /dev/null
+++ b/test/Directory.Packages.props
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/EFCore.Analyzers.Tests/EFCore.Analyzers.Tests.csproj b/test/EFCore.Analyzers.Tests/EFCore.Analyzers.Tests.csproj
index d6d3557f289..2c3875c95d3 100644
--- a/test/EFCore.Analyzers.Tests/EFCore.Analyzers.Tests.csproj
+++ b/test/EFCore.Analyzers.Tests/EFCore.Analyzers.Tests.csproj
@@ -39,13 +39,16 @@
-
-
-
-
+
+
+
+
+
+
+
diff --git a/test/EFCore.Analyzers.Tests/TestUtilities/CSharpAnalyzerVerifier.cs b/test/EFCore.Analyzers.Tests/TestUtilities/CSharpAnalyzerVerifier.cs
index 0bc003b1ae3..2f5ee948477 100644
--- a/test/EFCore.Analyzers.Tests/TestUtilities/CSharpAnalyzerVerifier.cs
+++ b/test/EFCore.Analyzers.Tests/TestUtilities/CSharpAnalyzerVerifier.cs
@@ -18,7 +18,9 @@ public static class CSharpAnalyzerVerifier
where TAnalyzer : DiagnosticAnalyzer, new()
{
public static DiagnosticResult Diagnostic(string diagnosticId)
+#pragma warning disable CS0618 // Type or member is obsolete
=> CSharpAnalyzerVerifier.Diagnostic(diagnosticId);
+#pragma warning restore CS0618 // Type or member is obsolete
public static Task VerifyAnalyzerAsync(string source, params DiagnosticResult[] expected)
{
@@ -27,7 +29,9 @@ public static Task VerifyAnalyzerAsync(string source, params DiagnosticResult[]
return test.RunAsync();
}
+#pragma warning disable CS0618 // Type or member is obsolete
public class Test : CSharpAnalyzerTest
+#pragma warning restore CS0618 // Type or member is obsolete
{
protected override CompilationOptions CreateCompilationOptions()
{
diff --git a/test/EFCore.Analyzers.Tests/TestUtilities/CSharpCodeFixVerifier.cs b/test/EFCore.Analyzers.Tests/TestUtilities/CSharpCodeFixVerifier.cs
index 1f859e69de8..5354b86e3d3 100644
--- a/test/EFCore.Analyzers.Tests/TestUtilities/CSharpCodeFixVerifier.cs
+++ b/test/EFCore.Analyzers.Tests/TestUtilities/CSharpCodeFixVerifier.cs
@@ -18,7 +18,9 @@ public static class CSharpCodeFixVerifier
where TCodeFix : CodeFixProvider, new()
{
public static DiagnosticResult Diagnostic(string diagnosticId)
+#pragma warning disable CS0618 // Type or member is obsolete
=> CSharpAnalyzerVerifier.Diagnostic(diagnosticId);
+#pragma warning restore CS0618 // Type or member is obsolete
public static Task VerifyAnalyzerAsync(string source, params DiagnosticResult[] expected)
{
@@ -34,7 +36,9 @@ public static async Task VerifyCodeFixAsync(string source, string fixedSource)
await test.RunAsync();
}
+#pragma warning disable CS0618 // Type or member is obsolete
public class Test : CSharpCodeFixTest
+#pragma warning restore CS0618 // Type or member is obsolete
{
protected override async Task CreateProjectImplAsync(
EvaluatedProjectState primaryProject,
diff --git a/test/EFCore.AspNet.InMemory.FunctionalTests/EFCore.AspNet.InMemory.FunctionalTests.csproj b/test/EFCore.AspNet.InMemory.FunctionalTests/EFCore.AspNet.InMemory.FunctionalTests.csproj
index 3774b870241..abffdd03822 100644
--- a/test/EFCore.AspNet.InMemory.FunctionalTests/EFCore.AspNet.InMemory.FunctionalTests.csproj
+++ b/test/EFCore.AspNet.InMemory.FunctionalTests/EFCore.AspNet.InMemory.FunctionalTests.csproj
@@ -45,6 +45,8 @@
+
+
diff --git a/test/EFCore.AspNet.Specification.Tests/EFCore.AspNet.Specification.Tests.csproj b/test/EFCore.AspNet.Specification.Tests/EFCore.AspNet.Specification.Tests.csproj
index 3c5cb9b150a..3ea53b38ea8 100644
--- a/test/EFCore.AspNet.Specification.Tests/EFCore.AspNet.Specification.Tests.csproj
+++ b/test/EFCore.AspNet.Specification.Tests/EFCore.AspNet.Specification.Tests.csproj
@@ -50,9 +50,11 @@
-
-
-
+
+
+
+
+
diff --git a/test/EFCore.AspNet.SqlServer.FunctionalTests/EFCore.AspNet.SqlServer.FunctionalTests.csproj b/test/EFCore.AspNet.SqlServer.FunctionalTests/EFCore.AspNet.SqlServer.FunctionalTests.csproj
index ed3086b264d..9a527a88ac1 100644
--- a/test/EFCore.AspNet.SqlServer.FunctionalTests/EFCore.AspNet.SqlServer.FunctionalTests.csproj
+++ b/test/EFCore.AspNet.SqlServer.FunctionalTests/EFCore.AspNet.SqlServer.FunctionalTests.csproj
@@ -50,6 +50,8 @@
+
+
diff --git a/test/EFCore.AspNet.Sqlite.FunctionalTests/EFCore.AspNet.Sqlite.FunctionalTests.csproj b/test/EFCore.AspNet.Sqlite.FunctionalTests/EFCore.AspNet.Sqlite.FunctionalTests.csproj
index 5838fe849ea..9c670219fb4 100644
--- a/test/EFCore.AspNet.Sqlite.FunctionalTests/EFCore.AspNet.Sqlite.FunctionalTests.csproj
+++ b/test/EFCore.AspNet.Sqlite.FunctionalTests/EFCore.AspNet.Sqlite.FunctionalTests.csproj
@@ -49,6 +49,8 @@
+
+
diff --git a/test/EFCore.Cosmos.FunctionalTests/EFCore.Cosmos.FunctionalTests.csproj b/test/EFCore.Cosmos.FunctionalTests/EFCore.Cosmos.FunctionalTests.csproj
index a8ecf58320d..5be9cabc700 100644
--- a/test/EFCore.Cosmos.FunctionalTests/EFCore.Cosmos.FunctionalTests.csproj
+++ b/test/EFCore.Cosmos.FunctionalTests/EFCore.Cosmos.FunctionalTests.csproj
@@ -76,10 +76,10 @@
-
-
-
-
+
+
+
+
diff --git a/test/EFCore.Cosmos.FunctionalTests/ModelBuilding/CosmosModelBuilderGenericTest.cs b/test/EFCore.Cosmos.FunctionalTests/ModelBuilding/CosmosModelBuilderGenericTest.cs
index 4d8994ef478..0865ab00f6d 100644
--- a/test/EFCore.Cosmos.FunctionalTests/ModelBuilding/CosmosModelBuilderGenericTest.cs
+++ b/test/EFCore.Cosmos.FunctionalTests/ModelBuilding/CosmosModelBuilderGenericTest.cs
@@ -855,6 +855,47 @@ public override void Navigation_to_shared_type_is_not_discovered_by_convention()
owned.DisplayName());
}
+ [ConditionalFact] // Issue #34329
+ public virtual void Navigation_cycle_can_be_broken()
+ {
+ var modelBuilder = CreateModelBuilder();
+
+ modelBuilder.Entity().Ignore(x => x.E2);
+
+ var model = modelBuilder.FinalizeModel();
+
+ var principal = model.FindEntityType(typeof(EntityType1))!;
+ Assert.Null(principal.FindNavigation(nameof(EntityType1.E2)));
+ Assert.Null(model.FindEntityType(typeof(EntityType2)));
+ }
+
+ protected class EntityType1
+ {
+ public int Id { get; set; }
+ public EntityType2? E2 { get; set; }
+ }
+
+
+ protected class EntityType2
+ {
+ public int Id { get; set; }
+ public EntityType3? E3 { get; set; }
+
+ public EntityType4? E4 { get; set; }
+ }
+
+ protected class EntityType3
+ {
+ public int Id { get; set; }
+ public EntityType2? U2 { get; set; }
+ }
+
+ protected class EntityType4
+ {
+ public int Id { get; set; }
+ public EntityType3? E3 { get; set; }
+ }
+
protected override TestModelBuilder CreateModelBuilder(Action? configure = null)
=> new GenericTestModelBuilder(Fixture, configure);
}
@@ -1210,28 +1251,20 @@ public virtual void Reference_type_is_discovered_as_owned()
{
var modelBuilder = CreateModelBuilder();
- modelBuilder.Entity(
- e =>
- {
- e.Property(p => p.Id);
- e.Property(p => p.AlternateKey);
- e.Property(p => p.Description);
- e.HasKey(p => p.Id);
- });
+ modelBuilder.Entity();
var model = modelBuilder.FinalizeModel();
- var owner = model.FindEntityType(typeof(OneToOneOwnerWithField))!;
- Assert.Equal(typeof(OneToOneOwnerWithField).FullName, owner.Name);
- var ownership = owner.FindNavigation(nameof(OneToOneOwnerWithField.OwnedDependent))!.ForeignKey;
+ var owner = model.FindEntityType(typeof(OwnerOfOwnees))!;
+ var ownership = owner.FindNavigation(nameof(OwnerOfOwnees.Ownee1))!.ForeignKey;
Assert.True(ownership.IsOwnership);
- Assert.Equal(nameof(OneToOneOwnerWithField.OwnedDependent), ownership.PrincipalToDependent!.Name);
- Assert.Equal(nameof(OneToOneOwnedWithField.OneToOneOwner), ownership.DependentToPrincipal!.Name);
- Assert.Equal(nameof(OneToOneOwnerWithField.Id), ownership.PrincipalKey.Properties.Single().Name);
+ Assert.Equal(nameof(OwnerOfOwnees.Ownee1), ownership.PrincipalToDependent!.Name);
+ Assert.Equal(nameof(Ownee1.Owner), ownership.DependentToPrincipal!.Name);
+ Assert.Equal(nameof(OwnerOfOwnees.Id), ownership.PrincipalKey.Properties.Single().Name);
var owned = ownership.DeclaringEntityType;
Assert.Single(owned.GetForeignKeys());
- Assert.NotNull(model.FindEntityType(typeof(OneToOneOwnedWithField)));
- Assert.Equal(1, model.GetEntityTypes().Count(e => e.ClrType == typeof(OneToOneOwnedWithField)));
+ Assert.NotNull(model.FindEntityType(typeof(Ownee1)));
+ Assert.Equal(1, model.GetEntityTypes().Count(e => e.ClrType == typeof(Ownee1)));
}
protected override TestModelBuilder CreateModelBuilder(Action? configure = null)
diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/PrimitiveCollectionsQueryCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/PrimitiveCollectionsQueryCosmosTest.cs
index 587b9d29fe4..78dd12d771c 100644
--- a/test/EFCore.Cosmos.FunctionalTests/Query/PrimitiveCollectionsQueryCosmosTest.cs
+++ b/test/EFCore.Cosmos.FunctionalTests/Query/PrimitiveCollectionsQueryCosmosTest.cs
@@ -1537,6 +1537,27 @@ FROM root c
""");
});
+ public override async Task Parameter_collection_with_type_inference_for_JsonScalarExpression(bool async)
+ {
+ // Always throws for sync.
+ if (async)
+ {
+ // Member indexer (c.Array[c.SomeMember]) isn't supported by Cosmos
+ var exception = await Assert.ThrowsAsync(
+ () => base.Parameter_collection_with_type_inference_for_JsonScalarExpression(async));
+
+ Assert.Equal(HttpStatusCode.BadRequest, exception.StatusCode);
+
+ AssertSql(
+ """
+@__values_0='["one","two"]'
+
+SELECT VALUE ((c["Id"] != 0) ? @__values_0[(c["Int"] % 2)] : "foo")
+FROM root c
+""");
+ }
+ }
+
public override Task Column_collection_Union_parameter_collection(bool async)
=> CosmosTestHelpers.Instance.NoSyncTest(
async, async a =>
diff --git a/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosTestStore.cs b/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosTestStore.cs
index 79ebcaeb66a..c889a991c64 100644
--- a/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosTestStore.cs
+++ b/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosTestStore.cs
@@ -172,7 +172,15 @@ private async Task CreateFromFile(DbContext context)
{
if (await EnsureCreatedAsync(context).ConfigureAwait(false))
{
- await context.Database.EnsureCreatedAsync().ConfigureAwait(false);
+ if (!TestEnvironment.UseTokenCredential)
+ {
+ await context.Database.EnsureCreatedAsync().ConfigureAwait(false);
+ }
+ else
+ {
+ await CreateContainersAsync(context).ConfigureAwait(false);
+ }
+
var cosmosClient = context.GetService();
var serializer = CosmosClientWrapper.Serializer;
using var fs = new FileStream(_dataFilePath!, FileMode.Open, FileAccess.Read);
@@ -253,7 +261,7 @@ public async Task EnsureCreatedAsync(DbContext context, CancellationToken
var databaseAccount = await GetDBAccount(cancellationToken).ConfigureAwait(false);
var collection = databaseAccount.Value.GetCosmosDBSqlDatabases();
- var sqlDatabaseCreateUpdateOptions = new CosmosDBSqlDatabaseCreateOrUpdateContent(
+ var sqlDatabaseCreateUpdateContent = new CosmosDBSqlDatabaseCreateOrUpdateContent(
TestEnvironment.AzureLocation,
new CosmosDBSqlDatabaseResourceInfo(Name));
if (await collection.ExistsAsync(Name, cancellationToken))
@@ -261,9 +269,28 @@ public async Task EnsureCreatedAsync(DbContext context, CancellationToken
return false;
}
- var databaseResponse = (await collection.CreateOrUpdateAsync(
- WaitUntil.Completed, Name, sqlDatabaseCreateUpdateOptions, cancellationToken).ConfigureAwait(false)).GetRawResponse();
- return databaseResponse.Status == (int)HttpStatusCode.OK;
+ var model = context.GetService().Model;
+
+ var modelThrouput = model.GetThroughput();
+ if (modelThrouput == null
+ && GetContainersToCreate(model).All(c => c.Throughput == null))
+ {
+ modelThrouput = ThroughputProperties.CreateManualThroughput(400);
+ }
+
+ if (modelThrouput != null)
+ {
+ sqlDatabaseCreateUpdateContent.Options = new CosmosDBCreateUpdateConfig
+ {
+ Throughput = modelThrouput.Throughput,
+ AutoscaleMaxThroughput = modelThrouput.AutoscaleMaxThroughput
+ };
+ }
+
+ var databaseResponse = await collection.CreateOrUpdateAsync(
+ WaitUntil.Completed, Name, sqlDatabaseCreateUpdateContent, cancellationToken).ConfigureAwait(false);
+
+ return databaseResponse.GetRawResponse().Status == (int)HttpStatusCode.OK;
}
private async Task EnsureDeletedAsync(DbContext context, CancellationToken cancellationToken = default)
@@ -362,8 +389,11 @@ private async Task CreateContainersAsync(DbContext context)
var content = new CosmosDBSqlContainerCreateOrUpdateContent(TestEnvironment.AzureLocation, resource);
if (container.Throughput != null)
{
- content.Options.AutoscaleMaxThroughput = container.Throughput.AutoscaleMaxThroughput;
- content.Options.Throughput = container.Throughput.Throughput;
+ content.Options = new CosmosDBCreateUpdateConfig
+ {
+ AutoscaleMaxThroughput = container.Throughput.AutoscaleMaxThroughput,
+ Throughput = container.Throughput.Throughput
+ };
}
await database.Value.GetCosmosDBSqlContainers().CreateOrUpdateAsync(
diff --git a/test/EFCore.Design.Tests/EFCore.Design.Tests.csproj b/test/EFCore.Design.Tests/EFCore.Design.Tests.csproj
index 1123621c531..9d4ed03c0fe 100644
--- a/test/EFCore.Design.Tests/EFCore.Design.Tests.csproj
+++ b/test/EFCore.Design.Tests/EFCore.Design.Tests.csproj
@@ -56,9 +56,8 @@
-
-
-
+
+
diff --git a/test/EFCore.FSharp.FunctionalTests/EFCore.FSharp.FunctionalTests.fsproj b/test/EFCore.FSharp.FunctionalTests/EFCore.FSharp.FunctionalTests.fsproj
index 4d158d20380..edc4e73d6a3 100644
--- a/test/EFCore.FSharp.FunctionalTests/EFCore.FSharp.FunctionalTests.fsproj
+++ b/test/EFCore.FSharp.FunctionalTests/EFCore.FSharp.FunctionalTests.fsproj
@@ -4,7 +4,7 @@
Microsoft.EntityFrameworkCore
$(DefaultNetCoreTargetFramework)
Microsoft.EntityFrameworkCore.FSharp.FunctionalTests
- True
+ True
latest
@@ -13,8 +13,9 @@
-
-
+
+
+
diff --git a/test/EFCore.NativeAotTests/EFCore.NativeAotTests.csproj b/test/EFCore.NativeAotTests/EFCore.NativeAotTests.csproj
index 8ec6cbe0126..fe0f037d78e 100644
--- a/test/EFCore.NativeAotTests/EFCore.NativeAotTests.csproj
+++ b/test/EFCore.NativeAotTests/EFCore.NativeAotTests.csproj
@@ -17,9 +17,9 @@
-
-
-
+
+
+
diff --git a/test/EFCore.OData.FunctionalTests/EFCore.OData.FunctionalTests.csproj b/test/EFCore.OData.FunctionalTests/EFCore.OData.FunctionalTests.csproj
index 56e314a4657..1778dd946d9 100644
--- a/test/EFCore.OData.FunctionalTests/EFCore.OData.FunctionalTests.csproj
+++ b/test/EFCore.OData.FunctionalTests/EFCore.OData.FunctionalTests.csproj
@@ -42,7 +42,7 @@
-
+
diff --git a/test/EFCore.Relational.Specification.Tests/EFCore.Relational.Specification.Tests.csproj b/test/EFCore.Relational.Specification.Tests/EFCore.Relational.Specification.Tests.csproj
index 94f59331dcb..d88c0787094 100644
--- a/test/EFCore.Relational.Specification.Tests/EFCore.Relational.Specification.Tests.csproj
+++ b/test/EFCore.Relational.Specification.Tests/EFCore.Relational.Specification.Tests.csproj
@@ -49,10 +49,7 @@
-
-
-
-
+
diff --git a/test/EFCore.Relational.Specification.Tests/Update/UpdatesRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Update/UpdatesRelationalTestBase.cs
index 453ea766d0d..666e030a6a1 100644
--- a/test/EFCore.Relational.Specification.Tests/Update/UpdatesRelationalTestBase.cs
+++ b/test/EFCore.Relational.Specification.Tests/Update/UpdatesRelationalTestBase.cs
@@ -175,6 +175,43 @@ public virtual Task Swap_filtered_unique_index_values()
});
}
+ [ConditionalFact] // Issue #33023
+ public virtual Task Swap_computed_unique_index_values()
+ {
+ var productId1 = new Guid("984ade3c-2f7b-4651-a351-642e92ab7146");
+ var productId2 = new Guid("0edc9136-7eed-463b-9b97-bdb9648ab877");
+
+ return ExecuteWithStrategyInTransactionAsync(
+ async context =>
+ {
+ var product1 = (await context.Products.FindAsync(productId1))!;
+ var product2 = (await context.Products.FindAsync(productId2))!;
+
+ product1.IsPrimary = false;
+ product2.Name = product1.Name;
+ product2.IsPrimary = true;
+
+ await context.SaveChangesAsync();
+ }, async context =>
+ {
+ var product1 = (await context.Products.FindAsync(productId1))!;
+ var product2 = (await context.Products.FindAsync(productId2))!;
+
+ product1.Name = "Apple Cobler";
+ product1.IsPrimary = true;
+ product2.IsPrimary = false;
+
+ await context.SaveChangesAsync();
+ }, async context =>
+ {
+ var product1 = (await context.Products.FindAsync(productId1))!;
+ var product2 = (await context.Products.FindAsync(productId2))!;
+
+ Assert.True(product1.IsPrimary);
+ Assert.False(product2.IsPrimary);
+ });
+ }
+
[ConditionalFact]
public virtual Task Update_non_indexed_values()
{
@@ -197,13 +234,15 @@ public virtual Task Update_non_indexed_values()
{
Id = productId1,
Name = "",
- Price = 1.49M
+ Price = 1.49M,
+ IsPrimary = true
};
var product2 = new Product
{
Id = productId2,
Name = "",
- Price = 1.49M
+ Price = 1.49M,
+ IsPrimary = false
};
context.Attach(product1).Property(p => p.DependentId).IsModified = true;
diff --git a/test/EFCore.Relational.Tests/EFCore.Relational.Tests.csproj b/test/EFCore.Relational.Tests/EFCore.Relational.Tests.csproj
index 3d389319bed..2c14c5d40b9 100644
--- a/test/EFCore.Relational.Tests/EFCore.Relational.Tests.csproj
+++ b/test/EFCore.Relational.Tests/EFCore.Relational.Tests.csproj
@@ -46,7 +46,7 @@
-
+
diff --git a/test/EFCore.Specification.Tests/Directory.Packages.props b/test/EFCore.Specification.Tests/Directory.Packages.props
new file mode 100644
index 00000000000..c779d47c5be
--- /dev/null
+++ b/test/EFCore.Specification.Tests/Directory.Packages.props
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/EFCore.Specification.Tests/EFCore.Specification.Tests.csproj b/test/EFCore.Specification.Tests/EFCore.Specification.Tests.csproj
index dd337cdf607..43c4f24085a 100644
--- a/test/EFCore.Specification.Tests/EFCore.Specification.Tests.csproj
+++ b/test/EFCore.Specification.Tests/EFCore.Specification.Tests.csproj
@@ -56,12 +56,13 @@
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.OwnedTypes.cs b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.OwnedTypes.cs
index c1a251a6471..e8371d55489 100644
--- a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.OwnedTypes.cs
+++ b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.OwnedTypes.cs
@@ -599,6 +599,12 @@ public virtual void Can_call_Owner_fluent_api_after_calling_Entity()
modelBuilder.Owned();
modelBuilder.Owned();
modelBuilder.Owned();
+
+ var model = modelBuilder.FinalizeModel();
+
+ var owner = model.FindEntityType(typeof(OwnerOfOwnees))!;
+ var ownership = owner.FindNavigation(nameof(OwnerOfOwnees.Ownee1))!.ForeignKey;
+ Assert.True(ownership.IsOwnership);
}
[Flags]
diff --git a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.TestModel.cs b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.TestModel.cs
index 7bfb5484941..1af3de98e34 100644
--- a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.TestModel.cs
+++ b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.TestModel.cs
@@ -1112,16 +1112,23 @@ protected class OwnerOfOwnees
protected class Ownee1
{
+ public string Data { get; private set; } = "";
+
+ public OwnerOfOwnees Owner { get; private set; } = null!;
public Ownee3? NewOwnee3 { get; private set; }
}
protected class Ownee2
{
+ public Guid Data { get; private set; }
+
public Ownee3? Ownee3 { get; private set; }
}
protected class Ownee3
{
+ public DateTime Data { get; private set; }
+
public string? Name { get; private set; }
}
@@ -1189,6 +1196,7 @@ protected class OneToManyOwnedWithField
public OneToManyOwnerWithField? OneToManyOwner { get; set; }
}
+ [Index(nameof(OwnedDependent))]
protected class OneToOneOwnerWithField
{
public int Id;
diff --git a/test/EFCore.Specification.Tests/Query/PrimitiveCollectionsQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/PrimitiveCollectionsQueryTestBase.cs
index 7de363ee184..2304ac3db4c 100644
--- a/test/EFCore.Specification.Tests/Query/PrimitiveCollectionsQueryTestBase.cs
+++ b/test/EFCore.Specification.Tests/Query/PrimitiveCollectionsQueryTestBase.cs
@@ -925,13 +925,24 @@ public virtual Task Inline_collection_Join_ordered_column_collection(bool async)
[MemberData(nameof(IsAsyncData))]
public virtual Task Parameter_collection_Concat_column_collection(bool async)
{
- var ints = new[] { 11, 111 };
+ int[] ints = [11, 111];
return AssertQuery(
async,
ss => ss.Set().Where(c => ints.Concat(c.Ints).Count() == 2));
}
+ [ConditionalTheory] // #33582
+ [MemberData(nameof(IsAsyncData))]
+ public virtual Task Parameter_collection_with_type_inference_for_JsonScalarExpression(bool async)
+ {
+ string[] values = ["one", "two"];
+
+ return AssertQuery(
+ async,
+ ss => ss.Set().Select(c => c.Id != 0 ? values[c.Int % 2] : "foo"));
+ }
+
[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Column_collection_Union_parameter_collection(bool async)
@@ -1557,8 +1568,8 @@ private static IReadOnlyList CreatePrimitiveArrayEnt
DateTimes = [],
Bools = [],
Enums = [],
- NullableInts = Array.Empty(),
- NullableStrings = Array.Empty()
+ NullableInts = [],
+ NullableStrings = []
}
};
}
diff --git a/test/EFCore.Specification.Tests/TestModels/UpdatesModel/Product.cs b/test/EFCore.Specification.Tests/TestModels/UpdatesModel/Product.cs
index b3bd807684b..352432bee78 100644
--- a/test/EFCore.Specification.Tests/TestModels/UpdatesModel/Product.cs
+++ b/test/EFCore.Specification.Tests/TestModels/UpdatesModel/Product.cs
@@ -17,5 +17,9 @@ public class Product : ProductBase
[ConcurrencyCheck]
public decimal Price { get; set; }
+ public bool IsPrimary { get; set; }
+
+ public bool? IsPrimaryNormalized { get => IsPrimary ? true : null; set { } }
+
public ICollection ProductCategories { get; set; } = null!;
}
diff --git a/test/EFCore.Specification.Tests/TestModels/UpdatesModel/UpdatesContext.cs b/test/EFCore.Specification.Tests/TestModels/UpdatesModel/UpdatesContext.cs
index 53a54579e9b..7213ae7709c 100644
--- a/test/EFCore.Specification.Tests/TestModels/UpdatesModel/UpdatesContext.cs
+++ b/test/EFCore.Specification.Tests/TestModels/UpdatesModel/UpdatesContext.cs
@@ -29,7 +29,8 @@ public static Task SeedAsync(UpdatesContext context)
Id = productId1,
Name = "Apple Cider",
Price = 1.49M,
- DependentId = 778
+ DependentId = 778,
+ IsPrimary = true
});
context.Add(
new Product
@@ -37,7 +38,8 @@ public static Task SeedAsync(UpdatesContext context)
Id = productId2,
Name = "Apple Cobler",
Price = 2.49M,
- DependentId = 778
+ DependentId = 778,
+ IsPrimary = false
});
return context.SaveChangesAsync();
diff --git a/test/EFCore.Specification.Tests/Update/UpdatesTestBase.cs b/test/EFCore.Specification.Tests/Update/UpdatesTestBase.cs
index 6108506e568..f0c0d83e3d7 100644
--- a/test/EFCore.Specification.Tests/Update/UpdatesTestBase.cs
+++ b/test/EFCore.Specification.Tests/Update/UpdatesTestBase.cs
@@ -935,6 +935,10 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con
.HasForeignKey(e => e.DependentId)
.HasPrincipalKey(e => e.PrincipalId);
+ modelBuilder.Entity()
+ .HasIndex(e => new { e.Name, e.IsPrimaryNormalized })
+ .IsUnique();
+
modelBuilder.Entity(
pb =>
{
diff --git a/test/EFCore.SqlServer.FunctionalTests/EFCore.SqlServer.FunctionalTests.csproj b/test/EFCore.SqlServer.FunctionalTests/EFCore.SqlServer.FunctionalTests.csproj
index f2bf02bd544..d91e7e88ddf 100644
--- a/test/EFCore.SqlServer.FunctionalTests/EFCore.SqlServer.FunctionalTests.csproj
+++ b/test/EFCore.SqlServer.FunctionalTests/EFCore.SqlServer.FunctionalTests.csproj
@@ -75,7 +75,7 @@
-
-
+
+
diff --git a/test/EFCore.SqlServer.FunctionalTests/ModelBuilding/SqlServerModelBuilderTestBase.cs b/test/EFCore.SqlServer.FunctionalTests/ModelBuilding/SqlServerModelBuilderTestBase.cs
index 5f76da6288e..9b20c495e9e 100644
--- a/test/EFCore.SqlServer.FunctionalTests/ModelBuilding/SqlServerModelBuilderTestBase.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/ModelBuilding/SqlServerModelBuilderTestBase.cs
@@ -1633,8 +1633,11 @@ public virtual void Json_entity_with_nested_structure_same_property_names()
x => x.OwnedCollection2, bb =>
{
bb.ToJson("col2");
- bb.OwnsOne(x => x.Reference1);
- bb.OwnsOne(x => x.Reference2);
+ bb.OwnsOne(x => x.Reference1)
+ .HasAnnotation(RelationalAnnotationNames.JsonPropertyName, null);
+ bb.OwnsOne(x => x.Reference2)
+ .ToTable("Ref2")
+ .HasAnnotation(RelationalAnnotationNames.ContainerColumnName, null);
bb.OwnsMany(x => x.Collection1);
bb.OwnsMany(x => x.Collection2);
});
@@ -1642,36 +1645,49 @@ public virtual void Json_entity_with_nested_structure_same_property_names()
var model = modelBuilder.FinalizeModel();
var outerOwnedEntities = model.FindEntityTypes(typeof(OwnedEntityExtraLevel));
- Assert.Equal(4, outerOwnedEntities.Count());
+
+ Assert.Collection(outerOwnedEntities,
+ e => Assert.Equal("col1", e.GetContainerColumnName()),
+ e => Assert.Equal("col2", e.GetContainerColumnName()),
+ e => Assert.Equal("ref1", e.GetContainerColumnName()),
+ e => Assert.Equal("ref2", e.GetContainerColumnName()));
foreach (var outerOwnedEntity in outerOwnedEntities)
{
Assert.Equal("Date", outerOwnedEntity.GetProperty("Date").GetJsonPropertyName());
Assert.Equal("Fraction", outerOwnedEntity.GetProperty("Fraction").GetJsonPropertyName());
Assert.Equal("Enum", outerOwnedEntity.GetProperty("Enum").GetJsonPropertyName());
- Assert.Equal(
- "Reference1",
- outerOwnedEntity.GetNavigations().Single(n => n.Name == "Reference1").TargetEntityType.GetJsonPropertyName());
- Assert.Equal(
- "Reference2",
- outerOwnedEntity.GetNavigations().Single(n => n.Name == "Reference2").TargetEntityType.GetJsonPropertyName());
- Assert.Equal(
- "Collection1",
- outerOwnedEntity.GetNavigations().Single(n => n.Name == "Collection1").TargetEntityType.GetJsonPropertyName());
- Assert.Equal(
- "Collection2",
- outerOwnedEntity.GetNavigations().Single(n => n.Name == "Collection2").TargetEntityType.GetJsonPropertyName());
- }
- var ownedEntities = model.FindEntityTypes(typeof(OwnedEntity));
- Assert.Equal(16, ownedEntities.Count());
+ var nestedOwnedTypes = outerOwnedEntity.GetNavigations().Select(n => n.TargetEntityType).ToList();
+ Assert.Collection(nestedOwnedTypes,
+ e => Assert.Equal("Collection1", e.GetJsonPropertyName()),
+ e => Assert.Equal("Collection2", e.GetJsonPropertyName()),
+ e => Assert.Equal(outerOwnedEntity.GetContainerColumnName() == "col2" ? null : "Reference1",
+ e.GetJsonPropertyName()),
+ e => Assert.Equal(outerOwnedEntity.GetContainerColumnName() == "col2" ? null : "Reference2",
+ e.GetJsonPropertyName()));
+
+ Assert.Collection(nestedOwnedTypes,
+ e => Assert.Equal(outerOwnedEntity.GetContainerColumnName(), e.GetContainerColumnName()),
+ e => Assert.Equal(outerOwnedEntity.GetContainerColumnName(), e.GetContainerColumnName()),
+ e => Assert.Equal(outerOwnedEntity.GetContainerColumnName(), e.GetContainerColumnName()),
+ e => Assert.Equal(outerOwnedEntity.GetContainerColumnName() == "col2" ?
+ null : outerOwnedEntity.GetContainerColumnName(), e.GetContainerColumnName()));
+
+ foreach (var ownedEntity in nestedOwnedTypes)
+ {
+ if (ownedEntity.GetContainerColumnName() == null)
+ {
+ continue;
+ }
- foreach (var ownedEntity in ownedEntities)
- {
- Assert.Equal("Date", ownedEntity.GetProperty("Date").GetJsonPropertyName());
- Assert.Equal("Fraction", ownedEntity.GetProperty("Fraction").GetJsonPropertyName());
- Assert.Equal("Enum", ownedEntity.GetProperty("Enum").GetJsonPropertyName());
+ Assert.Equal("Date", ownedEntity.GetProperty("Date").GetJsonPropertyName());
+ Assert.Equal("Fraction", ownedEntity.GetProperty("Fraction").GetJsonPropertyName());
+ Assert.Equal("Enum", ownedEntity.GetProperty("Enum").GetJsonPropertyName());
+ }
}
+
+ Assert.Equal(16, model.FindEntityTypes(typeof(OwnedEntity)).Count());
}
[ConditionalFact]
@@ -2047,62 +2063,6 @@ public virtual void Json_entity_and_normal_owned_can_exist_side_to_side_on_same_
Assert.Equal(2, ownedEntities.Where(e => e.IsMappedToJson()).Count());
Assert.Equal(2, ownedEntities.Where(e => e.IsOwned() && !e.IsMappedToJson()).Count());
}
-
- [ConditionalFact]
- public virtual void Json_entity_with_nested_structure_same_property_names_()
- {
- var modelBuilder = CreateModelBuilder();
- modelBuilder.Entity(
- b =>
- {
- b.OwnsOne(
- x => x.OwnedReference1, bb =>
- {
- bb.ToJson("ref1");
- bb.OwnsOne(x => x.Reference1);
- bb.OwnsOne(x => x.Reference2);
- bb.OwnsMany(x => x.Collection1);
- bb.OwnsMany(x => x.Collection2);
- });
-
- b.OwnsOne(
- x => x.OwnedReference2, bb =>
- {
- bb.ToJson("ref2");
- bb.OwnsOne(x => x.Reference1);
- bb.OwnsOne(x => x.Reference2);
- bb.OwnsMany(x => x.Collection1);
- bb.OwnsMany(x => x.Collection2);
- });
-
- b.OwnsMany(
- x => x.OwnedCollection1, bb =>
- {
- bb.ToJson("col1");
- bb.OwnsOne(x => x.Reference1);
- bb.OwnsOne(x => x.Reference2);
- bb.OwnsMany(x => x.Collection1);
- bb.OwnsMany(x => x.Collection2);
- });
-
- b.OwnsMany(
- x => x.OwnedCollection2, bb =>
- {
- bb.ToJson("col2");
- bb.OwnsOne(x => x.Reference1);
- bb.OwnsOne(x => x.Reference2);
- bb.OwnsMany(x => x.Collection1);
- bb.OwnsMany(x => x.Collection2);
- });
- });
-
- var model = modelBuilder.FinalizeModel();
- var outerOwnedEntities = model.FindEntityTypes(typeof(OwnedEntityExtraLevel));
- Assert.Equal(4, outerOwnedEntities.Count());
-
- var ownedEntities = model.FindEntityTypes(typeof(OwnedEntity));
- Assert.Equal(16, ownedEntities.Count());
- }
}
public class SqlServerModelBuilderFixture : RelationalModelBuilderFixture
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQueryOldSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQueryOldSqlServerTest.cs
index c09c7a89029..d23ea73a1ce 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQueryOldSqlServerTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQueryOldSqlServerTest.cs
@@ -905,6 +905,9 @@ public override Task Inline_collection_Join_ordered_column_collection(bool async
public override Task Parameter_collection_Concat_column_collection(bool async)
=> AssertCompatibilityLevelTooLow(() => base.Parameter_collection_Concat_column_collection(async));
+ public override Task Parameter_collection_with_type_inference_for_JsonScalarExpression(bool async)
+ => AssertCompatibilityLevelTooLow(() => base.Parameter_collection_Concat_column_collection(async));
+
public override Task Column_collection_Union_parameter_collection(bool async)
=> AssertCompatibilityLevelTooLow(() => base.Column_collection_Union_parameter_collection(async));
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs
index 00a87df1eb7..a42b4ac42f7 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs
@@ -1507,6 +1507,22 @@ FROM OPENJSON([p].[Ints]) AS [i0]
""");
}
+ public override async Task Parameter_collection_with_type_inference_for_JsonScalarExpression(bool async)
+ {
+ await base.Parameter_collection_with_type_inference_for_JsonScalarExpression(async);
+
+ AssertSql(
+ """
+@__values_0='["one","two"]' (Size = 4000)
+
+SELECT CASE
+ WHEN [p].[Id] <> 0 THEN JSON_VALUE(@__values_0, '$[' + CAST([p].[Int] % 2 AS nvarchar(max)) + ']')
+ ELSE N'foo'
+END
+FROM [PrimitiveCollectionsEntity] AS [p]
+""");
+ }
+
public override async Task Column_collection_Union_parameter_collection(bool async)
{
await base.Column_collection_Union_parameter_collection(async);
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerJsonTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerJsonTypeTest.cs
index f5b0b9d9380..d382ca0642d 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerJsonTypeTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerJsonTypeTest.cs
@@ -1481,6 +1481,22 @@ FROM OPENJSON(CAST([p].[Ints] AS nvarchar(max))) AS [i0]
""");
}
+ public override async Task Parameter_collection_with_type_inference_for_JsonScalarExpression(bool async)
+ {
+ await base.Parameter_collection_with_type_inference_for_JsonScalarExpression(async);
+
+ AssertSql(
+ """
+@__values_0='["one","two"]' (Size = 4000)
+
+SELECT CASE
+ WHEN [p].[Id] <> 0 THEN JSON_VALUE(@__values_0, '$[' + CAST([p].[Int] % 2 AS nvarchar(max)) + ']')
+ ELSE N'foo'
+END
+FROM [PrimitiveCollectionsEntity] AS [p]
+""");
+ }
+
public override async Task Column_collection_Union_parameter_collection(bool async)
{
await base.Column_collection_Union_parameter_collection(async);
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs
index 330a3159cf7..de05c4c3797 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs
@@ -1530,6 +1530,23 @@ FROM OPENJSON([p].[Ints]) AS [i0]
""");
}
+ [SqlServerCondition(SqlServerCondition.SupportsJsonPathExpressions)]
+ public override async Task Parameter_collection_with_type_inference_for_JsonScalarExpression(bool async)
+ {
+ await base.Parameter_collection_with_type_inference_for_JsonScalarExpression(async);
+
+ AssertSql(
+ """
+@__values_0='["one","two"]' (Size = 4000)
+
+SELECT CASE
+ WHEN [p].[Id] <> 0 THEN JSON_VALUE(@__values_0, '$[' + CAST([p].[Int] % 2 AS nvarchar(max)) + ']')
+ ELSE N'foo'
+END
+FROM [PrimitiveCollectionsEntity] AS [p]
+""");
+ }
+
public override async Task Column_collection_Union_parameter_collection(bool async)
{
await base.Column_collection_Union_parameter_collection(async);
diff --git a/test/EFCore.SqlServer.FunctionalTests/Update/UpdatesSqlServerTPCTest.cs b/test/EFCore.SqlServer.FunctionalTests/Update/UpdatesSqlServerTPCTest.cs
index 3f02486912d..b9be9e4c23a 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Update/UpdatesSqlServerTPCTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Update/UpdatesSqlServerTPCTest.cs
@@ -51,7 +51,7 @@ FROM [SpecialCategory] AS [s]
"""
@__category_PrincipalId_0='778' (Nullable = true)
-SELECT [p].[Id], [p].[Discriminator], [p].[DependentId], [p].[Name], [p].[Price]
+SELECT [p].[Id], [p].[Discriminator], [p].[DependentId], [p].[IsPrimary], [p].[IsPrimaryNormalized], [p].[Name], [p].[Price]
FROM [ProductBase] AS [p]
WHERE [p].[Discriminator] = N'Product' AND [p].[DependentId] = @__category_PrincipalId_0
""",
@@ -81,7 +81,7 @@ FROM [SpecialCategory] AS [s]
"""
@__category_PrincipalId_0='778' (Nullable = true)
-SELECT [p].[Id], [p].[Discriminator], [p].[DependentId], [p].[Name], [p].[Price]
+SELECT [p].[Id], [p].[Discriminator], [p].[DependentId], [p].[IsPrimary], [p].[IsPrimaryNormalized], [p].[Name], [p].[Price]
FROM [ProductBase] AS [p]
WHERE [p].[Discriminator] = N'Product' AND [p].[DependentId] = @__category_PrincipalId_0
""");
diff --git a/test/EFCore.SqlServer.FunctionalTests/Update/UpdatesSqlServerTPTTest.cs b/test/EFCore.SqlServer.FunctionalTests/Update/UpdatesSqlServerTPTTest.cs
index 64f37a9b476..2ffeb1f8853 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Update/UpdatesSqlServerTPTTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Update/UpdatesSqlServerTPTTest.cs
@@ -48,7 +48,7 @@ FROM [Categories] AS [c]
"""
@__category_PrincipalId_0='778' (Nullable = true)
-SELECT [p].[Id], [p].[Discriminator], [p].[DependentId], [p].[Name], [p].[Price]
+SELECT [p].[Id], [p].[Discriminator], [p].[DependentId], [p].[IsPrimary], [p].[IsPrimaryNormalized], [p].[Name], [p].[Price]
FROM [ProductBase] AS [p]
WHERE [p].[Discriminator] = N'Product' AND [p].[DependentId] = @__category_PrincipalId_0
""",
@@ -75,7 +75,7 @@ FROM [Categories] AS [c]
"""
@__category_PrincipalId_0='778' (Nullable = true)
-SELECT [p].[Id], [p].[Discriminator], [p].[DependentId], [p].[Name], [p].[Price]
+SELECT [p].[Id], [p].[Discriminator], [p].[DependentId], [p].[IsPrimary], [p].[IsPrimaryNormalized], [p].[Name], [p].[Price]
FROM [ProductBase] AS [p]
WHERE [p].[Discriminator] = N'Product' AND [p].[DependentId] = @__category_PrincipalId_0
""");
diff --git a/test/EFCore.SqlServer.FunctionalTests/Update/UpdatesSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Update/UpdatesSqlServerTest.cs
index f98cae5f0b6..37cdb66be00 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Update/UpdatesSqlServerTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Update/UpdatesSqlServerTest.cs
@@ -44,7 +44,7 @@ FROM [Categories] AS [c]
"""
@__category_PrincipalId_0='778' (Nullable = true)
-SELECT [p].[Id], [p].[Discriminator], [p].[DependentId], [p].[Name], [p].[Price]
+SELECT [p].[Id], [p].[Discriminator], [p].[DependentId], [p].[IsPrimary], [p].[IsPrimaryNormalized], [p].[Name], [p].[Price]
FROM [ProductBase] AS [p]
WHERE [p].[Discriminator] = N'Product' AND [p].[DependentId] = @__category_PrincipalId_0
""",
@@ -68,7 +68,7 @@ FROM [Categories] AS [c]
"""
@__category_PrincipalId_0='778' (Nullable = true)
-SELECT [p].[Id], [p].[Discriminator], [p].[DependentId], [p].[Name], [p].[Price]
+SELECT [p].[Id], [p].[Discriminator], [p].[DependentId], [p].[IsPrimary], [p].[IsPrimaryNormalized], [p].[Name], [p].[Price]
FROM [ProductBase] AS [p]
WHERE [p].[Discriminator] = N'Product' AND [p].[DependentId] = @__category_PrincipalId_0
""");
diff --git a/test/EFCore.SqlServer.FunctionalTests/Update/UpdatesSqlServerTestBase.cs b/test/EFCore.SqlServer.FunctionalTests/Update/UpdatesSqlServerTestBase.cs
index 14ab500ba54..1232f975744 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Update/UpdatesSqlServerTestBase.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Update/UpdatesSqlServerTestBase.cs
@@ -258,6 +258,15 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con
.Property(p => p.Id).HasDefaultValueSql("NEWID()");
modelBuilder.Entity().HasIndex(p => new { p.Name, p.Price }).HasFilter("Name IS NOT NULL");
+
+ modelBuilder.Entity()
+ .HasIndex(e => new { e.Name, e.IsPrimaryNormalized })
+ .IsUnique()
+ .HasFilter(null);
+
+ modelBuilder.Entity()
+ .Property(e => e.IsPrimaryNormalized)
+ .HasComputedColumnSql($"IIF(IsPrimary = 1, CONVERT(bit, 1), NULL)", stored: true);
}
public virtual async Task ResetIdentity()
diff --git a/test/EFCore.Sqlite.FunctionalTests/EFCore.Sqlite.FunctionalTests.csproj b/test/EFCore.Sqlite.FunctionalTests/EFCore.Sqlite.FunctionalTests.csproj
index 83e856f4a05..1279a7b59b3 100644
--- a/test/EFCore.Sqlite.FunctionalTests/EFCore.Sqlite.FunctionalTests.csproj
+++ b/test/EFCore.Sqlite.FunctionalTests/EFCore.Sqlite.FunctionalTests.csproj
@@ -65,7 +65,7 @@
-
+
diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs
index 00fe2e3436a..ce27814d118 100644
--- a/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs
+++ b/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs
@@ -1489,6 +1489,22 @@ FROM json_each("p"."Ints") AS "i0"
""");
}
+ public override async Task Parameter_collection_with_type_inference_for_JsonScalarExpression(bool async)
+ {
+ await base.Parameter_collection_with_type_inference_for_JsonScalarExpression(async);
+
+ AssertSql(
+ """
+@__values_0='["one","two"]' (Size = 13)
+
+SELECT CASE
+ WHEN "p"."Id" <> 0 THEN @__values_0 ->> ("p"."Int" % 2)
+ ELSE 'foo'
+END
+FROM "PrimitiveCollectionsEntity" AS "p"
+""");
+ }
+
public override async Task Column_collection_Union_parameter_collection(bool async)
{
await base.Column_collection_Union_parameter_collection(async);
diff --git a/test/EFCore.Tests/EFCore.Tests.csproj b/test/EFCore.Tests/EFCore.Tests.csproj
index ce9ba2dadcd..aa6260f3e87 100644
--- a/test/EFCore.Tests/EFCore.Tests.csproj
+++ b/test/EFCore.Tests/EFCore.Tests.csproj
@@ -54,7 +54,7 @@
-
+
diff --git a/test/EFCore.TrimmingTests/EFCore.TrimmingTests.csproj b/test/EFCore.TrimmingTests/EFCore.TrimmingTests.csproj
index 9717693ead9..1862142a484 100644
--- a/test/EFCore.TrimmingTests/EFCore.TrimmingTests.csproj
+++ b/test/EFCore.TrimmingTests/EFCore.TrimmingTests.csproj
@@ -16,9 +16,9 @@
-
-
-
+
+
+
diff --git a/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.Tests.csproj b/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.Tests.csproj
index c5a81c51141..4decb62d26f 100644
--- a/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.Tests.csproj
+++ b/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.Tests.csproj
@@ -11,7 +11,7 @@
-
+
diff --git a/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.e_sqlcipher.Tests.csproj b/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.e_sqlcipher.Tests.csproj
index 0bc896d750a..675c49e1c0d 100644
--- a/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.e_sqlcipher.Tests.csproj
+++ b/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.e_sqlcipher.Tests.csproj
@@ -11,7 +11,7 @@
-
+
diff --git a/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.e_sqlite3mc.Tests.csproj b/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.e_sqlite3mc.Tests.csproj
index cbc2fb8e474..5695d730aff 100644
--- a/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.e_sqlite3mc.Tests.csproj
+++ b/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.e_sqlite3mc.Tests.csproj
@@ -11,7 +11,7 @@
-
+
diff --git a/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.sqlite3.Tests.csproj b/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.sqlite3.Tests.csproj
index 2820be56a1e..c057b2cf32a 100644
--- a/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.sqlite3.Tests.csproj
+++ b/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.sqlite3.Tests.csproj
@@ -11,7 +11,7 @@
-
+
diff --git a/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.winsqlite3.Tests.csproj b/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.winsqlite3.Tests.csproj
index 581fdd490c4..d5a11003545 100644
--- a/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.winsqlite3.Tests.csproj
+++ b/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.winsqlite3.Tests.csproj
@@ -11,7 +11,7 @@
-
+
diff --git a/test/ef.Tests/ef.Tests.csproj b/test/ef.Tests/ef.Tests.csproj
index a0c282eaf1f..b99b7dd7bdf 100644
--- a/test/ef.Tests/ef.Tests.csproj
+++ b/test/ef.Tests/ef.Tests.csproj
@@ -43,8 +43,7 @@
-
-
+