diff --git a/Directory.Build.props b/Directory.Build.props index 27589f30050..993806e6af3 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -55,6 +55,10 @@ $(NoWarn.Replace(';1591', '')) + + moderate + + diff --git a/azure-pipelines.yml b/azure-pipelines.yml index f0c87f45726..3270707d5cf 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -47,7 +47,9 @@ extends: parameters: featureFlags: autoBaseline: false + usePrefastVersion3: true autoEnableRoslynWithNewRuleset: false + binskimScanAllExtensions: true sdl: sourceAnalysisPool: name: $(DncEngInternalBuildPool) @@ -57,6 +59,8 @@ extends: baselineFile: $(Build.SourcesDirectory)\.config\guardian\.gdnbaselines binskim: scanOutputDirectoryOnly: true + analyzeTargetGlob: +:f|**/Microsoft.EntityFrameworkCore*.dll;+:f|**/Microsoft.Data.Sqlite*.dll;+:f|**/ef.exe;+:f|**/dotnet-ef.exe;-:f|**/shims/**/*.exe; + preReleaseVersion: '4.3.1' policheck: enabled: true tsa: @@ -155,6 +159,9 @@ extends: COMPlus_EnableWriteXorExecute: 0 displayName: Build templateContext: + sdl: + binskim: + prereleaseVersion: ' ' outputs: - output: pipelineArtifact displayName: Upload TestResults @@ -177,6 +184,9 @@ extends: - script: eng/common/cibuild.sh --configuration $(_BuildConfig) --prepareMachine $(_InternalRuntimeDownloadArgs) displayName: Build templateContext: + sdl: + binskim: + prereleaseVersion: ' ' outputs: - output: pipelineArtifact displayName: Upload TestResults diff --git a/benchmark/Directory.Build.props b/benchmark/Directory.Build.props index acb8c8be1b6..2b1c507f4c6 100644 --- a/benchmark/Directory.Build.props +++ b/benchmark/Directory.Build.props @@ -3,6 +3,7 @@ $(MSBuildThisFileDirectory)..\rulesets\EFCore.test.ruleset + false diff --git a/benchmark/EFCore.Sqlite.Benchmarks/EFCore.Sqlite.Benchmarks.csproj b/benchmark/EFCore.Sqlite.Benchmarks/EFCore.Sqlite.Benchmarks.csproj index 2eb2534dfb2..5829a05d56f 100644 --- a/benchmark/EFCore.Sqlite.Benchmarks/EFCore.Sqlite.Benchmarks.csproj +++ b/benchmark/EFCore.Sqlite.Benchmarks/EFCore.Sqlite.Benchmarks.csproj @@ -16,10 +16,6 @@ - - - - Always diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index d14a2c72bce..8a5f81e4b02 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,83 +1,83 @@ - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 893c2ebbd49952ca49e93298148af2d95a61a0a4 + fa7cdded37981a97cec9a3e233c4a6af58a91c57 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 893c2ebbd49952ca49e93298148af2d95a61a0a4 + fa7cdded37981a97cec9a3e233c4a6af58a91c57 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 893c2ebbd49952ca49e93298148af2d95a61a0a4 + fa7cdded37981a97cec9a3e233c4a6af58a91c57 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 893c2ebbd49952ca49e93298148af2d95a61a0a4 + fa7cdded37981a97cec9a3e233c4a6af58a91c57 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 893c2ebbd49952ca49e93298148af2d95a61a0a4 + fa7cdded37981a97cec9a3e233c4a6af58a91c57 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 893c2ebbd49952ca49e93298148af2d95a61a0a4 + fa7cdded37981a97cec9a3e233c4a6af58a91c57 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 893c2ebbd49952ca49e93298148af2d95a61a0a4 + fa7cdded37981a97cec9a3e233c4a6af58a91c57 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 893c2ebbd49952ca49e93298148af2d95a61a0a4 + fa7cdded37981a97cec9a3e233c4a6af58a91c57 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 893c2ebbd49952ca49e93298148af2d95a61a0a4 + fa7cdded37981a97cec9a3e233c4a6af58a91c57 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 893c2ebbd49952ca49e93298148af2d95a61a0a4 + fa7cdded37981a97cec9a3e233c4a6af58a91c57 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 893c2ebbd49952ca49e93298148af2d95a61a0a4 + fa7cdded37981a97cec9a3e233c4a6af58a91c57 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 893c2ebbd49952ca49e93298148af2d95a61a0a4 + fa7cdded37981a97cec9a3e233c4a6af58a91c57 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 893c2ebbd49952ca49e93298148af2d95a61a0a4 + fa7cdded37981a97cec9a3e233c4a6af58a91c57 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 893c2ebbd49952ca49e93298148af2d95a61a0a4 + fa7cdded37981a97cec9a3e233c4a6af58a91c57 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 893c2ebbd49952ca49e93298148af2d95a61a0a4 + fa7cdded37981a97cec9a3e233c4a6af58a91c57 - + https://github.com/dotnet/arcade - f8c9a6d12e5a3b281661924da22d7de1cc6ab27d + 0890ca08513391dafe556fb326c73c6c5c6cb329 - + https://github.com/dotnet/arcade - f8c9a6d12e5a3b281661924da22d7de1cc6ab27d + 0890ca08513391dafe556fb326c73c6c5c6cb329 - + https://github.com/dotnet/arcade - f8c9a6d12e5a3b281661924da22d7de1cc6ab27d + 0890ca08513391dafe556fb326c73c6c5c6cb329 diff --git a/eng/Versions.props b/eng/Versions.props index daef25f5ad2..aaf5ac026dc 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -1,7 +1,7 @@ - 9.0.11 - rtm + 9.0.12 + servicing False @@ -17,24 +17,24 @@ False - 9.0.9 - 9.0.9 - 9.0.9 - 9.0.9 - 9.0.9 - 9.0.9 - 9.0.9 - 9.0.9-servicing.25419.16 - 9.0.9 - 9.0.9 - 9.0.9 - 9.0.9-servicing.25419.16 - 9.0.9 - 9.0.9 - 9.0.9 + 9.0.11 + 9.0.11 + 9.0.11 + 9.0.11 + 9.0.11 + 9.0.11 + 9.0.11 + 9.0.11-servicing.25517.16 + 9.0.11 + 9.0.11 + 9.0.11 + 9.0.11-servicing.25517.16 + 9.0.11 + 9.0.11 + 9.0.11 - 9.0.0-beta.25503.3 + 9.0.0-beta.25577.5 17.8.43 diff --git a/eng/common/core-templates/job/publish-build-assets.yml b/eng/common/core-templates/job/publish-build-assets.yml index a58c8a418e8..6b5ff28cc70 100644 --- a/eng/common/core-templates/job/publish-build-assets.yml +++ b/eng/common/core-templates/job/publish-build-assets.yml @@ -145,6 +145,11 @@ jobs: PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} is1ESPipeline: ${{ parameters.is1ESPipeline }} + # Darc is targeting 8.0, so make sure it's installed + - task: UseDotNet@2 + inputs: + version: 8.0.x + - task: AzureCLI@2 displayName: Publish Using Darc inputs: diff --git a/eng/common/core-templates/job/source-build.yml b/eng/common/core-templates/job/source-build.yml index 5baedac1e03..1037ccedcb5 100644 --- a/eng/common/core-templates/job/source-build.yml +++ b/eng/common/core-templates/job/source-build.yml @@ -65,7 +65,7 @@ jobs: demands: ImageOverride -equals build.ubuntu.2004.amd64 ${{ if eq(variables['System.TeamProject'], 'internal') }}: name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore1ESPool-Svc-Internal'), False, 'NetCore1ESPool-Internal')] - image: 1es-mariner-2 + image: 1es-azurelinux-3 os: linux ${{ else }}: pool: diff --git a/eng/common/core-templates/post-build/post-build.yml b/eng/common/core-templates/post-build/post-build.yml index 2ee8bbfff54..221d1ac6de1 100644 --- a/eng/common/core-templates/post-build/post-build.yml +++ b/eng/common/core-templates/post-build/post-build.yml @@ -305,6 +305,11 @@ stages: - task: NuGetAuthenticate@1 + # Darc is targeting 8.0, so make sure it's installed + - task: UseDotNet@2 + inputs: + version: 8.0.x + - task: AzureCLI@2 displayName: Publish Using Darc inputs: diff --git a/eng/common/core-templates/steps/source-build.yml b/eng/common/core-templates/steps/source-build.yml index 0718e4ba902..7846584d2a7 100644 --- a/eng/common/core-templates/steps/source-build.yml +++ b/eng/common/core-templates/steps/source-build.yml @@ -41,7 +41,7 @@ steps: # in the default public locations. internalRuntimeDownloadArgs= if [ '$(dotnetbuilds-internal-container-read-token-base64)' != '$''(dotnetbuilds-internal-container-read-token-base64)' ]; then - internalRuntimeDownloadArgs='/p:DotNetRuntimeSourceFeed=https://dotnetbuilds.blob.core.windows.net/internal /p:DotNetRuntimeSourceFeedKey=$(dotnetbuilds-internal-container-read-token-base64) --runtimesourcefeed https://dotnetbuilds.blob.core.windows.net/internal --runtimesourcefeedkey $(dotnetbuilds-internal-container-read-token-base64)' + internalRuntimeDownloadArgs='/p:DotNetRuntimeSourceFeed=https://ci.dot.net/internal /p:DotNetRuntimeSourceFeedKey=$(dotnetbuilds-internal-container-read-token-base64) --runtimesourcefeed https://ci.dot.net/internal --runtimesourcefeedkey $(dotnetbuilds-internal-container-read-token-base64)' fi buildConfig=Release diff --git a/eng/common/cross/arm/tizen/tizen.patch b/eng/common/cross/arm/tizen/tizen.patch new file mode 100644 index 00000000000..fb12ade7250 --- /dev/null +++ b/eng/common/cross/arm/tizen/tizen.patch @@ -0,0 +1,9 @@ +diff -u -r a/usr/lib/libc.so b/usr/lib/libc.so +--- a/usr/lib/libc.so 2016-12-30 23:00:08.284951863 +0900 ++++ b/usr/lib/libc.so 2016-12-30 23:00:32.140951815 +0900 +@@ -2,4 +2,4 @@ + Use the shared library, but some functions are only in + the static library, so try that secondarily. */ + OUTPUT_FORMAT(elf32-littlearm) +-GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a AS_NEEDED ( /lib/ld-linux-armhf.so.3 ) ) ++GROUP ( libc.so.6 libc_nonshared.a AS_NEEDED ( ld-linux-armhf.so.3 ) ) diff --git a/eng/common/cross/arm64/tizen/tizen.patch b/eng/common/cross/arm64/tizen/tizen.patch new file mode 100644 index 00000000000..af7c8be0590 --- /dev/null +++ b/eng/common/cross/arm64/tizen/tizen.patch @@ -0,0 +1,9 @@ +diff -u -r a/usr/lib/libc.so b/usr/lib/libc.so +--- a/usr/lib64/libc.so 2016-12-30 23:00:08.284951863 +0900 ++++ b/usr/lib64/libc.so 2016-12-30 23:00:32.140951815 +0900 +@@ -2,4 +2,4 @@ + Use the shared library, but some functions are only in + the static library, so try that secondarily. */ + OUTPUT_FORMAT(elf64-littleaarch64) +-GROUP ( /lib64/libc.so.6 /usr/lib64/libc_nonshared.a AS_NEEDED ( /lib/ld-linux-aarch64.so.1 ) ) ++GROUP ( libc.so.6 libc_nonshared.a AS_NEEDED ( ld-linux-aarch64.so.1 ) ) diff --git a/eng/common/cross/x64/tizen/tizen.patch b/eng/common/cross/x64/tizen/tizen.patch new file mode 100644 index 00000000000..56fbc881095 --- /dev/null +++ b/eng/common/cross/x64/tizen/tizen.patch @@ -0,0 +1,9 @@ +diff -u -r a/usr/lib64/libc.so b/usr/lib64/libc.so +--- a/usr/lib64/libc.so 2016-12-30 23:00:08.284951863 +0900 ++++ b/usr/lib64/libc.so 2016-12-30 23:00:32.140951815 +0900 +@@ -2,4 +2,4 @@ + Use the shared library, but some functions are only in + the static library, so try that secondarily. */ + OUTPUT_FORMAT(elf64-x86-64) +-GROUP ( /lib64/libc.so.6 /usr/lib64/libc_nonshared.a AS_NEEDED ( /lib64/ld-linux-x86-64.so.2 ) ) ++GROUP ( libc.so.6 libc_nonshared.a AS_NEEDED ( ld-linux-x86-64.so.2 ) ) diff --git a/eng/common/cross/x86/tizen/tizen.patch b/eng/common/cross/x86/tizen/tizen.patch new file mode 100644 index 00000000000..f4fe8838ad6 --- /dev/null +++ b/eng/common/cross/x86/tizen/tizen.patch @@ -0,0 +1,9 @@ +diff -u -r a/usr/lib/libc.so b/usr/lib/libc.so +--- a/usr/lib/libc.so 2016-12-30 23:00:08.284951863 +0900 ++++ b/usr/lib/libc.so 2016-12-30 23:00:32.140951815 +0900 +@@ -2,4 +2,4 @@ + Use the shared library, but some functions are only in + the static library, so try that secondarily. */ + OUTPUT_FORMAT(elf32-i386) +-GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a AS_NEEDED ( /lib/ld-linux.so.2 ) ) ++GROUP ( libc.so.6 libc_nonshared.a AS_NEEDED ( ld-linux.so.2 ) ) diff --git a/global.json b/global.json index e428a94ebb9..dcc285dbd61 100644 --- a/global.json +++ b/global.json @@ -1,11 +1,11 @@ { "sdk": { - "version": "9.0.110", + "version": "9.0.112", "allowPrerelease": true, "rollForward": "latestMajor" }, "tools": { - "dotnet": "9.0.110", + "dotnet": "9.0.112", "runtimes": { "dotnet": [ "$(MicrosoftNETCoreBrowserDebugHostTransportVersion)" @@ -13,7 +13,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.25503.3", - "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.25503.3" + "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.25577.5", + "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.25577.5" } } diff --git a/src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs b/src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs index d5efd7f6a81..5b1ba37c024 100644 --- a/src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs +++ b/src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Text; +using System.Text.Json; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata.Internal; @@ -837,6 +838,20 @@ protected virtual void GenerateEntityTypeAnnotations( .FilterIgnoredAnnotations(entityType.GetAnnotations()) .ToDictionary(a => a.Name, a => a); + // Add ContainerColumnType annotation if entity is mapped to JSON but the type annotation is missing + if (annotations.ContainsKey(RelationalAnnotationNames.ContainerColumnName) + && !annotations.ContainsKey(RelationalAnnotationNames.ContainerColumnType)) + { + var containerColumnType = entityType.GetContainerColumnType() + ?? Dependencies.RelationalTypeMappingSource.FindMapping(typeof(JsonElement))?.StoreType; + if (containerColumnType != null) + { + annotations[RelationalAnnotationNames.ContainerColumnType] = new Annotation( + RelationalAnnotationNames.ContainerColumnType, + containerColumnType); + } + } + GenerateTableMapping(entityTypeBuilderName, entityType, stringBuilder, annotations); GenerateSplitTableMapping(entityTypeBuilderName, entityType, stringBuilder); diff --git a/src/EFCore.Proxies/Proxies/Internal/LazyLoadingInterceptor.cs b/src/EFCore.Proxies/Proxies/Internal/LazyLoadingInterceptor.cs index c955c62219b..e1137bfab67 100644 --- a/src/EFCore.Proxies/Proxies/Internal/LazyLoadingInterceptor.cs +++ b/src/EFCore.Proxies/Proxies/Internal/LazyLoadingInterceptor.cs @@ -57,7 +57,7 @@ public virtual void Intercept(IInvocation invocation) } else if (LazyLoaderSetter.Equals(invocation.Method)) { - _loader = (ILazyLoader)invocation.Arguments[0]; + _loader = (ILazyLoader)invocation.Arguments[0]!; } else { diff --git a/src/EFCore.Proxies/Proxies/Internal/PropertyChangeInterceptorBase.cs b/src/EFCore.Proxies/Proxies/Internal/PropertyChangeInterceptorBase.cs index 393439441f3..076697bf2de 100644 --- a/src/EFCore.Proxies/Proxies/Internal/PropertyChangeInterceptorBase.cs +++ b/src/EFCore.Proxies/Proxies/Internal/PropertyChangeInterceptorBase.cs @@ -58,7 +58,7 @@ protected virtual string FindPropertyName(IInvocation invocation) if (indexerPropertyInfo != null && indexerPropertyInfo.GetSetMethod(nonPublic: true) == invocation.Method) { - return (string)invocation.Arguments[0]; + return (string)invocation.Arguments[0]!; } } diff --git a/src/EFCore.Proxies/Proxies/Internal/PropertyChangedInterceptor.cs b/src/EFCore.Proxies/Proxies/Internal/PropertyChangedInterceptor.cs index 45308ec2753..2429693109c 100644 --- a/src/EFCore.Proxies/Proxies/Internal/PropertyChangedInterceptor.cs +++ b/src/EFCore.Proxies/Proxies/Internal/PropertyChangedInterceptor.cs @@ -48,12 +48,12 @@ public virtual void Intercept(IInvocation invocation) if (methodName == $"add_{nameof(INotifyPropertyChanged.PropertyChanged)}") { _handler = (PropertyChangedEventHandler)Delegate.Combine( - _handler, (Delegate)invocation.Arguments[0]); + _handler, (Delegate)invocation.Arguments[0]!); } else if (methodName == $"remove_{nameof(INotifyPropertyChanged.PropertyChanged)}") { _handler = (PropertyChangedEventHandler?)Delegate.Remove( - _handler, (Delegate)invocation.Arguments[0]); + _handler, (Delegate)invocation.Arguments[0]!); } } else if (methodName.StartsWith("set_", StringComparison.Ordinal)) diff --git a/src/EFCore.Proxies/Proxies/Internal/PropertyChangingInterceptor.cs b/src/EFCore.Proxies/Proxies/Internal/PropertyChangingInterceptor.cs index 26ba9d4b04c..8b5a8ed0a2c 100644 --- a/src/EFCore.Proxies/Proxies/Internal/PropertyChangingInterceptor.cs +++ b/src/EFCore.Proxies/Proxies/Internal/PropertyChangingInterceptor.cs @@ -48,12 +48,12 @@ public virtual void Intercept(IInvocation invocation) if (methodName == $"add_{nameof(INotifyPropertyChanging.PropertyChanging)}") { _handler = (PropertyChangingEventHandler)Delegate.Combine( - _handler, (Delegate)invocation.Arguments[0]); + _handler, (Delegate)invocation.Arguments[0]!); } else if (methodName == $"remove_{nameof(INotifyPropertyChanging.PropertyChanging)}") { _handler = (PropertyChangingEventHandler?)Delegate.Remove( - _handler, (Delegate)invocation.Arguments[0]); + _handler, (Delegate)invocation.Arguments[0]!); } } else if (methodName.StartsWith("set_", StringComparison.Ordinal)) diff --git a/src/ef/ef.csproj b/src/ef/ef.csproj index 36f668682e5..54d4a068b22 100644 --- a/src/ef/ef.csproj +++ b/src/ef/ef.csproj @@ -30,6 +30,11 @@ + + + $(NoWarn);NU1903 + + diff --git a/test/Directory.Build.props b/test/Directory.Build.props index 68b58c1da11..e66d1c6474d 100644 --- a/test/Directory.Build.props +++ b/test/Directory.Build.props @@ -6,6 +6,7 @@ $(MSBuildThisFileDirectory)..\rulesets\EFCore.test.ruleset preview net9.0 + false diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/PrimitiveCollectionsQueryCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/PrimitiveCollectionsQueryCosmosTest.cs index b8f411bcbb7..323790c99e3 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/PrimitiveCollectionsQueryCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/PrimitiveCollectionsQueryCosmosTest.cs @@ -1597,11 +1597,11 @@ public override Task Parameter_collection_Concat_column_collection(bool async) AssertSql( """ -@__ints_0='[11,111]' +@__p_0='[11,111]' SELECT VALUE c FROM root c -WHERE (ARRAY_LENGTH(ARRAY_CONCAT(@__ints_0, c["Ints"])) = 2) +WHERE (ARRAY_LENGTH(ARRAY_CONCAT(@__p_0, c["Ints"])) = 2) """); }); diff --git a/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.ModelSnapshot.cs b/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.ModelSnapshot.cs index ce667239197..4d82613e507 100644 --- a/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.ModelSnapshot.cs +++ b/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.ModelSnapshot.cs @@ -4362,7 +4362,9 @@ public virtual void Owned_types_mapped_to_json_are_stored_in_snapshot() b1.ToTable("EntityWithOneProperty", "DefaultSchema"); - b1.ToJson("EntityWithTwoProperties"); + b1 + .ToJson("EntityWithTwoProperties") + .HasColumnType("nvarchar(max)"); b1.WithOwner("EntityWithOneProperty") .HasForeignKey("EntityWithOnePropertyId"); @@ -4437,6 +4439,7 @@ public virtual void Owned_types_mapped_to_json_are_stored_in_snapshot() Assert.Equal(nameof(EntityWithOneProperty), ownedType1.GetTableName()); Assert.Equal("EntityWithTwoProperties", ownedType1.GetContainerColumnName()); + Assert.Equal("nvarchar(max)", ownedType1.GetContainerColumnType()); var ownership2 = ownedType1.FindNavigation(nameof(EntityWithStringKey)).ForeignKey; Assert.Equal("EntityWithTwoPropertiesEntityWithOnePropertyId", ownership2.Properties[0].Name); @@ -4473,6 +4476,83 @@ public virtual void Owned_types_mapped_to_json_are_stored_in_snapshot() Assert.Equal("Name", ownedProperties3[3].Name); }); + [ConditionalFact] + public virtual void Owned_types_mapped_to_json_with_explicit_column_type_are_stored_in_snapshot() + => Test( + builder => + { + builder.Entity(b => + { + b.HasKey(x => x.Id).HasName("PK_Custom"); + + b.OwnsOne( + x => x.EntityWithTwoProperties, bb => + { + bb.ToJson().HasColumnType("json"); + bb.Ignore(x => x.Id); + bb.Property(x => x.AlternateId).HasJsonPropertyName("NotKey"); + bb.WithOwner(e => e.EntityWithOneProperty); + }); + }); + }, + AddBoilerPlate( + GetHeading() + + """ + modelBuilder.Entity("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+EntityWithOneProperty", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.HasKey("Id") + .HasName("PK_Custom"); + + b.ToTable("EntityWithOneProperty", "DefaultSchema"); + }); + + modelBuilder.Entity("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+EntityWithOneProperty", b => + { + b.OwnsOne("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+EntityWithTwoProperties", "EntityWithTwoProperties", b1 => + { + b1.Property("EntityWithOnePropertyId") + .HasColumnType("int"); + + b1.Property("AlternateId") + .HasColumnType("int") + .HasAnnotation("Relational:JsonPropertyName", "NotKey"); + + b1.HasKey("EntityWithOnePropertyId"); + + b1.ToTable("EntityWithOneProperty", "DefaultSchema"); + + b1 + .ToJson("EntityWithTwoProperties") + .HasColumnType("json"); + + b1.WithOwner("EntityWithOneProperty") + .HasForeignKey("EntityWithOnePropertyId"); + + b1.Navigation("EntityWithOneProperty"); + }); + + b.Navigation("EntityWithTwoProperties"); + }); +""", usingSystem: false), + o => + { + var entityWithOneProperty = o.FindEntityType(typeof(EntityWithOneProperty)); + Assert.Equal("PK_Custom", entityWithOneProperty.GetKeys().Single().GetName()); + + var ownership1 = entityWithOneProperty.FindNavigation(nameof(EntityWithOneProperty.EntityWithTwoProperties)) + .ForeignKey; + var ownedType1 = ownership1.DeclaringEntityType; + Assert.Equal(nameof(EntityWithOneProperty), ownedType1.GetTableName()); + Assert.Equal("EntityWithTwoProperties", ownedType1.GetContainerColumnName()); + Assert.Equal("json", ownedType1.GetContainerColumnType()); + }); + private class Order { public int Id { get; set; } diff --git a/test/EFCore.Specification.Tests/Query/NorthwindMiscellaneousQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/NorthwindMiscellaneousQueryTestBase.cs index f0b8346fcb4..73ccb60482f 100644 --- a/test/EFCore.Specification.Tests/Query/NorthwindMiscellaneousQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/NorthwindMiscellaneousQueryTestBase.cs @@ -5802,7 +5802,7 @@ public virtual Task Contains_over_concatenated_parameter_and_constant(bool async return AssertQuery( async, - ss => ss.Set().Where(c => data.Contains(someVariable + "SomeConstant"))); + ss => ss.Set().Where(c => ((IEnumerable)data).Contains(someVariable + "SomeConstant"))); } [ConditionalTheory] diff --git a/test/EFCore.Specification.Tests/Query/PrimitiveCollectionsQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/PrimitiveCollectionsQueryTestBase.cs index 10bc9225e49..ed86211b24a 100644 --- a/test/EFCore.Specification.Tests/Query/PrimitiveCollectionsQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/PrimitiveCollectionsQueryTestBase.cs @@ -973,7 +973,7 @@ public virtual Task Parameter_collection_Concat_column_collection(bool async) return AssertQuery( async, - ss => ss.Set().Where(c => ints.Concat(c.Ints).Count() == 2)); + ss => ss.Set().Where(c => ((IEnumerable)ints).Concat(c.Ints).Count() == 2)); } [ConditionalTheory] // #33582 diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs index 186799afd4e..940969852ad 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs @@ -1558,7 +1558,7 @@ public override async Task Parameter_collection_Concat_column_collection(bool as AssertSql( """ -@__ints_0='[11,111]' (Size = 4000) +@__p_0='[11,111]' (Size = 4000) SELECT [p].[Id], [p].[Bool], [p].[Bools], [p].[DateTime], [p].[DateTimes], [p].[Enum], [p].[Enums], [p].[Int], [p].[Ints], [p].[NullableInt], [p].[NullableInts], [p].[NullableString], [p].[NullableStrings], [p].[String], [p].[Strings] FROM [PrimitiveCollectionsEntity] AS [p] @@ -1566,10 +1566,10 @@ FROM [PrimitiveCollectionsEntity] AS [p] SELECT COUNT(*) FROM ( SELECT 1 AS empty - FROM OPENJSON(@__ints_0) AS [i] + FROM OPENJSON(@__p_0) AS [p0] UNION ALL SELECT 1 AS empty - FROM OPENJSON([p].[Ints]) AS [i0] + FROM OPENJSON([p].[Ints]) AS [i] ) AS [u]) = 2 """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs index ed20eb7db20..d15d5caab90 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs @@ -1581,7 +1581,7 @@ public override async Task Parameter_collection_Concat_column_collection(bool as AssertSql( """ -@__ints_0='[11,111]' (Size = 4000) +@__p_0='[11,111]' (Size = 4000) SELECT [p].[Id], [p].[Bool], [p].[Bools], [p].[DateTime], [p].[DateTimes], [p].[Enum], [p].[Enums], [p].[Int], [p].[Ints], [p].[NullableInt], [p].[NullableInts], [p].[NullableString], [p].[NullableStrings], [p].[String], [p].[Strings] FROM [PrimitiveCollectionsEntity] AS [p] @@ -1589,10 +1589,10 @@ FROM [PrimitiveCollectionsEntity] AS [p] SELECT COUNT(*) FROM ( SELECT 1 AS empty - FROM OPENJSON(@__ints_0) AS [i] + FROM OPENJSON(@__p_0) AS [p0] UNION ALL SELECT 1 AS empty - FROM OPENJSON([p].[Ints]) AS [i0] + FROM OPENJSON([p].[Ints]) AS [i] ) AS [u]) = 2 """); } diff --git a/test/EFCore.SqlServer.Tests/Migrations/SqlServerModelDifferTest.cs b/test/EFCore.SqlServer.Tests/Migrations/SqlServerModelDifferTest.cs index 0f8dddae5a4..4b180344c3c 100644 --- a/test/EFCore.SqlServer.Tests/Migrations/SqlServerModelDifferTest.cs +++ b/test/EFCore.SqlServer.Tests/Migrations/SqlServerModelDifferTest.cs @@ -1900,4 +1900,57 @@ public void Rebuild_index_with_different_datacompression_value() Assert.Equal(DataCompressionType.Page, annotationValue); }); + + [ConditionalFact] + public void Alter_column_from_nvarchar_max_to_json_for_owned_type() + => Execute( + _ => { }, + source => source.Entity( + "Blog", + x => + { + x.Property("Id"); + x.HasKey("Id"); + x.OwnsOne( + "Details", "Details", d => + { + d.Property("Author"); + d.Property("Viewers"); + d.ToJson(); + }); + }), + target => target.Entity( + "Blog", + x => + { + x.Property("Id"); + x.HasKey("Id"); + x.OwnsOne( + "Details", "Details", d => + { + d.Property("Author"); + d.Property("Viewers"); + d.ToJson().HasColumnType("json"); + }); + }), + upOps => + { + Assert.Equal(1, upOps.Count); + + var operation = Assert.IsType(upOps[0]); + Assert.Equal("Blog", operation.Table); + Assert.Equal("Details", operation.Name); + Assert.Equal("json", operation.ColumnType); + Assert.Equal("nvarchar(max)", operation.OldColumn.ColumnType); + }, + downOps => + { + Assert.Equal(1, downOps.Count); + + var operation = Assert.IsType(downOps[0]); + Assert.Equal("Blog", operation.Table); + Assert.Equal("Details", operation.Name); + Assert.Equal("nvarchar(max)", operation.ColumnType); + Assert.Equal("json", operation.OldColumn.ColumnType); + }); } diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs index 68a914a22c5..44a92f77add 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs @@ -1540,7 +1540,7 @@ await Assert.ThrowsAsync( AssertSql( """ -@__ints_0='[11,111]' (Size = 8) +@__p_0='[11,111]' (Size = 8) SELECT "p"."Id", "p"."Bool", "p"."Bools", "p"."DateTime", "p"."DateTimes", "p"."Enum", "p"."Enums", "p"."Int", "p"."Ints", "p"."NullableInt", "p"."NullableInts", "p"."NullableString", "p"."NullableStrings", "p"."String", "p"."Strings" FROM "PrimitiveCollectionsEntity" AS "p" @@ -1548,10 +1548,10 @@ await Assert.ThrowsAsync( SELECT COUNT(*) FROM ( SELECT 1 - FROM json_each(@__ints_0) AS "i" + FROM json_each(@__p_0) AS "p0" UNION ALL SELECT 1 - FROM json_each("p"."Ints") AS "i0" + FROM json_each("p"."Ints") AS "i" ) AS "u") = 2 """); }