diff --git a/.editorconfig b/.editorconfig index 246a4e1422f..fc773da07c9 100644 --- a/.editorconfig +++ b/.editorconfig @@ -91,9 +91,9 @@ csharp_style_var_elsewhere = true:suggestion # Expression-bodied members # Explicitly disabled due to difference in coding style between source and tests -#csharp_style_expression_bodied_methods = false:silent -#csharp_style_expression_bodied_constructors = false:silent -csharp_style_expression_bodied_operators = false:silent +csharp_style_expression_bodied_methods = true:suggestion +csharp_style_expression_bodied_constructors = true:suggestion +csharp_style_expression_bodied_operators = true:suggestion csharp_style_expression_bodied_properties = true:suggestion csharp_style_expression_bodied_indexers = true:suggestion csharp_style_expression_bodied_accessors = true:suggestion @@ -251,8 +251,5 @@ dotnet_naming_rule.everything_else_naming.symbols = everything_else dotnet_naming_rule.everything_else_naming.style = camel_case_style dotnet_naming_rule.everything_else_naming.severity = suggestion -# Microsoft .NET properties -csharp_style_expression_bodied_methods = true:suggestion - # ReSharper properties resharper_local_function_body = expression_body diff --git a/.gitattributes b/.gitattributes index f5f8978580c..cc296e9aaab 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,3 +2,4 @@ *.cs diff=csharp *.sh eol=lf *.sln eol=crlf +*.sql diff diff --git a/.github/SUPPORT.md b/.github/SUPPORT.md index f588c1c5439..8e505319174 100644 --- a/.github/SUPPORT.md +++ b/.github/SUPPORT.md @@ -24,4 +24,4 @@ If you have a specific question about using the product, we encourage you to [as Official Support ---------------- -Entity Framework Core is covered by Microsoft's [.NET Core Support Policy](https://dotnet.microsoft.com/platform/support/policy/dotnet-core). If you've tried all the optoins above and are still looking for help, you may wish to [contact a Microsoft Support professional](http://support.microsoft.com/supportforbusiness/productselection?sapId=bec2bc54-b200-6962-301f-f098532f27b2). Please note that personal help may incur a fee. +Entity Framework Core is covered by Microsoft's [.NET Core Support Policy](https://dotnet.microsoft.com/platform/support/policy/dotnet-core). If you've tried all the options above and are still looking for help, you may wish to [contact a Microsoft Support professional](http://support.microsoft.com/supportforbusiness/productselection?sapId=bec2bc54-b200-6962-301f-f098532f27b2). Please note that personal help may incur a fee. 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.Build.targets b/Directory.Build.targets index 1ecc794c902..9044e67550f 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -11,13 +11,6 @@ - - - - + + + + + true + true + true + + $(NoWarn);NU1507 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/EFCore.sln b/EFCore.sln index 3f1cd5ae7c2..22394d18d26 100644 --- a/EFCore.sln +++ b/EFCore.sln @@ -141,6 +141,8 @@ Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "EFCore.VisualBasic.Function EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EFCore.Tasks", "src\EFCore.Tasks\EFCore.Tasks.csproj", "{711EE8F3-F92D-4470-8B0B-25D8B13EF282}" EndProject +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "EFCore.FSharp.FunctionalTests", "test\EFCore.FSharp.FunctionalTests\EFCore.FSharp.FunctionalTests.fsproj", "{89180105-1D98-4844-9C24-3A5DA2C53329}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -371,6 +373,10 @@ Global {711EE8F3-F92D-4470-8B0B-25D8B13EF282}.Debug|Any CPU.Build.0 = Debug|Any CPU {711EE8F3-F92D-4470-8B0B-25D8B13EF282}.Release|Any CPU.ActiveCfg = Release|Any CPU {711EE8F3-F92D-4470-8B0B-25D8B13EF282}.Release|Any CPU.Build.0 = Release|Any CPU + {89180105-1D98-4844-9C24-3A5DA2C53329}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {89180105-1D98-4844-9C24-3A5DA2C53329}.Debug|Any CPU.Build.0 = Debug|Any CPU + {89180105-1D98-4844-9C24-3A5DA2C53329}.Release|Any CPU.ActiveCfg = Release|Any CPU + {89180105-1D98-4844-9C24-3A5DA2C53329}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -433,6 +439,7 @@ Global {3D935B7D-80BD-49AD-BDC9-E1B0C9D9494F} = {CE6B50B2-34AE-44C9-940A-4E48C3E1B3BC} {2AC6A8AC-5C0A-422A-B21A-CDC8D75F20A3} = {258D5057-81B9-40EC-A872-D21E27452749} {711EE8F3-F92D-4470-8B0B-25D8B13EF282} = {CE6B50B2-34AE-44C9-940A-4E48C3E1B3BC} + {89180105-1D98-4844-9C24-3A5DA2C53329} = {258D5057-81B9-40EC-A872-D21E27452749} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {285A5EB4-BCF4-40EB-B9E1-DF6DBCB5E705} diff --git a/NuGet.config b/NuGet.config index d1a8a417e43..ec22121ce3c 100644 --- a/NuGet.config +++ b/NuGet.config @@ -12,10 +12,16 @@ + + + + + + diff --git a/azure-pipelines-public.yml b/azure-pipelines-public.yml index cd521dd30b6..d56ef44140b 100644 --- a/azure-pipelines-public.yml +++ b/azure-pipelines-public.yml @@ -53,7 +53,7 @@ stages: enablePublishTestResults: true pool: name: $(DncEngPublicBuildPool) - demands: ImageOverride -equals 1es-windows-2019-open + demands: ImageOverride -equals 1es-windows-2022-open timeoutInMinutes: 90 variables: - _InternalBuildArgs: '' @@ -143,7 +143,7 @@ stages: timeoutInMinutes: 180 pool: name: $(DncEngPublicBuildPool) - demands: ImageOverride -equals 1es-windows-2019-open + demands: ImageOverride -equals 1es-windows-2022-open variables: # Rely on task Arcade injects, not auto-injected build step. - skipComponentGovernanceDetection: true diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 64638066d6f..19604d65d27 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -56,6 +56,8 @@ extends: baselineFile: $(Build.SourcesDirectory)\.config\guardian\.gdnbaselines binskim: scanOutputDirectoryOnly: true + policheck: + enabled: true tsa: enabled: true customBuildTags: @@ -250,4 +252,4 @@ extends: enableSourceLinkValidation: false publishAssetsImmediately: true SDLValidationParameters: - enable: false \ No newline at end of file + enable: false 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 51ac02729fc..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 849d6cbbaed..33d4a6f3e00 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,71 +1,79 @@ - + https://github.com/dotnet/runtime - 7cb32e193a55a95c74fc3bd56501b951b48b700f + 0372b5080a4aec8d73d6861ad4b993d9d0fe3a11 - + https://github.com/dotnet/runtime - 7cb32e193a55a95c74fc3bd56501b951b48b700f + 0372b5080a4aec8d73d6861ad4b993d9d0fe3a11 - + https://github.com/dotnet/runtime - 7cb32e193a55a95c74fc3bd56501b951b48b700f + 0372b5080a4aec8d73d6861ad4b993d9d0fe3a11 - + https://github.com/dotnet/runtime - 7cb32e193a55a95c74fc3bd56501b951b48b700f + 0372b5080a4aec8d73d6861ad4b993d9d0fe3a11 - + https://github.com/dotnet/runtime - 7cb32e193a55a95c74fc3bd56501b951b48b700f + 0372b5080a4aec8d73d6861ad4b993d9d0fe3a11 - + https://github.com/dotnet/runtime - 7cb32e193a55a95c74fc3bd56501b951b48b700f + 0372b5080a4aec8d73d6861ad4b993d9d0fe3a11 - + https://github.com/dotnet/runtime - 7cb32e193a55a95c74fc3bd56501b951b48b700f + 0372b5080a4aec8d73d6861ad4b993d9d0fe3a11 - + https://github.com/dotnet/runtime - 7cb32e193a55a95c74fc3bd56501b951b48b700f + 0372b5080a4aec8d73d6861ad4b993d9d0fe3a11 - + https://github.com/dotnet/runtime - 7cb32e193a55a95c74fc3bd56501b951b48b700f + 0372b5080a4aec8d73d6861ad4b993d9d0fe3a11 - + https://github.com/dotnet/runtime - 7cb32e193a55a95c74fc3bd56501b951b48b700f + 0372b5080a4aec8d73d6861ad4b993d9d0fe3a11 - + https://github.com/dotnet/runtime - 7cb32e193a55a95c74fc3bd56501b951b48b700f + 0372b5080a4aec8d73d6861ad4b993d9d0fe3a11 - + https://github.com/dotnet/runtime - 7cb32e193a55a95c74fc3bd56501b951b48b700f + 0372b5080a4aec8d73d6861ad4b993d9d0fe3a11 + + + https://github.com/dotnet/runtime + 0372b5080a4aec8d73d6861ad4b993d9d0fe3a11 + + + https://github.com/dotnet/runtime + 0372b5080a4aec8d73d6861ad4b993d9d0fe3a11 - + https://github.com/dotnet/arcade - 60ae233c3d77f11c5fdb53e570b64d503b13ba59 + f209a925b15bc66ecb9a8825bd9595937bbe3aa1 - + https://github.com/dotnet/arcade - 60ae233c3d77f11c5fdb53e570b64d503b13ba59 + f209a925b15bc66ecb9a8825bd9595937bbe3aa1 - + https://github.com/dotnet/arcade - 60ae233c3d77f11c5fdb53e570b64d503b13ba59 + f209a925b15bc66ecb9a8825bd9595937bbe3aa1 diff --git a/eng/Versions.props b/eng/Versions.props index 8f7ab52831d..33ecdca09d5 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -1,7 +1,7 @@ - 9.0.0 - rc + 10.0.0 + alpha 1 False true @@ -16,31 +16,33 @@ False - 9.0.0-rc.1.24410.5 - 9.0.0-rc.1.24410.5 - 9.0.0-rc.1.24410.5 - 9.0.0-rc.1.24410.5 - 9.0.0-rc.1.24410.5 - 9.0.0-rc.1.24410.5 - 9.0.0-rc.1.24410.5 - 9.0.0-rc.1.24410.5 - 9.0.0-rc.1.24410.5 - 9.0.0-rc.1.24410.5 - 9.0.0-rc.1.24410.5 - 9.0.0-rc.1.24410.5 + 10.0.0-alpha.1.24504.10 + 10.0.0-alpha.1.24504.10 + 10.0.0-alpha.1.24504.10 + 10.0.0-alpha.1.24504.10 + 10.0.0-alpha.1.24504.10 + 10.0.0-alpha.1.24504.10 + 10.0.0-alpha.1.24504.10 + 10.0.0-alpha.1.24504.10 + 10.0.0-alpha.1.24504.10 + 10.0.0-alpha.1.24504.10 + 10.0.0-alpha.1.24504.10 + 10.0.0-alpha.1.24504.10 + 10.0.0-alpha.1.24504.10 + 10.0.0-alpha.1.24504.10 - 9.0.0-beta.24408.2 + 10.0.0-beta.24504.4 - 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.11.3 + 1.1.2 + 1.12.1 1.3.2 1.8.1 + 2.1.10 diff --git a/eng/common/SetupNugetSources.ps1 b/eng/common/SetupNugetSources.ps1 index 2b0a5c9e665..5db4ad71ee2 100644 --- a/eng/common/SetupNugetSources.ps1 +++ b/eng/common/SetupNugetSources.ps1 @@ -157,7 +157,7 @@ if ($dotnet31Source -ne $null) { AddPackageSource -Sources $sources -SourceName "dotnet3.1-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-transport/nuget/v2" -Creds $creds -Username $userName -pwd $Password } -$dotnetVersions = @('5','6','7','8') +$dotnetVersions = @('5','6','7','8','9') foreach ($dotnetVersion in $dotnetVersions) { $feedPrefix = "dotnet" + $dotnetVersion; diff --git a/eng/common/SetupNugetSources.sh b/eng/common/SetupNugetSources.sh index b493479a1da..4604b61b032 100644 --- a/eng/common/SetupNugetSources.sh +++ b/eng/common/SetupNugetSources.sh @@ -99,7 +99,7 @@ if [ "$?" == "0" ]; then PackageSources+=('dotnet3.1-internal-transport') fi -DotNetVersions=('5' '6' '7' '8') +DotNetVersions=('5' '6' '7' '8' '9') for DotNetVersion in ${DotNetVersions[@]} ; do FeedPrefix="dotnet${DotNetVersion}"; diff --git a/eng/common/core-templates/job/job.yml b/eng/common/core-templates/job/job.yml index c732bee9f4a..c37d16634d1 100644 --- a/eng/common/core-templates/job/job.yml +++ b/eng/common/core-templates/job/job.yml @@ -19,6 +19,7 @@ parameters: # publishing defaults artifacts: '' enableMicrobuild: false + enableMicrobuildForMacAndLinux: false enablePublishBuildArtifacts: false enablePublishBuildAssets: false enablePublishTestResults: false @@ -33,11 +34,6 @@ parameters: artifactPublishSteps: [] runAsPublic: false -# Sbom related params - enableSbom: true - PackageVersion: 9.0.0 - BuildDropPath: '$(Build.SourcesDirectory)/artifacts' - # 1es specific parameters is1ESPipeline: '' @@ -139,11 +135,26 @@ jobs: signType: $(_SignType) zipSources: false feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json + ${{ if and(eq(parameters.enableMicrobuildForMacAndLinux, 'true'), ne(variables['Agent.Os'], 'Windows_NT')) }}: + azureSubscription: 'MicroBuild Signing Task (DevDiv)' env: TeamName: $(_TeamName) MicroBuildOutputFolderOverride: '$(Agent.TempDirectory)' + SYSTEM_ACCESSTOKEN: $(System.AccessToken) continueOnError: ${{ parameters.continueOnError }} - condition: and(succeeded(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT')) + condition: and( + succeeded(), + or( + and( + eq(variables['Agent.Os'], 'Windows_NT'), + in(variables['_SignType'], 'real', 'test') + ), + and( + ${{ eq(parameters.enableMicrobuildForMacAndLinux, true) }}, + ne(variables['Agent.Os'], 'Windows_NT'), + eq(variables['_SignType'], 'real') + ) + )) - ${{ if and(eq(parameters.runAsPublic, 'false'), eq(variables['System.TeamProject'], 'internal')) }}: - task: NuGetAuthenticate@1 @@ -176,7 +187,19 @@ jobs: - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - task: MicroBuildCleanup@1 displayName: Execute Microbuild cleanup tasks - condition: and(always(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT')) + condition: and( + always(), + or( + and( + eq(variables['Agent.Os'], 'Windows_NT'), + in(variables['_SignType'], 'real', 'test') + ), + and( + ${{ eq(parameters.enableMicrobuildForMacAndLinux, true) }}, + ne(variables['Agent.Os'], 'Windows_NT'), + eq(variables['_SignType'], 'real') + ) + )) continueOnError: ${{ parameters.continueOnError }} env: TeamName: $(_TeamName) diff --git a/eng/common/core-templates/job/source-index-stage1.yml b/eng/common/core-templates/job/source-index-stage1.yml index 205fb5b3a39..30530359a5d 100644 --- a/eng/common/core-templates/job/source-index-stage1.yml +++ b/eng/common/core-templates/job/source-index-stage1.yml @@ -1,8 +1,5 @@ parameters: runAsPublic: false - sourceIndexUploadPackageVersion: 2.0.0-20240522.1 - sourceIndexProcessBinlogPackageVersion: 1.0.1-20240522.1 - sourceIndexPackageSource: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json sourceIndexBuildCommand: powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -Command "eng/common/build.ps1 -restore -build -binarylog -ci" preSteps: [] binlogPath: artifacts/log/Debug/Build.binlog @@ -16,12 +13,6 @@ jobs: dependsOn: ${{ parameters.dependsOn }} condition: ${{ parameters.condition }} variables: - - name: SourceIndexUploadPackageVersion - value: ${{ parameters.sourceIndexUploadPackageVersion }} - - name: SourceIndexProcessBinlogPackageVersion - value: ${{ parameters.sourceIndexProcessBinlogPackageVersion }} - - name: SourceIndexPackageSource - value: ${{ parameters.sourceIndexPackageSource }} - name: BinlogPath value: ${{ parameters.binlogPath }} - template: /eng/common/core-templates/variables/pool-providers.yml @@ -34,12 +25,10 @@ jobs: pool: ${{ if eq(variables['System.TeamProject'], 'public') }}: name: $(DncEngPublicBuildPool) - image: 1es-windows-2022-open - os: windows + image: windows.vs2022.amd64.open ${{ if eq(variables['System.TeamProject'], 'internal') }}: name: $(DncEngInternalBuildPool) - image: 1es-windows-2022 - os: windows + image: windows.vs2022.amd64 steps: - ${{ if eq(parameters.is1ESPipeline, '') }}: @@ -47,35 +36,9 @@ jobs: - ${{ each preStep in parameters.preSteps }}: - ${{ preStep }} - - - task: UseDotNet@2 - displayName: Use .NET 8 SDK - inputs: - packageType: sdk - version: 8.0.x - installationPath: $(Agent.TempDirectory)/dotnet - workingDirectory: $(Agent.TempDirectory) - - - script: | - $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version $(sourceIndexProcessBinlogPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools - $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version $(sourceIndexUploadPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools - displayName: Download Tools - # Set working directory to temp directory so 'dotnet' doesn't try to use global.json and use the repo's sdk. - workingDirectory: $(Agent.TempDirectory) - - script: ${{ parameters.sourceIndexBuildCommand }} displayName: Build Repository - - script: $(Agent.TempDirectory)/.source-index/tools/BinLogToSln -i $(BinlogPath) -r $(Build.SourcesDirectory) -n $(Build.Repository.Name) -o .source-index/stage1output - displayName: Process Binlog into indexable sln - - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - task: AzureCLI@2 - displayName: Log in to Azure and upload stage1 artifacts to source index - inputs: - azureSubscription: 'SourceDotNet Stage1 Publish' - addSpnToEnvironment: true - scriptType: 'ps' - scriptLocation: 'inlineScript' - inlineScript: | - $(Agent.TempDirectory)/.source-index/tools/UploadIndexStage1 -i .source-index/stage1output -n $(Build.Repository.Name) -s netsourceindexstage1 -b stage1 + - template: /eng/common/core-templates/steps/source-index-stage1-publish.yml + parameters: + binLogPath: ${{ parameters.binLogPath }} \ No newline at end of file diff --git a/eng/common/core-templates/steps/publish-logs.yml b/eng/common/core-templates/steps/publish-logs.yml index 80788c52319..de24d0087c5 100644 --- a/eng/common/core-templates/steps/publish-logs.yml +++ b/eng/common/core-templates/steps/publish-logs.yml @@ -34,7 +34,9 @@ steps: '$(akams-client-id)' '$(microsoft-symbol-server-pat)' '$(symweb-symbol-server-pat)' + '$(dnceng-symbol-server-pat)' '$(dn-bot-all-orgs-build-rw-code-rw)' + '$(System.AccessToken)' ${{parameters.CustomSensitiveDataList}} continueOnError: true condition: always() @@ -45,6 +47,7 @@ steps: SourceFolder: '$(Build.SourcesDirectory)/PostBuildLogs' Contents: '**' TargetFolder: '$(Build.ArtifactStagingDirectory)/PostBuildLogs' + condition: always() - template: /eng/common/core-templates/steps/publish-build-artifacts.yml parameters: diff --git a/eng/common/core-templates/steps/source-index-stage1-publish.yml b/eng/common/core-templates/steps/source-index-stage1-publish.yml new file mode 100644 index 00000000000..473a22c4719 --- /dev/null +++ b/eng/common/core-templates/steps/source-index-stage1-publish.yml @@ -0,0 +1,35 @@ +parameters: + sourceIndexUploadPackageVersion: 2.0.0-20240522.1 + sourceIndexProcessBinlogPackageVersion: 1.0.1-20240522.1 + sourceIndexPackageSource: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json + binlogPath: artifacts/log/Debug/Build.binlog + +steps: +- task: UseDotNet@2 + displayName: "Source Index: Use .NET 8 SDK" + inputs: + packageType: sdk + version: 8.0.x + installationPath: $(Agent.TempDirectory)/dotnet + workingDirectory: $(Agent.TempDirectory) + +- script: | + $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version ${{parameters.sourceIndexProcessBinlogPackageVersion}} --add-source ${{parameters.SourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools + $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version ${{parameters.sourceIndexUploadPackageVersion}} --add-source ${{parameters.SourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools + displayName: "Source Index: Download netsourceindex Tools" + # Set working directory to temp directory so 'dotnet' doesn't try to use global.json and use the repo's sdk. + workingDirectory: $(Agent.TempDirectory) + +- script: $(Agent.TempDirectory)/.source-index/tools/BinLogToSln -i ${{parameters.BinlogPath}} -r $(Build.SourcesDirectory) -n $(Build.Repository.Name) -o .source-index/stage1output + displayName: "Source Index: Process Binlog into indexable sln" + +- ${{ if and(ne(parameters.runAsPublic, 'true'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - task: AzureCLI@2 + displayName: "Source Index: Upload Source Index stage1 artifacts to Azure" + inputs: + azureSubscription: 'SourceDotNet Stage1 Publish' + addSpnToEnvironment: true + scriptType: 'ps' + scriptLocation: 'inlineScript' + inlineScript: | + $(Agent.TempDirectory)/.source-index/tools/UploadIndexStage1 -i .source-index/stage1output -n $(Build.Repository.Name) -s netsourceindexstage1 -b stage1 diff --git a/eng/common/cross/build-rootfs.sh b/eng/common/cross/build-rootfs.sh index 4b5e8d7166b..20ae8c28687 100755 --- a/eng/common/cross/build-rootfs.sh +++ b/eng/common/cross/build-rootfs.sh @@ -66,6 +66,7 @@ __UbuntuPackages+=" libcurl4-openssl-dev" __UbuntuPackages+=" libkrb5-dev" __UbuntuPackages+=" libssl-dev" __UbuntuPackages+=" zlib1g-dev" +__UbuntuPackages+=" libbrotli-dev" __AlpinePackages+=" curl-dev" __AlpinePackages+=" krb5-dev" @@ -91,18 +92,18 @@ __HaikuPackages="gcc_syslibs" __HaikuPackages+=" gcc_syslibs_devel" __HaikuPackages+=" gmp" __HaikuPackages+=" gmp_devel" -__HaikuPackages+=" icu66" -__HaikuPackages+=" icu66_devel" +__HaikuPackages+=" icu[0-9]+" +__HaikuPackages+=" icu[0-9]*_devel" __HaikuPackages+=" krb5" __HaikuPackages+=" krb5_devel" __HaikuPackages+=" libiconv" __HaikuPackages+=" libiconv_devel" -__HaikuPackages+=" llvm12_libunwind" -__HaikuPackages+=" llvm12_libunwind_devel" +__HaikuPackages+=" llvm[0-9]*_libunwind" +__HaikuPackages+=" llvm[0-9]*_libunwind_devel" __HaikuPackages+=" mpfr" __HaikuPackages+=" mpfr_devel" -__HaikuPackages+=" openssl" -__HaikuPackages+=" openssl_devel" +__HaikuPackages+=" openssl3" +__HaikuPackages+=" openssl3_devel" __HaikuPackages+=" zlib" __HaikuPackages+=" zlib_devel" @@ -496,7 +497,7 @@ if [[ "$__CodeName" == "alpine" ]]; then arch="$(uname -m)" ensureDownloadTool - + if [[ "$__hasWget" == 1 ]]; then wget -P "$__ApkToolsDir" "https://gitlab.alpinelinux.org/api/v4/projects/5/packages/generic/v$__ApkToolsVersion/$arch/apk.static" else @@ -681,7 +682,7 @@ elif [[ "$__CodeName" == "haiku" ]]; then ensureDownloadTool - echo "Downloading Haiku package tool" + echo "Downloading Haiku package tools" git clone https://github.com/haiku/haiku-toolchains-ubuntu --depth 1 "$__RootfsDir/tmp/script" if [[ "$__hasWget" == 1 ]]; then wget -O "$__RootfsDir/tmp/download/hosttools.zip" "$("$__RootfsDir/tmp/script/fetch.sh" --hosttools)" @@ -691,34 +692,42 @@ elif [[ "$__CodeName" == "haiku" ]]; then unzip -o "$__RootfsDir/tmp/download/hosttools.zip" -d "$__RootfsDir/tmp/bin" - DepotBaseUrl="https://depot.haiku-os.org/__api/v2/pkg/get-pkg" - HpkgBaseUrl="https://eu.hpkg.haiku-os.org/haiku/master/$__HaikuArch/current" + HaikuBaseUrl="https://eu.hpkg.haiku-os.org/haiku/master/$__HaikuArch/current" + HaikuPortsBaseUrl="https://eu.hpkg.haiku-os.org/haikuports/master/$__HaikuArch/current" + + echo "Downloading HaikuPorts package repository index..." + if [[ "$__hasWget" == 1 ]]; then + wget -P "$__RootfsDir/tmp/download" "$HaikuPortsBaseUrl/repo" + else + curl -SLO --create-dirs --output-dir "$__RootfsDir/tmp/download" "$HaikuPortsBaseUrl/repo" + fi - # Download Haiku packages echo "Downloading Haiku packages" read -ra array <<<"$__HaikuPackages" for package in "${array[@]}"; do echo "Downloading $package..." - # API documented here: https://github.com/haiku/haikudepotserver/blob/master/haikudepotserver-api2/src/main/resources/api2/pkg.yaml#L60 - # The schema here: https://github.com/haiku/haikudepotserver/blob/master/haikudepotserver-api2/src/main/resources/api2/pkg.yaml#L598 + hpkgFilename="$(LD_LIBRARY_PATH="$__RootfsDir/tmp/bin" "$__RootfsDir/tmp/bin/package_repo" list -f "$__RootfsDir/tmp/download/repo" | + grep -E "${package}-" | sort -V | tail -n 1 | xargs)" + if [ -z "$hpkgFilename" ]; then + >&2 echo "ERROR: package $package missing." + exit 1 + fi + echo "Resolved filename: $hpkgFilename..." + hpkgDownloadUrl="$HaikuPortsBaseUrl/packages/$hpkgFilename" if [[ "$__hasWget" == 1 ]]; then - hpkgDownloadUrl="$(wget -qO- --post-data '{"name":"'"$package"'","repositorySourceCode":"haikuports_'$__HaikuArch'","versionType":"LATEST","naturalLanguageCode":"en"}' \ - --header 'Content-Type:application/json' "$DepotBaseUrl" | jq -r '.result.versions[].hpkgDownloadURL')" wget -P "$__RootfsDir/tmp/download" "$hpkgDownloadUrl" else - hpkgDownloadUrl="$(curl -sSL -XPOST --data '{"name":"'"$package"'","repositorySourceCode":"haikuports_'$__HaikuArch'","versionType":"LATEST","naturalLanguageCode":"en"}' \ - --header 'Content-Type:application/json' "$DepotBaseUrl" | jq -r '.result.versions[].hpkgDownloadURL')" curl -SLO --create-dirs --output-dir "$__RootfsDir/tmp/download" "$hpkgDownloadUrl" fi done for package in haiku haiku_devel; do echo "Downloading $package..." if [[ "$__hasWget" == 1 ]]; then - hpkgVersion="$(wget -qO- "$HpkgBaseUrl" | sed -n 's/^.*version: "\([^"]*\)".*$/\1/p')" - wget -P "$__RootfsDir/tmp/download" "$HpkgBaseUrl/packages/$package-$hpkgVersion-1-$__HaikuArch.hpkg" + hpkgVersion="$(wget -qO- "$HaikuBaseUrl" | sed -n 's/^.*version: "\([^"]*\)".*$/\1/p')" + wget -P "$__RootfsDir/tmp/download" "$HaikuBaseUrl/packages/$package-$hpkgVersion-1-$__HaikuArch.hpkg" else - hpkgVersion="$(curl -sSL "$HpkgBaseUrl" | sed -n 's/^.*version: "\([^"]*\)".*$/\1/p')" - curl -SLO --create-dirs --output-dir "$__RootfsDir/tmp/download" "$HpkgBaseUrl/packages/$package-$hpkgVersion-1-$__HaikuArch.hpkg" + hpkgVersion="$(curl -sSL "$HaikuBaseUrl" | sed -n 's/^.*version: "\([^"]*\)".*$/\1/p')" + curl -SLO --create-dirs --output-dir "$__RootfsDir/tmp/download" "$HaikuBaseUrl/packages/$package-$hpkgVersion-1-$__HaikuArch.hpkg" fi done diff --git a/eng/common/internal/Tools.csproj b/eng/common/internal/Tools.csproj index e925952d566..32f79dfb340 100644 --- a/eng/common/internal/Tools.csproj +++ b/eng/common/internal/Tools.csproj @@ -4,6 +4,7 @@ net472 false + false diff --git a/eng/common/template-guidance.md b/eng/common/template-guidance.md index 5ef6c30ba92..98bbc1ded0b 100644 --- a/eng/common/template-guidance.md +++ b/eng/common/template-guidance.md @@ -57,7 +57,7 @@ extends: Note: Multiple outputs are ONLY applicable to 1ES PT publishing (only usable when referencing `templates-official`). -# Development notes +## Development notes **Folder / file structure** diff --git a/eng/common/templates-official/job/job.yml b/eng/common/templates-official/job/job.yml index 0c2928d5c79..605692d2fb7 100644 --- a/eng/common/templates-official/job/job.yml +++ b/eng/common/templates-official/job/job.yml @@ -1,8 +1,23 @@ +parameters: +# Sbom related params + enableSbom: true + runAsPublic: false + PackageVersion: 9.0.0 + BuildDropPath: '$(Build.SourcesDirectory)/artifacts' + jobs: - template: /eng/common/core-templates/job/job.yml parameters: is1ESPipeline: true + componentGovernanceSteps: + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.enableSbom, 'true')) }}: + - template: /eng/common/templates/steps/generate-sbom.yml + parameters: + PackageVersion: ${{ parameters.packageVersion }} + BuildDropPath: ${{ parameters.buildDropPath }} + publishArtifacts: false + # publish artifacts # for 1ES managed templates, use the templateContext.output to handle multiple outputs. templateContext: diff --git a/eng/common/templates-official/steps/source-index-stage1-publish.yml b/eng/common/templates-official/steps/source-index-stage1-publish.yml new file mode 100644 index 00000000000..9b8b80942b5 --- /dev/null +++ b/eng/common/templates-official/steps/source-index-stage1-publish.yml @@ -0,0 +1,7 @@ +steps: +- template: /eng/common/core-templates/steps/source-index-stage1-publish.yml + parameters: + is1ESPipeline: true + + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates/job/job.yml b/eng/common/templates/job/job.yml index 8da477dd69f..d1aeb92fcea 100644 --- a/eng/common/templates/job/job.yml +++ b/eng/common/templates/job/job.yml @@ -4,6 +4,7 @@ parameters: componentGovernanceIgnoreDirectories: '' # Sbom related params enableSbom: true + runAsPublic: false PackageVersion: 9.0.0 BuildDropPath: '$(Build.SourcesDirectory)/artifacts' @@ -19,71 +20,63 @@ jobs: steps: - ${{ each step in parameters.steps }}: - ${{ step }} - + componentGovernanceSteps: - - template: /eng/common/templates/steps/component-governance.yml - parameters: - ${{ if eq(parameters.disableComponentGovernance, '') }}: - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.runAsPublic, 'false'), or(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/dotnet/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/microsoft/'), eq(variables['Build.SourceBranch'], 'refs/heads/main'))) }}: - disableComponentGovernance: false - ${{ else }}: - disableComponentGovernance: true + - template: /eng/common/templates/steps/component-governance.yml + parameters: + ${{ if eq(parameters.disableComponentGovernance, '') }}: + ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.runAsPublic, 'false'), or(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/dotnet/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/microsoft/'), eq(variables['Build.SourceBranch'], 'refs/heads/main'))) }}: + disableComponentGovernance: false ${{ else }}: - disableComponentGovernance: ${{ parameters.disableComponentGovernance }} - componentGovernanceIgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} - - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.enableSbom, 'true')) }}: - - template: /eng/common/templates/steps/generate-sbom.yml - parameters: - PackageVersion: ${{ parameters.packageVersion }} - BuildDropPath: ${{ parameters.buildDropPath }} - publishArtifacts: false - + disableComponentGovernance: true + ${{ else }}: + disableComponentGovernance: ${{ parameters.disableComponentGovernance }} + componentGovernanceIgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} artifactPublishSteps: - - ${{ if ne(parameters.artifacts.publish, '') }}: - - ${{ if and(ne(parameters.artifacts.publish.artifacts, 'false'), ne(parameters.artifacts.publish.artifacts, '')) }}: - - template: /eng/common/core-templates/steps/publish-build-artifacts.yml - parameters: - is1ESPipeline: false - args: - displayName: Publish pipeline artifacts - pathToPublish: '$(Build.ArtifactStagingDirectory)/artifacts' - publishLocation: Container - artifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }} - continueOnError: true - condition: always() - - ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}: - - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml - parameters: - is1ESPipeline: false - args: - targetPath: '$(Build.ArtifactStagingDirectory)/artifacts/log' - artifactName: ${{ coalesce(parameters.artifacts.publish.logs.name, 'Logs_Build_$(Agent.Os)_$(_BuildConfig)') }} - displayName: 'Publish logs' - continueOnError: true - condition: always() - sbomEnabled: false # we don't need SBOM for logs - - - ${{ if ne(parameters.enablePublishBuildArtifacts, 'false') }}: + - ${{ if ne(parameters.artifacts.publish, '') }}: + - ${{ if and(ne(parameters.artifacts.publish.artifacts, 'false'), ne(parameters.artifacts.publish.artifacts, '')) }}: - template: /eng/common/core-templates/steps/publish-build-artifacts.yml parameters: is1ESPipeline: false args: - displayName: Publish Logs - pathToPublish: '$(Build.ArtifactStagingDirectory)/artifacts/log/$(_BuildConfig)' + displayName: Publish pipeline artifacts + pathToPublish: '$(Build.ArtifactStagingDirectory)/artifacts' publishLocation: Container - artifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)' ) }} + artifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }} continueOnError: true condition: always() - - - ${{ if eq(parameters.enableBuildRetry, 'true') }}: + - ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}: - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml parameters: is1ESPipeline: false args: - targetPath: '$(Build.SourcesDirectory)\eng\common\BuildConfiguration' - artifactName: 'BuildConfiguration' - displayName: 'Publish build retry configuration' + targetPath: '$(Build.ArtifactStagingDirectory)/artifacts/log' + artifactName: ${{ coalesce(parameters.artifacts.publish.logs.name, 'Logs_Build_$(Agent.Os)_$(_BuildConfig)') }} + displayName: 'Publish logs' continueOnError: true - sbomEnabled: false # we don't need SBOM for BuildConfiguration + condition: always() + sbomEnabled: false # we don't need SBOM for logs + + - ${{ if ne(parameters.enablePublishBuildArtifacts, 'false') }}: + - template: /eng/common/core-templates/steps/publish-build-artifacts.yml + parameters: + is1ESPipeline: false + args: + displayName: Publish Logs + pathToPublish: '$(Build.ArtifactStagingDirectory)/artifacts/log/$(_BuildConfig)' + publishLocation: Container + artifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)' ) }} + continueOnError: true + condition: always() + + - ${{ if eq(parameters.enableBuildRetry, 'true') }}: + - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml + parameters: + is1ESPipeline: false + args: + targetPath: '$(Build.SourcesDirectory)\eng\common\BuildConfiguration' + artifactName: 'BuildConfiguration' + displayName: 'Publish build retry configuration' + continueOnError: true + sbomEnabled: false # we don't need SBOM for BuildConfiguration diff --git a/eng/common/templates/steps/source-index-stage1-publish.yml b/eng/common/templates/steps/source-index-stage1-publish.yml new file mode 100644 index 00000000000..182cec33a7b --- /dev/null +++ b/eng/common/templates/steps/source-index-stage1-publish.yml @@ -0,0 +1,7 @@ +steps: +- template: /eng/common/core-templates/steps/source-index-stage1-publish.yml + parameters: + is1ESPipeline: false + + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index 9574f4eb9df..22954477a57 100644 --- a/eng/common/tools.ps1 +++ b/eng/common/tools.ps1 @@ -900,7 +900,7 @@ function IsWindowsPlatform() { } function Get-Darc($version) { - $darcPath = "$TempDir\darc\$(New-Guid)" + $darcPath = "$TempDir\darc\$([guid]::NewGuid())" if ($version -ne $null) { & $PSScriptRoot\darc-init.ps1 -toolpath $darcPath -darcVersion $version | Out-Host } else { diff --git a/github-merge-flow.jsonc b/github-merge-flow.jsonc index 8dd6479f54e..9232211c085 100644 --- a/github-merge-flow.jsonc +++ b/github-merge-flow.jsonc @@ -1,7 +1,23 @@ // IMPORTANT: This file is read by the merge flow from main branch only. { "merge-flow-configurations": { + // Automate opening PRs to merge release/8.0 to release/9.0 "release/8.0":{ + "MergeToBranch": "release/9.0", + "ExtraSwitches": "-QuietComments" + }, + // Automate opening PRs to merge release/9.0-rc1 to release/9.0 + "release/9.0-rc1":{ + "MergeToBranch": "release/9.0", + "ExtraSwitches": "-QuietComments" + }, + // Automate opening PRs to merge release/9.0-rc2 to release/9.0 + "release/9.0-rc2":{ + "MergeToBranch": "release/9.0", + "ExtraSwitches": "-QuietComments" + }, + // Automate opening PRs to merge release/9.0 to main + "release/9.0":{ "MergeToBranch": "main", "ExtraSwitches": "-QuietComments" } diff --git a/global.json b/global.json index ff47bc6399d..03a0a166315 100644 --- a/global.json +++ b/global.json @@ -1,11 +1,11 @@ { "sdk": { - "version": "9.0.100-preview.5.24307.3", + "version": "9.0.100-rc.1.24452.12", "allowPrerelease": true, "rollForward": "latestMajor" }, "tools": { - "dotnet": "9.0.100-preview.5.24307.3", + "dotnet": "9.0.100-rc.1.24452.12", "runtimes": { "dotnet": [ "$(MicrosoftNETCoreAppRuntimewinx64Version)" @@ -13,7 +13,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24408.2", - "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24408.2" + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.24504.4", + "Microsoft.DotNet.Helix.Sdk": "10.0.0-beta.24504.4" } } 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.Abstractions/DeleteBehaviorAttribute.cs b/src/EFCore.Abstractions/DeleteBehaviorAttribute.cs index bc282f5b2a0..bb71f6e145a 100644 --- a/src/EFCore.Abstractions/DeleteBehaviorAttribute.cs +++ b/src/EFCore.Abstractions/DeleteBehaviorAttribute.cs @@ -19,9 +19,7 @@ public sealed class DeleteBehaviorAttribute : Attribute /// /// The to be configured. public DeleteBehaviorAttribute(DeleteBehavior behavior) - { - Behavior = behavior; - } + => Behavior = behavior; /// /// Gets the to be configured. diff --git a/src/EFCore.Abstractions/UnicodeAttribute.cs b/src/EFCore.Abstractions/UnicodeAttribute.cs index 1cc4559bd02..1c7a9253fa9 100644 --- a/src/EFCore.Abstractions/UnicodeAttribute.cs +++ b/src/EFCore.Abstractions/UnicodeAttribute.cs @@ -17,9 +17,7 @@ public sealed class UnicodeAttribute : Attribute /// /// A value indicating whether the property can contain unicode characters or not. public UnicodeAttribute(bool unicode = true) - { - IsUnicode = unicode; - } + => IsUnicode = unicode; /// /// A value indicating whether the property can contain unicode characters or not. diff --git a/src/EFCore.Analyzers/EFCore.Analyzers.csproj b/src/EFCore.Analyzers/EFCore.Analyzers.csproj index beacecfce80..4b145c8c2a1 100644 --- a/src/EFCore.Analyzers/EFCore.Analyzers.csproj +++ b/src/EFCore.Analyzers/EFCore.Analyzers.csproj @@ -10,7 +10,7 @@ $(MSBuildThisFileDirectory)..\..\rulesets\EFCore.noxmldocs.ruleset true true - NU5128 + $(NoWarn);NU5128 @@ -29,8 +29,7 @@ - - + @@ -60,4 +59,8 @@ + + + + diff --git a/src/EFCore.Cosmos/ChangeTracking/Internal/NullableEqualityComparer.cs b/src/EFCore.Cosmos/ChangeTracking/Internal/NullableEqualityComparer.cs index 7a83743c708..5d5e3abe2aa 100644 --- a/src/EFCore.Cosmos/ChangeTracking/Internal/NullableEqualityComparer.cs +++ b/src/EFCore.Cosmos/ChangeTracking/Internal/NullableEqualityComparer.cs @@ -21,9 +21,7 @@ public class NullableEqualityComparer : IEqualityComparer /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public NullableEqualityComparer(IEqualityComparer underlyingComparer) - { - _underlyingComparer = underlyingComparer; - } + => _underlyingComparer = underlyingComparer; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Cosmos/ChangeTracking/Internal/StringDictionaryComparer.cs b/src/EFCore.Cosmos/ChangeTracking/Internal/StringDictionaryComparer.cs index 21b8f7fbf53..aa4589d54b8 100644 --- a/src/EFCore.Cosmos/ChangeTracking/Internal/StringDictionaryComparer.cs +++ b/src/EFCore.Cosmos/ChangeTracking/Internal/StringDictionaryComparer.cs @@ -34,9 +34,7 @@ public StringDictionaryComparer(ValueComparer elementComparer) CompareLambda(elementComparer), GetHashCodeLambda(elementComparer), SnapshotLambda(elementComparer)) - { - ElementComparer = elementComparer; - } + => ElementComparer = elementComparer; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -46,7 +44,8 @@ public StringDictionaryComparer(ValueComparer elementComparer) /// public ValueComparer ElementComparer { get; } - ValueComparer IInfrastructure.Instance => ElementComparer; + ValueComparer IInfrastructure.Instance + => ElementComparer; private static Expression> CompareLambda(ValueComparer elementComparer) { diff --git a/src/EFCore.Cosmos/Diagnostics/CosmosEventId.cs b/src/EFCore.Cosmos/Diagnostics/CosmosEventId.cs index dfbc3cceb71..aa0940b2bac 100644 --- a/src/EFCore.Cosmos/Diagnostics/CosmosEventId.cs +++ b/src/EFCore.Cosmos/Diagnostics/CosmosEventId.cs @@ -41,7 +41,6 @@ private enum Id // Model validation events NoPartitionKeyDefined = CoreEventId.ProviderBaseId + 600, - } private static readonly string DatabasePrefix = DbLoggerCategory.Database.Name + "."; diff --git a/src/EFCore.Cosmos/Diagnostics/Internal/CosmosLoggerExtensions.cs b/src/EFCore.Cosmos/Diagnostics/Internal/CosmosLoggerExtensions.cs index 1c6d629221d..bf458d70a81 100644 --- a/src/EFCore.Cosmos/Diagnostics/Internal/CosmosLoggerExtensions.cs +++ b/src/EFCore.Cosmos/Diagnostics/Internal/CosmosLoggerExtensions.cs @@ -508,7 +508,8 @@ public static void PrimaryKeyValueNotSet( { var eventData = new PropertyEventData( definition, - (d, p) => ((EventDefinition)d).GenerateMessage(((PropertyEventData)p).Property.DeclaringType.DisplayName(), ((PropertyEventData)p).Property.Name), + (d, p) => ((EventDefinition)d).GenerateMessage( + ((PropertyEventData)p).Property.DeclaringType.DisplayName(), ((PropertyEventData)p).Property.Name), property); diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); } diff --git a/src/EFCore.Cosmos/EFCore.Cosmos.csproj b/src/EFCore.Cosmos/EFCore.Cosmos.csproj index 4b064e25562..43c07d376d6 100644 --- a/src/EFCore.Cosmos/EFCore.Cosmos.csproj +++ b/src/EFCore.Cosmos/EFCore.Cosmos.csproj @@ -43,12 +43,12 @@ - + - + diff --git a/src/EFCore.Cosmos/Extensions/CosmosDbFunctionsExtensions.cs b/src/EFCore.Cosmos/Extensions/CosmosDbFunctionsExtensions.cs index f562fa59c36..3dc681450be 100644 --- a/src/EFCore.Cosmos/Extensions/CosmosDbFunctionsExtensions.cs +++ b/src/EFCore.Cosmos/Extensions/CosmosDbFunctionsExtensions.cs @@ -43,7 +43,9 @@ public static bool IsDefined(this DbFunctions _, object? expression) /// will be returned. /// /// The expression to be returned if is undefined. - /// Cosmos coalesce operator + /// + /// Cosmos coalesce operator + /// public static T CoalesceUndefined( this DbFunctions _, T expression1, @@ -52,7 +54,9 @@ public static T CoalesceUndefined( /// /// Returns the distance between two vectors, using the distance function and data type defined using - /// . + /// + /// . /// /// The instance. /// The first vector. @@ -67,9 +71,11 @@ public static double VectorDistance(this DbFunctions _, ReadOnlyMemory vec /// The instance. /// The first vector. /// The second vector. - /// A specifying how the computed value is used in an ORDER BY - /// expression. If , then brute force is used, otherwise any index defined on the vector - /// property is leveraged. + /// + /// A specifying how the computed value is used in an ORDER BY + /// expression. If , then brute force is used, otherwise any index defined on the vector + /// property is leveraged. + /// [Experimental(EFDiagnostics.CosmosVectorSearchExperimental)] public static double VectorDistance( this DbFunctions _, @@ -85,9 +91,11 @@ public static double VectorDistance( /// The first vector. /// The second vector. /// The distance function to use. - /// A specifying how the computed value is used in an ORDER BY - /// expression. If , then brute force is used, otherwise any index defined on the vector - /// property is leveraged. + /// + /// A specifying how the computed value is used in an ORDER BY + /// expression. If , then brute force is used, otherwise any index defined on the vector + /// property is leveraged. + /// [Experimental(EFDiagnostics.CosmosVectorSearchExperimental)] public static double VectorDistance( this DbFunctions _, @@ -99,7 +107,9 @@ public static double VectorDistance( /// /// Returns the distance between two vectors, using the distance function and data type defined using - /// . + /// + /// . /// /// The instance. /// The first vector. @@ -114,9 +124,11 @@ public static double VectorDistance(this DbFunctions _, ReadOnlyMemory ve /// The instance. /// The first vector. /// The second vector. - /// A specifying how the computed value is used in an ORDER BY - /// expression. If , then brute force is used, otherwise any index defined on the vector - /// property is leveraged. + /// + /// A specifying how the computed value is used in an ORDER BY + /// expression. If , then brute force is used, otherwise any index defined on the vector + /// property is leveraged. + /// [Experimental(EFDiagnostics.CosmosVectorSearchExperimental)] public static double VectorDistance( this DbFunctions _, @@ -132,9 +144,11 @@ public static double VectorDistance( /// The first vector. /// The second vector. /// The distance function to use. - /// A specifying how the computed value is used in an ORDER BY - /// expression. If , then brute force is used, otherwise any index defined on the vector - /// property is leveraged. + /// + /// A specifying how the computed value is used in an ORDER BY + /// expression. If , then brute force is used, otherwise any index defined on the vector + /// property is leveraged. + /// [Experimental(EFDiagnostics.CosmosVectorSearchExperimental)] public static double VectorDistance( this DbFunctions _, @@ -146,7 +160,9 @@ public static double VectorDistance( /// /// Returns the distance between two vectors, using the distance function and data type defined using - /// . + /// + /// . /// /// The instance. /// The first vector. @@ -161,9 +177,11 @@ public static double VectorDistance(this DbFunctions _, ReadOnlyMemory ve /// The instance. /// The first vector. /// The second vector. - /// A specifying how the computed value is used in an ORDER BY - /// expression. If , then brute force is used, otherwise any index defined on the vector - /// property is leveraged. + /// + /// A specifying how the computed value is used in an ORDER BY + /// expression. If , then brute force is used, otherwise any index defined on the vector + /// property is leveraged. + /// [Experimental(EFDiagnostics.CosmosVectorSearchExperimental)] public static double VectorDistance( this DbFunctions _, @@ -179,9 +197,11 @@ public static double VectorDistance( /// The first vector. /// The second vector. /// The distance function to use. - /// A specifying how the computed value is used in an ORDER BY - /// expression. If , then brute force is used, otherwise any index defined on the vector - /// property is leveraged. + /// + /// A specifying how the computed value is used in an ORDER BY + /// expression. If , then brute force is used, otherwise any index defined on the vector + /// property is leveraged. + /// [Experimental(EFDiagnostics.CosmosVectorSearchExperimental)] public static double VectorDistance( this DbFunctions _, diff --git a/src/EFCore.Cosmos/Extensions/CosmosEntityTypeBuilderExtensions.cs b/src/EFCore.Cosmos/Extensions/CosmosEntityTypeBuilderExtensions.cs index f62d3e37777..e801beb2235 100644 --- a/src/EFCore.Cosmos/Extensions/CosmosEntityTypeBuilderExtensions.cs +++ b/src/EFCore.Cosmos/Extensions/CosmosEntityTypeBuilderExtensions.cs @@ -531,7 +531,7 @@ public static EntityTypeBuilder HasDiscriminatorInJsonId( /// to revert to the default setting. /// /// The same builder instance so that multiple calls can be chained. - public static EntityTypeBuilder IncludeRootDiscriminatorInJsonId( + public static EntityTypeBuilder HasRootDiscriminatorInJsonId( this EntityTypeBuilder entityTypeBuilder, bool? includeDiscriminator = true) { @@ -559,7 +559,8 @@ public static EntityTypeBuilder IncludeRootDiscriminatorInJsonId( /// /// The same builder instance so that multiple calls can be chained. public static EntityTypeBuilder HasDiscriminatorInJsonId( - this EntityTypeBuilder entityTypeBuilder, bool? includeDiscriminator = true) + this EntityTypeBuilder entityTypeBuilder, + bool? includeDiscriminator = true) where TEntity : class => (EntityTypeBuilder)HasDiscriminatorInJsonId((EntityTypeBuilder)entityTypeBuilder, includeDiscriminator); @@ -577,10 +578,11 @@ public static EntityTypeBuilder HasDiscriminatorInJsonId( /// to revert to the default setting. /// /// The same builder instance so that multiple calls can be chained. - public static EntityTypeBuilder IncludeRootDiscriminatorInJsonId( - this EntityTypeBuilder entityTypeBuilder, bool? includeDiscriminator = true) + public static EntityTypeBuilder HasRootDiscriminatorInJsonId( + this EntityTypeBuilder entityTypeBuilder, + bool? includeDiscriminator = true) where TEntity : class - => (EntityTypeBuilder)IncludeRootDiscriminatorInJsonId((EntityTypeBuilder)entityTypeBuilder, includeDiscriminator); + => (EntityTypeBuilder)HasRootDiscriminatorInJsonId((EntityTypeBuilder)entityTypeBuilder, includeDiscriminator); /// /// Includes the discriminator value of the entity type in the JSON "id" value. This was the default behavior before EF Core 9. @@ -597,7 +599,9 @@ public static EntityTypeBuilder IncludeRootDiscriminatorInJsonIdIndicates whether the configuration was specified using a data annotation. /// The same builder instance if the configuration was applied, otherwise. public static IConventionEntityTypeBuilder? HasDiscriminatorInJsonId( - this IConventionEntityTypeBuilder entityTypeBuilder, bool? includeDiscriminator, bool fromDataAnnotation = false) + this IConventionEntityTypeBuilder entityTypeBuilder, + bool? includeDiscriminator, + bool fromDataAnnotation = false) { if (!entityTypeBuilder.CanSetDiscriminatorInJsonId(includeDiscriminator, fromDataAnnotation)) { @@ -629,10 +633,12 @@ public static EntityTypeBuilder IncludeRootDiscriminatorInJsonId /// Indicates whether the configuration was specified using a data annotation. /// The same builder instance if the configuration was applied, otherwise. - public static IConventionEntityTypeBuilder? IncludeRootDiscriminatorInJsonId( - this IConventionEntityTypeBuilder entityTypeBuilder, bool? includeDiscriminator, bool fromDataAnnotation = false) + public static IConventionEntityTypeBuilder? HasRootDiscriminatorInJsonId( + this IConventionEntityTypeBuilder entityTypeBuilder, + bool? includeDiscriminator, + bool fromDataAnnotation = false) { - if (!entityTypeBuilder.CanSetIncludeRootDiscriminatorInJsonId(includeDiscriminator, fromDataAnnotation)) + if (!entityTypeBuilder.CanSetRootDiscriminatorInJsonId(includeDiscriminator, fromDataAnnotation)) { return null; } @@ -678,7 +684,6 @@ public static bool CanSetDiscriminatorInJsonId( : IdDiscriminatorMode.None, fromDataAnnotation); } - /// /// Returns a value indicating whether the setting for including the discriminator can be set /// from the current configuration source @@ -694,7 +699,7 @@ public static bool CanSetDiscriminatorInJsonId( /// /// Indicates whether the configuration was specified using a data annotation. /// if the configuration can be applied. - public static bool CanSetIncludeRootDiscriminatorInJsonId( + public static bool CanSetRootDiscriminatorInJsonId( this IConventionEntityTypeBuilder entityTypeBuilder, bool? includeDiscriminator, bool fromDataAnnotation = false) diff --git a/src/EFCore.Cosmos/Extensions/CosmosEntityTypeExtensions.cs b/src/EFCore.Cosmos/Extensions/CosmosEntityTypeExtensions.cs index 9ca08c71e0a..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 @@ -194,17 +198,17 @@ public static void SetPartitionKeyPropertyName(this IMutableEntityType entityTyp /// Returns the names of the properties that are used to store the hierarchical partition key, if any. /// /// The entity type. - /// The names of the partition key properties, or if not set. + /// The names of the partition key properties, or if not set. 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. /// /// The entity type. - /// The names to set, or to clear all names. + /// The names to set, or to clear all names. public static void SetPartitionKeyPropertyNames(this IMutableEntityType entityType, IReadOnlyList? names) => entityType.SetOrRemoveAnnotation( CosmosAnnotationNames.PartitionKeyNames, names is null ? names : Check.HasNoEmptyElements(names, nameof(names))); @@ -352,7 +356,7 @@ public static void SetETagPropertyName(this IMutableEntityType entityType, strin /// /// to force __id creation, to not force __id creation, /// to revert to the default setting. - /// . + /// public static bool? GetHasShadowId(this IReadOnlyEntityType entityType) => (entityType.BaseType != null ? entityType.GetRootType().GetHasShadowId() @@ -389,7 +393,7 @@ public static void SetHasShadowId(this IMutableEntityType entityType, bool? alwa CosmosAnnotationNames.HasShadowId, alwaysCreate, fromDataAnnotation)?.Value; /// - /// Gets the for . + /// Gets the for . /// /// The entity typer. /// The . @@ -401,7 +405,7 @@ public static void SetHasShadowId(this IMutableEntityType entityType, bool? alwa /// Prior to EF Core 9, it was always included. Starting with EF Core 9, it is not included by default. /// /// The entity type. - /// The or if not set. + /// The or if not set. public static IdDiscriminatorMode? GetDiscriminatorInKey(this IReadOnlyEntityType entityType) => (entityType.BaseType != null ? entityType.GetRootType().GetDiscriminatorInKey() @@ -423,12 +427,14 @@ public static void SetDiscriminatorInKey(this IMutableEntityType entityType, IdD /// The behavior to use, or to reset the behavior to the default. /// Indicates whether the configuration was specified using a data annotation. public static IdDiscriminatorMode? SetDiscriminatorInKey( - this IConventionEntityType entityType, IdDiscriminatorMode? behavior, bool fromDataAnnotation = false) + this IConventionEntityType entityType, + IdDiscriminatorMode? behavior, + bool fromDataAnnotation = false) => (IdDiscriminatorMode?)entityType.SetOrRemoveAnnotation( CosmosAnnotationNames.DiscriminatorInKey, behavior, fromDataAnnotation)?.Value; /// - /// Gets the for . + /// Gets the for . /// /// The entity typer. /// The . diff --git a/src/EFCore.Cosmos/Extensions/CosmosIndexBuilderExtensions.cs b/src/EFCore.Cosmos/Extensions/CosmosIndexBuilderExtensions.cs index ed0a40b8ce7..217e3691eae 100644 --- a/src/EFCore.Cosmos/Extensions/CosmosIndexBuilderExtensions.cs +++ b/src/EFCore.Cosmos/Extensions/CosmosIndexBuilderExtensions.cs @@ -8,7 +8,7 @@ namespace Microsoft.EntityFrameworkCore; /// -/// Azure Cosmos DB-specific extension methods for . +/// Azure Cosmos DB-specific extension methods for . /// /// /// See Modeling entity types and relationships, and diff --git a/src/EFCore.Cosmos/Extensions/CosmosIndexExtensions.cs b/src/EFCore.Cosmos/Extensions/CosmosIndexExtensions.cs index 9692a128068..6f9ab7b6184 100644 --- a/src/EFCore.Cosmos/Extensions/CosmosIndexExtensions.cs +++ b/src/EFCore.Cosmos/Extensions/CosmosIndexExtensions.cs @@ -55,7 +55,7 @@ public static void SetVectorIndexType(this IMutableIndex index, VectorIndexType? fromDataAnnotation)?.Value; /// - /// Returns the for whether the . + /// Returns the for whether the . /// /// The property. /// The for whether the index is clustered. diff --git a/src/EFCore.Cosmos/Extensions/CosmosModelBuilderExtensions.cs b/src/EFCore.Cosmos/Extensions/CosmosModelBuilderExtensions.cs index f4a8c1e91df..ad6064ebab2 100644 --- a/src/EFCore.Cosmos/Extensions/CosmosModelBuilderExtensions.cs +++ b/src/EFCore.Cosmos/Extensions/CosmosModelBuilderExtensions.cs @@ -165,7 +165,7 @@ public static ModelBuilder HasDiscriminatorInJsonIds( /// to revert to the default setting. /// /// The same builder instance so that multiple calls can be chained. - public static ModelBuilder IncludeRootDiscriminatorInJsonId( + public static ModelBuilder HasRootDiscriminatorInJsonId( this ModelBuilder modelBuilder, bool? includeDiscriminator = true) { diff --git a/src/EFCore.Cosmos/Extensions/CosmosModelExtensions.cs b/src/EFCore.Cosmos/Extensions/CosmosModelExtensions.cs index e187219cb8b..da9671f361a 100644 --- a/src/EFCore.Cosmos/Extensions/CosmosModelExtensions.cs +++ b/src/EFCore.Cosmos/Extensions/CosmosModelExtensions.cs @@ -96,7 +96,7 @@ public static void SetHasShadowIds(this IMutableModel model, bool? alwaysCreate) /// /// Gets the - /// for . + /// for . /// /// The model. /// The . @@ -108,7 +108,7 @@ public static void SetHasShadowIds(this IMutableModel model, bool? alwaysCreate) /// Prior to EF Core 9, it was always included. Starting with EF Core 9, it is not included by default. /// /// The model. - /// The or if not set. + /// The or if not set. public static IdDiscriminatorMode? GetDiscriminatorInKey(this IReadOnlyModel model) => (IdDiscriminatorMode?)model[CosmosAnnotationNames.DiscriminatorInKey]; @@ -135,7 +135,7 @@ public static void SetDiscriminatorInKey(this IMutableModel model, IdDiscriminat /// /// Gets the - /// for . + /// for . /// /// The model. /// The . diff --git a/src/EFCore.Cosmos/Extensions/CosmosPropertyExtensions.cs b/src/EFCore.Cosmos/Extensions/CosmosPropertyExtensions.cs index c4e0cb43466..6439a41eee7 100644 --- a/src/EFCore.Cosmos/Extensions/CosmosPropertyExtensions.cs +++ b/src/EFCore.Cosmos/Extensions/CosmosPropertyExtensions.cs @@ -109,7 +109,10 @@ public static void SetVectorType(this IMutableProperty property, CosmosVectorTyp /// Indicates whether the configuration was specified using a data annotation. /// The configured value. [Experimental(EFDiagnostics.CosmosVectorSearchExperimental)] - public static CosmosVectorType? SetVectorType(this IConventionProperty property, CosmosVectorType? vectorType, bool fromDataAnnotation = false) + public static CosmosVectorType? SetVectorType( + this IConventionProperty property, + CosmosVectorType? vectorType, + bool fromDataAnnotation = false) => (CosmosVectorType?)property.SetOrRemoveAnnotation( CosmosAnnotationNames.VectorType, vectorType, diff --git a/src/EFCore.Cosmos/Extensions/CosmosQueryableExtensions.cs b/src/EFCore.Cosmos/Extensions/CosmosQueryableExtensions.cs index 68417190ef9..70bc240dfb8 100644 --- a/src/EFCore.Cosmos/Extensions/CosmosQueryableExtensions.cs +++ b/src/EFCore.Cosmos/Extensions/CosmosQueryableExtensions.cs @@ -18,14 +18,24 @@ namespace Microsoft.EntityFrameworkCore; /// public static class CosmosQueryableExtensions { - internal static readonly MethodInfo WithPartitionKeyMethodInfo + internal static readonly MethodInfo WithPartitionKeyMethodInfo1 + = typeof(CosmosQueryableExtensions).GetTypeInfo() + .GetDeclaredMethods(nameof(WithPartitionKey)) + .Single(mi => mi.GetParameters().Length == 2); + + internal static readonly MethodInfo WithPartitionKeyMethodInfo2 = typeof(CosmosQueryableExtensions).GetTypeInfo() .GetDeclaredMethods(nameof(WithPartitionKey)) .Single(mi => mi.GetParameters().Length == 3); + internal static readonly MethodInfo WithPartitionKeyMethodInfo3 + = typeof(CosmosQueryableExtensions).GetTypeInfo() + .GetDeclaredMethods(nameof(WithPartitionKey)) + .Single(mi => mi.GetParameters().Length == 4); + /// - /// Specify the partition key value for partition used for the query. Required when using - /// a resource token that provides permission based on a partition key for authentication. + /// Specify the partition key for partition used for the query. + /// Required when using a resource token that provides permission based on a partition key for authentication, /// /// /// See Querying data with EF Core, and @@ -33,15 +43,27 @@ internal static readonly MethodInfo WithPartitionKeyMethodInfo /// /// The type of entity being queried. /// The source query. - /// The partition key value. + /// The partition key value. /// A new query with the set partition key. - public static IQueryable WithPartitionKey(this IQueryable source, string partitionKey) + public static IQueryable WithPartitionKey(this IQueryable source, object partitionKeyValue) where TEntity : class - => WithPartitionKey(source, partitionKey, []); + { + Check.NotNull(partitionKeyValue, nameof(partitionKeyValue)); + + return + source.Provider is EntityQueryProvider + ? source.Provider.CreateQuery( + Expression.Call( + instance: null, + method: WithPartitionKeyMethodInfo1.MakeGenericMethod(typeof(TEntity)), + source.Expression, + Expression.Constant(partitionKeyValue, typeof(object)))) + : source; + } /// - /// Specify the partition key for partition used for the query. Required when using - /// a resource token that provides permission based on a partition key for authentication, + /// Specify the partition key for partition used for the query. + /// Required when using a resource token that provides permission based on a partition key for authentication, /// /// /// See Querying data with EF Core, and @@ -49,27 +71,65 @@ public static IQueryable WithPartitionKey(this IQueryable /// The type of entity being queried. /// The source query. - /// The partition key value. - /// Additional values for hierarchical partitions. + /// The first value in a hierarchical partition key. + /// The second value in a hierarchical partition key. /// A new query with the set partition key. public static IQueryable WithPartitionKey( this IQueryable source, - object partitionKeyValue, - params object[] additionalPartitionKeyValues) + object partitionKeyValue1, + object partitionKeyValue2) where TEntity : class { - Check.NotNull(partitionKeyValue, nameof(partitionKeyValue)); - Check.HasNoNulls(additionalPartitionKeyValues, nameof(additionalPartitionKeyValues)); + Check.NotNull(partitionKeyValue1, nameof(partitionKeyValue1)); + Check.NotNull(partitionKeyValue2, nameof(partitionKeyValue2)); + + return + source.Provider is EntityQueryProvider + ? source.Provider.CreateQuery( + Expression.Call( + instance: null, + method: WithPartitionKeyMethodInfo2.MakeGenericMethod(typeof(TEntity)), + source.Expression, + Expression.Constant(partitionKeyValue1, typeof(object)), + Expression.Constant(partitionKeyValue2, typeof(object)))) + : source; + } + + /// + /// Specify the partition key for partition used for the query. + /// Required when using a resource token that provides permission based on a partition key for authentication, + /// + /// + /// See Querying data with EF Core, and + /// Accessing Azure Cosmos DB with EF Core for more information and examples. + /// + /// The type of entity being queried. + /// The source query. + /// The first value in a hierarchical partition key. + /// The second value in a hierarchical partition key. + /// The third value in a hierarchical partition key. + /// A new query with the set partition key. + public static IQueryable WithPartitionKey( + this IQueryable source, + object partitionKeyValue1, + object partitionKeyValue2, + object partitionKeyValue3) + where TEntity : class + { + Check.NotNull(partitionKeyValue1, nameof(partitionKeyValue1)); + Check.NotNull(partitionKeyValue2, nameof(partitionKeyValue2)); + Check.NotNull(partitionKeyValue3, nameof(partitionKeyValue3)); return source.Provider is EntityQueryProvider ? source.Provider.CreateQuery( Expression.Call( instance: null, - method: WithPartitionKeyMethodInfo.MakeGenericMethod(typeof(TEntity)), + method: WithPartitionKeyMethodInfo3.MakeGenericMethod(typeof(TEntity)), source.Expression, - Expression.Constant(partitionKeyValue, typeof(object)), - Expression.Constant(additionalPartitionKeyValues, typeof(object[])))) + Expression.Constant(partitionKeyValue1, typeof(object)), + Expression.Constant(partitionKeyValue2, typeof(object)), + Expression.Constant(partitionKeyValue3, typeof(object)))) : source; } @@ -180,7 +240,6 @@ private static FromSqlQueryRootExpression GenerateFromSqlQueryRoot( internal static readonly MethodInfo ToPageAsyncMethodInfo = typeof(CosmosQueryableExtensions).GetMethod(nameof(ToPageAsync))!; - /// /// Allows paginating through query results by repeatedly executing the same query, passing continuation tokens to retrieve /// successive pages of the result set, and specifying the maximum number of results per page. diff --git a/src/EFCore.Cosmos/Extensions/Embedding.cs b/src/EFCore.Cosmos/Extensions/Embedding.cs index f700da1653c..e46c274d887 100644 --- a/src/EFCore.Cosmos/Extensions/Embedding.cs +++ b/src/EFCore.Cosmos/Extensions/Embedding.cs @@ -13,6 +13,7 @@ internal class Embedding : IEquatable public VectorDataType DataType { get; set; } public int Dimensions { get; set; } public DistanceFunction DistanceFunction { get; set; } + public bool Equals(Embedding? that) => Equals(Path, that?.Path) && Equals(DataType, that?.DataType) && Equals(Dimensions, that.Dimensions); } diff --git a/src/EFCore.Cosmos/Infrastructure/CosmosDbContextOptionsBuilder.cs b/src/EFCore.Cosmos/Infrastructure/CosmosDbContextOptionsBuilder.cs index 85a1cd37136..32305e525b4 100644 --- a/src/EFCore.Cosmos/Infrastructure/CosmosDbContextOptionsBuilder.cs +++ b/src/EFCore.Cosmos/Infrastructure/CosmosDbContextOptionsBuilder.cs @@ -34,9 +34,7 @@ public class CosmosDbContextOptionsBuilder : ICosmosDbContextOptionsBuilderInfra /// /// The options builder. public CosmosDbContextOptionsBuilder(DbContextOptionsBuilder optionsBuilder) - { - _optionsBuilder = optionsBuilder; - } + => _optionsBuilder = optionsBuilder; /// DbContextOptionsBuilder ICosmosDbContextOptionsBuilderInfrastructure.OptionsBuilder diff --git a/src/EFCore.Cosmos/Infrastructure/Internal/CosmosDbOptionExtension.cs b/src/EFCore.Cosmos/Infrastructure/Internal/CosmosDbOptionExtension.cs index a948636884c..f2545174ac3 100644 --- a/src/EFCore.Cosmos/Infrastructure/Internal/CosmosDbOptionExtension.cs +++ b/src/EFCore.Cosmos/Infrastructure/Internal/CosmosDbOptionExtension.cs @@ -5,7 +5,6 @@ using System.Net; using System.Text; using Azure.Core; -using Microsoft.EntityFrameworkCore.Cosmos.Internal; namespace Microsoft.EntityFrameworkCore.Cosmos.Infrastructure.Internal; diff --git a/src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelRuntimeInitializer.cs b/src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelRuntimeInitializer.cs index 40ebe958f43..3d368546f6d 100644 --- a/src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelRuntimeInitializer.cs +++ b/src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelRuntimeInitializer.cs @@ -25,9 +25,7 @@ public CosmosModelRuntimeInitializer( ModelRuntimeInitializerDependencies dependencies, CosmosModelRuntimeInitializerDependencies cosmosDependencies) : base(dependencies) - { - CosmosDependencies = cosmosDependencies; - } + => CosmosDependencies = cosmosDependencies; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelRuntimeInitializerDependencies.cs b/src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelRuntimeInitializerDependencies.cs index c82e63a9056..298f96599c1 100644 --- a/src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelRuntimeInitializerDependencies.cs +++ b/src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelRuntimeInitializerDependencies.cs @@ -29,9 +29,7 @@ public sealed record CosmosModelRuntimeInitializerDependencies /// [EntityFrameworkInternal] public CosmosModelRuntimeInitializerDependencies(IJsonIdDefinitionFactory jsonIdDefinitionFactory) - { - JsonIdDefinitionFactory = jsonIdDefinitionFactory; - } + => JsonIdDefinitionFactory = jsonIdDefinitionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Cosmos/Infrastructure/Internal/CosmosSingletonOptions.cs b/src/EFCore.Cosmos/Infrastructure/Internal/CosmosSingletonOptions.cs index dd911b7206c..af29229cfa5 100644 --- a/src/EFCore.Cosmos/Infrastructure/Internal/CosmosSingletonOptions.cs +++ b/src/EFCore.Cosmos/Infrastructure/Internal/CosmosSingletonOptions.cs @@ -141,7 +141,7 @@ public class CosmosSingletonOptions : ICosmosSingletonOptions /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public virtual bool? EnableContentResponseOnWrite { get; private set; } + public virtual bool? EnableContentResponseOnWrite { get; } /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Cosmos/Metadata/Conventions/ContextContainerConvention.cs b/src/EFCore.Cosmos/Metadata/Conventions/ContextContainerConvention.cs index a5654dec91b..e981912ae68 100644 --- a/src/EFCore.Cosmos/Metadata/Conventions/ContextContainerConvention.cs +++ b/src/EFCore.Cosmos/Metadata/Conventions/ContextContainerConvention.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.Metadata.Conventions; /// @@ -18,9 +19,7 @@ public class ContextContainerConvention : IModelInitializedConvention /// /// Parameter object containing dependencies for this convention. public ContextContainerConvention(ProviderConventionSetBuilderDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore.Cosmos/Metadata/Conventions/CosmosDiscriminatorConvention.cs b/src/EFCore.Cosmos/Metadata/Conventions/CosmosDiscriminatorConvention.cs index ea91a2777fe..fd42271c82b 100644 --- a/src/EFCore.Cosmos/Metadata/Conventions/CosmosDiscriminatorConvention.cs +++ b/src/EFCore.Cosmos/Metadata/Conventions/CosmosDiscriminatorConvention.cs @@ -30,13 +30,13 @@ public CosmosDiscriminatorConvention(ProviderConventionSetBuilderDependencies de { } - /// + /// public virtual void ProcessEntityTypeAdded( IConventionEntityTypeBuilder entityTypeBuilder, IConventionContext context) => ProcessEntityType(entityTypeBuilder); - /// + /// public virtual void ProcessForeignKeyOwnershipChanged( IConventionForeignKeyBuilder relationshipBuilder, IConventionContext context) @@ -46,7 +46,7 @@ public virtual void ProcessForeignKeyOwnershipChanged( ProcessEntityType(entityType.Builder); } - /// + /// public virtual void ProcessForeignKeyRemoved( IConventionEntityTypeBuilder entityTypeBuilder, IConventionForeignKey foreignKey, @@ -59,7 +59,7 @@ public virtual void ProcessForeignKeyRemoved( } } - /// + /// public virtual void ProcessEntityTypeAnnotationChanged( IConventionEntityTypeBuilder entityTypeBuilder, string name, @@ -95,7 +95,7 @@ private static void ProcessEntityType(IConventionEntityTypeBuilder entityTypeBui } } - /// + /// public override void ProcessDiscriminatorPropertySet( IConventionEntityTypeBuilder entityTypeBuilder, string? name, @@ -108,7 +108,7 @@ public override void ProcessDiscriminatorPropertySet( } } - /// + /// public override void ProcessEntityTypeBaseTypeChanged( IConventionEntityTypeBuilder entityTypeBuilder, IConventionEntityType? newBaseType, @@ -145,7 +145,7 @@ public override void ProcessEntityTypeBaseTypeChanged( } } - /// + /// protected override void SetDefaultDiscriminatorValues( IEnumerable entityTypes, IConventionDiscriminatorBuilder discriminatorBuilder) @@ -156,7 +156,7 @@ protected override void SetDefaultDiscriminatorValues( } } - /// + /// public override void ProcessEntityTypeRemoved( IConventionModelBuilder modelBuilder, IConventionEntityType entityType, @@ -164,7 +164,7 @@ public override void ProcessEntityTypeRemoved( { } - /// + /// public virtual void ProcessEmbeddedDiscriminatorName( IConventionModelBuilder modelBuilder, string? newName, diff --git a/src/EFCore.Cosmos/Metadata/Conventions/CosmosJsonIdConvention.cs b/src/EFCore.Cosmos/Metadata/Conventions/CosmosJsonIdConvention.cs index 0d19d7cb3ab..130041d556d 100644 --- a/src/EFCore.Cosmos/Metadata/Conventions/CosmosJsonIdConvention.cs +++ b/src/EFCore.Cosmos/Metadata/Conventions/CosmosJsonIdConvention.cs @@ -51,7 +51,7 @@ public class CosmosJsonIdConvention /// Creates a new instance of . /// /// Parameter object containing dependencies for this convention. - /// The factory to create a for each entity type. + /// The factory to create a for each entity type. public CosmosJsonIdConvention( ProviderConventionSetBuilderDependencies dependencies, IJsonIdDefinitionFactory definitionFactory) @@ -66,7 +66,7 @@ public CosmosJsonIdConvention( protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } /// - /// The factory to create a for each entity type. + /// The factory to create a for each entity type. /// protected virtual IJsonIdDefinitionFactory DefinitionFactory { get; } @@ -78,22 +78,22 @@ private void ProcessEntityType(IConventionEntityType entityType, IConventionCont var primaryKey = entityType.FindPrimaryKey(); if (entityType.BaseType != null // Requires: IEntityTypeBaseTypeChangedConvention || !entityType.IsDocumentRoot() // Requires: IEntityTypeAnnotationChangedConvention (ContainerName) - || entityType.GetForeignKeys().Any(fk => fk.IsOwnership) // Requires: IForeignKeyOwnershipChangedConvention, IForeignKeyRemovedConvention + || entityType.GetForeignKeys() + .Any(fk => fk.IsOwnership) // Requires: IForeignKeyOwnershipChangedConvention, IForeignKeyRemovedConvention || primaryKey == null) // Requires: IKeyAddedConvention, IKeyRemovedConvention { // If the entity type is not a keyed, root document in the container, then it doesn't have an `id` mapping, so // undo anything that was done by previous execution of this convention. - if (jsonIdProperty != null) + if (jsonIdProperty is not null) { jsonIdProperty.Builder.ToJsonProperty(null); - entityType.Builder.HasNoProperty(jsonIdProperty); + entityType.Builder.RemoveUnusedImplicitProperties([jsonIdProperty]); } - if (computedIdProperty != null + if (computedIdProperty is not null && computedIdProperty != jsonIdProperty) { - entityType.Builder.HasNoProperty(computedIdProperty); - } + entityType.Builder.RemoveUnusedImplicitProperties([computedIdProperty]); } return; } @@ -114,10 +114,17 @@ private void ProcessEntityType(IConventionEntityType entityType, IConventionCont // - IDiscriminatorPropertySetConvention // - IEntityTypeBaseTypeChangedConvention var idDefinition = DefinitionFactory.Create((IEntityType)entityType)!; - var keyProperty = (IConventionProperty?)idDefinition.Properties.FirstOrDefault(); if (idDefinition is { IncludesDiscriminator: false, Properties.Count: 1 }) { - var clrType = keyProperty!.GetValueConverter()?.ProviderClrType ?? keyProperty.ClrType; + // If the property maps to a string in the JSON document, then we can use it directly, even if a value converter + // is applied. On the other hand, if it maps to a numeric or bool, then we need to duplicate this to preserve the + // non-string value for queries. + var keyProperty = (IConventionProperty)idDefinition.Properties.First(); + var mapping = Dependencies.TypeMappingSource.FindMapping((IProperty)keyProperty); + var clrType = mapping?.Converter?.ProviderClrType + ?? mapping?.ClrType + ?? keyProperty!.ClrType; + if (clrType == typeof(string)) { // We are at the point where we are going to map the `id` directly to the PK. @@ -227,6 +234,7 @@ public virtual void ProcessEntityTypeAnnotationChanged( { ProcessEntityType(entityTypeBuilder.Metadata, context); } + break; case CosmosAnnotationNames.HasShadowId: @@ -235,12 +243,15 @@ public virtual void ProcessEntityTypeAnnotationChanged( { ProcessEntityType(entityTypeBuilder.Metadata, context); } + break; } } /// - public virtual void ProcessForeignKeyOwnershipChanged(IConventionForeignKeyBuilder relationshipBuilder, IConventionContext context) + public virtual void ProcessForeignKeyOwnershipChanged( + IConventionForeignKeyBuilder relationshipBuilder, + IConventionContext context) => ProcessEntityType(relationshipBuilder.Metadata.DeclaringEntityType, context); /// @@ -262,7 +273,9 @@ public virtual void ProcessKeyRemoved( } /// - public virtual void ProcessPropertyAdded(IConventionPropertyBuilder propertyBuilder, IConventionContext context) + public virtual void ProcessPropertyAdded( + IConventionPropertyBuilder propertyBuilder, + IConventionContext context) => ProcessEntityType(propertyBuilder.Metadata.DeclaringType.ContainingEntityType, context); /// diff --git a/src/EFCore.Cosmos/Metadata/Conventions/CosmosManyToManyJoinEntityTypeConvention.cs b/src/EFCore.Cosmos/Metadata/Conventions/CosmosManyToManyJoinEntityTypeConvention.cs index 187b574e268..b64b38b1341 100644 --- a/src/EFCore.Cosmos/Metadata/Conventions/CosmosManyToManyJoinEntityTypeConvention.cs +++ b/src/EFCore.Cosmos/Metadata/Conventions/CosmosManyToManyJoinEntityTypeConvention.cs @@ -188,5 +188,6 @@ private static bool ShouldSharePartitionKey(IConventionSkipNavigation skipNaviga => skipNavigation.DeclaringEntityType.GetContainer() == skipNavigation.TargetEntityType.GetContainer() && skipNavigation.DeclaringEntityType.GetPartitionKeyPropertyNames().Any() && (skipNavigation.Inverse?.DeclaringEntityType.GetPartitionKeyPropertyNames() - .SequenceEqual(skipNavigation.DeclaringEntityType.GetPartitionKeyPropertyNames(), StringComparer.Ordinal) == true); + .SequenceEqual(skipNavigation.DeclaringEntityType.GetPartitionKeyPropertyNames(), StringComparer.Ordinal) + == true); } diff --git a/src/EFCore.Cosmos/Metadata/Conventions/CosmosPartitionKeyInPrimaryKeyConvention.cs b/src/EFCore.Cosmos/Metadata/Conventions/CosmosPartitionKeyInPrimaryKeyConvention.cs index 5b2f2ad33cd..1b328cc683f 100644 --- a/src/EFCore.Cosmos/Metadata/Conventions/CosmosPartitionKeyInPrimaryKeyConvention.cs +++ b/src/EFCore.Cosmos/Metadata/Conventions/CosmosPartitionKeyInPrimaryKeyConvention.cs @@ -40,9 +40,7 @@ public class CosmosPartitionKeyInPrimaryKeyConvention : /// /// Parameter object containing dependencies for this convention. public CosmosPartitionKeyInPrimaryKeyConvention(ProviderConventionSetBuilderDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. @@ -73,7 +71,6 @@ private static void ProcessIdProperty(IConventionEntityTypeBuilder entityTypeBui primaryKeyProperties.Add(partitionKeyProperty!); keyContainsPartitionProperties = true; } - } if (keyContainsPartitionProperties) @@ -171,10 +168,12 @@ public virtual void ProcessEntityTypePrimaryKeyChanged( IConventionKey? previousPrimaryKey, IConventionContext context) { - if ((newPrimaryKey != null && newPrimaryKey.Properties - .Any(p => p.GetJsonPropertyName() == CosmosJsonIdConvention.IdPropertyJsonName)) - || (previousPrimaryKey != null && previousPrimaryKey.Properties - .Any(p => p.GetJsonPropertyName() == CosmosJsonIdConvention.IdPropertyJsonName))) + if ((newPrimaryKey != null + && newPrimaryKey.Properties + .Any(p => p.GetJsonPropertyName() == CosmosJsonIdConvention.IdPropertyJsonName)) + || (previousPrimaryKey != null + && previousPrimaryKey.Properties + .Any(p => p.GetJsonPropertyName() == CosmosJsonIdConvention.IdPropertyJsonName))) { ProcessIdProperty(entityTypeBuilder); } diff --git a/src/EFCore.Cosmos/Metadata/Conventions/CosmosRelationshipDiscoveryConvention.cs b/src/EFCore.Cosmos/Metadata/Conventions/CosmosRelationshipDiscoveryConvention.cs index 2063d27add5..1674300f1e6 100644 --- a/src/EFCore.Cosmos/Metadata/Conventions/CosmosRelationshipDiscoveryConvention.cs +++ b/src/EFCore.Cosmos/Metadata/Conventions/CosmosRelationshipDiscoveryConvention.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.Metadata.Conventions; /// diff --git a/src/EFCore.Cosmos/Metadata/Conventions/ETagPropertyConvention.cs b/src/EFCore.Cosmos/Metadata/Conventions/ETagPropertyConvention.cs index bb8b9a22f99..5169424e588 100644 --- a/src/EFCore.Cosmos/Metadata/Conventions/ETagPropertyConvention.cs +++ b/src/EFCore.Cosmos/Metadata/Conventions/ETagPropertyConvention.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.Metadata.Conventions; /// diff --git a/src/EFCore.Cosmos/Metadata/Conventions/Internal/CosmosConventionSetBuilder.cs b/src/EFCore.Cosmos/Metadata/Conventions/Internal/CosmosConventionSetBuilder.cs index bf1566146db..6756b34abf2 100644 --- a/src/EFCore.Cosmos/Metadata/Conventions/Internal/CosmosConventionSetBuilder.cs +++ b/src/EFCore.Cosmos/Metadata/Conventions/Internal/CosmosConventionSetBuilder.cs @@ -23,19 +23,17 @@ public CosmosConventionSetBuilder( ProviderConventionSetBuilderDependencies dependencies, IJsonIdDefinitionFactory definitionFactory) : base(dependencies) - { - DefinitionFactory = definitionFactory; - } + => DefinitionFactory = definitionFactory; /// - /// The factory to create a for each entity type. + /// The factory to create a for each entity type. /// /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. - /// > + /// protected virtual IJsonIdDefinitionFactory DefinitionFactory { get; } /// diff --git a/src/EFCore.Cosmos/Metadata/IdDiscriminatorMode.cs b/src/EFCore.Cosmos/Metadata/IdDiscriminatorMode.cs index fee33def274..ad4682614ac 100644 --- a/src/EFCore.Cosmos/Metadata/IdDiscriminatorMode.cs +++ b/src/EFCore.Cosmos/Metadata/IdDiscriminatorMode.cs @@ -2,10 +2,11 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.Metadata; /// -/// Defines the behavior for including discriminator values in the JSON "id" value. +/// Defines the behavior for including discriminator values in the JSON "id" value. /// public enum IdDiscriminatorMode { diff --git a/src/EFCore.Cosmos/Metadata/Internal/CosmosEntityTypeExtensions.cs b/src/EFCore.Cosmos/Metadata/Internal/CosmosEntityTypeExtensions.cs index 99fd4be5bf2..1ac3eb0bc0d 100644 --- a/src/EFCore.Cosmos/Metadata/Internal/CosmosEntityTypeExtensions.cs +++ b/src/EFCore.Cosmos/Metadata/Internal/CosmosEntityTypeExtensions.cs @@ -25,12 +25,14 @@ public static bool IsDocumentRoot(this IReadOnlyEntityType entityType) || entityType[CosmosAnnotationNames.ContainerName] != null); /// - /// Returns the JSON `id` definition, or if there is none. + /// Returns the JSON `id` definition, or if there is none. /// /// The entity type. public static IJsonIdDefinition? GetJsonIdDefinition(this IEntityType entityType) - => entityType.GetOrAddRuntimeAnnotationValue(CosmosAnnotationNames.JsonIdDefinition, + => entityType.GetOrAddRuntimeAnnotationValue( + CosmosAnnotationNames.JsonIdDefinition, static e => ((CosmosModelRuntimeInitializerDependencies)e!.Model.FindRuntimeAnnotationValue( CosmosAnnotationNames.ModelDependencies)!).JsonIdDefinitionFactory.Create(e), - entityType);} + entityType); +} diff --git a/src/EFCore.Cosmos/Metadata/Internal/IJsonIdDefinition.cs b/src/EFCore.Cosmos/Metadata/Internal/IJsonIdDefinition.cs index b17b17ca649..cb1e79088fb 100644 --- a/src/EFCore.Cosmos/Metadata/Internal/IJsonIdDefinition.cs +++ b/src/EFCore.Cosmos/Metadata/Internal/IJsonIdDefinition.cs @@ -20,7 +20,7 @@ public interface IJsonIdDefinition IReadOnlyList Properties { get; } /// - /// if the discriminator is included in the key. + /// if the discriminator is included in the key. /// /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -31,7 +31,7 @@ public interface IJsonIdDefinition bool IncludesDiscriminator { get; } /// - /// if the discriminator is for the root entity type. + /// if the discriminator is for the root entity type. /// /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Cosmos/Metadata/Internal/JsonIdDefinition.cs b/src/EFCore.Cosmos/Metadata/Internal/JsonIdDefinition.cs index 98165a02cee..92e2709cadb 100644 --- a/src/EFCore.Cosmos/Metadata/Internal/JsonIdDefinition.cs +++ b/src/EFCore.Cosmos/Metadata/Internal/JsonIdDefinition.cs @@ -24,9 +24,7 @@ public class JsonIdDefinition : IJsonIdDefinition /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public JsonIdDefinition(IReadOnlyList properties) - { - Properties = properties; - } + => Properties = properties; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -52,6 +50,7 @@ public JsonIdDefinition( /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual IReadOnlyList Properties { get; } + /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in diff --git a/src/EFCore.Cosmos/Properties/CosmosStrings.Designer.cs b/src/EFCore.Cosmos/Properties/CosmosStrings.Designer.cs index fcde6e3de80..d9571fc2d05 100644 --- a/src/EFCore.Cosmos/Properties/CosmosStrings.Designer.cs +++ b/src/EFCore.Cosmos/Properties/CosmosStrings.Designer.cs @@ -163,14 +163,6 @@ public static string IdNonStringStoreType(object? idProperty, object? entityType GetString("IdNonStringStoreType", nameof(idProperty), nameof(entityType), nameof(propertyType)), idProperty, entityType, propertyType); - /// - /// {actual} partition key values were provided, but the entity type '{entityType}' has {expected} partition key values defined. - /// - public static string IncorrectPartitionKeyNumber(object? entityType, object? actual, object? expected) - => string.Format( - GetString("IncorrectPartitionKeyNumber", nameof(entityType), nameof(actual), nameof(expected)), - entityType, actual, expected); - /// /// The entity type '{entityType}' has an index defined over properties '{properties}'. The Azure Cosmos DB provider for EF Core currently does not support index definitions. /// diff --git a/src/EFCore.Cosmos/Properties/CosmosStrings.resx b/src/EFCore.Cosmos/Properties/CosmosStrings.resx index 59db5844f85..171d85f852c 100644 --- a/src/EFCore.Cosmos/Properties/CosmosStrings.resx +++ b/src/EFCore.Cosmos/Properties/CosmosStrings.resx @@ -174,9 +174,6 @@ The type of the '{idProperty}' property on '{entityType}' is '{propertyType}'. All 'id' properties must be strings or have a string value converter. - - {actual} partition key values were provided, but the entity type '{entityType}' has {expected} partition key values defined. - The entity type '{entityType}' has an index defined over properties '{properties}'. The Azure Cosmos DB provider for EF Core currently does not support index definitions. diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosAliasManager.cs b/src/EFCore.Cosmos/Query/Internal/CosmosAliasManager.cs index 3e686495b86..bb43035c4f0 100644 --- a/src/EFCore.Cosmos/Query/Internal/CosmosAliasManager.cs +++ b/src/EFCore.Cosmos/Query/Internal/CosmosAliasManager.cs @@ -48,18 +48,19 @@ public class CosmosAliasManager /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual string GenerateSourceAlias(Expression expression, string? fallback = null) - => GenerateSourceAlias(expression switch - { - IAccessExpression { PropertyName: string propertyName } => propertyName, - FromSqlExpression => "sql", - SqlFunctionExpression { Name: "ARRAY_SLICE", Arguments: [var array, ..] } => GenerateSourceAlias(array), - ObjectFunctionExpression { Name: "ARRAY_SLICE", Arguments: [var array, ..] } => GenerateSourceAlias(array), - SqlFunctionExpression { Name: var name } => name, - ObjectFunctionExpression { Name: var name } => name, - ArrayConstantExpression => "array", + => GenerateSourceAlias( + expression switch + { + IAccessExpression { PropertyName: string propertyName } => propertyName, + FromSqlExpression => "sql", + SqlFunctionExpression { Name: "ARRAY_SLICE", Arguments: [var array, ..] } => GenerateSourceAlias(array), + ObjectFunctionExpression { Name: "ARRAY_SLICE", Arguments: [var array, ..] } => GenerateSourceAlias(array), + SqlFunctionExpression { Name: var name } => name, + ObjectFunctionExpression { Name: var name } => name, + ArrayConstantExpression => "array", - _ => fallback ?? "value" - }); + _ => fallback ?? "value" + }); /// /// Generates an alias based on the given . @@ -145,7 +146,7 @@ public virtual Expression PostprocessAliases(Expression expression) } else { - bitmap = aliasBitmaps[aliasBase] = new(aliasNum + 1); + bitmap = aliasBitmaps[aliasBase] = new BitArray(aliasNum + 1); } bitmap[aliasNum] = true; @@ -173,7 +174,7 @@ public virtual Expression PostprocessAliases(Expression expression) var j = i - numHoles; var newAlias = aliasBase + (j == 0 ? "" : (j - 1).ToString()); - aliasRewritingMap ??= new(); + aliasRewritingMap ??= new Dictionary(); aliasRewritingMap[oldAlias] = newAlias; } } diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosQueryCompilationContextFactory.cs b/src/EFCore.Cosmos/Query/Internal/CosmosQueryCompilationContextFactory.cs index c1c41af7c4c..dc5b69cb0f4 100644 --- a/src/EFCore.Cosmos/Query/Internal/CosmosQueryCompilationContextFactory.cs +++ b/src/EFCore.Cosmos/Query/Internal/CosmosQueryCompilationContextFactory.cs @@ -18,9 +18,7 @@ public class CosmosQueryCompilationContextFactory : IQueryCompilationContextFact /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public CosmosQueryCompilationContextFactory(QueryCompilationContextDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosQueryRootProcessor.cs b/src/EFCore.Cosmos/Query/Internal/CosmosQueryRootProcessor.cs index f7d4f62bd99..c1e56ee9847 100644 --- a/src/EFCore.Cosmos/Query/Internal/CosmosQueryRootProcessor.cs +++ b/src/EFCore.Cosmos/Query/Internal/CosmosQueryRootProcessor.cs @@ -21,9 +21,7 @@ public class CosmosQueryRootProcessor : QueryRootProcessor /// public CosmosQueryRootProcessor(QueryTranslationPreprocessorDependencies dependencies, QueryCompilationContext queryCompilationContext) : base(dependencies, queryCompilationContext) - { - _model = queryCompilationContext.Model; - } + => _model = queryCompilationContext.Model; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosQuerySqlGenerator.cs b/src/EFCore.Cosmos/Query/Internal/CosmosQuerySqlGenerator.cs index 6dd2963c6e1..67b1437208a 100644 --- a/src/EFCore.Cosmos/Query/Internal/CosmosQuerySqlGenerator.cs +++ b/src/EFCore.Cosmos/Query/Internal/CosmosQuerySqlGenerator.cs @@ -518,7 +518,7 @@ protected override Expression VisitSqlBinary(SqlBinaryExpression sqlBinaryExpres op = " || "; } else if (sqlBinaryExpression.OperatorType == ExpressionType.ExclusiveOr - && sqlBinaryExpression.Type == typeof(bool)) + && sqlBinaryExpression.Type == typeof(bool)) { op = " != "; } @@ -743,7 +743,6 @@ protected sealed override Expression VisitSource(SourceExpression sourceExpressi .Append(sourceExpression.Alias) .Append(" IN "); - VisitContainerExpression(sourceExpression.Expression); } else diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosQueryTranslationPostprocessor.cs b/src/EFCore.Cosmos/Query/Internal/CosmosQueryTranslationPostprocessor.cs index bc82944976e..cf11f40219e 100644 --- a/src/EFCore.Cosmos/Query/Internal/CosmosQueryTranslationPostprocessor.cs +++ b/src/EFCore.Cosmos/Query/Internal/CosmosQueryTranslationPostprocessor.cs @@ -10,9 +10,9 @@ namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public class CosmosQueryTranslationPostprocessor( - QueryTranslationPostprocessorDependencies dependencies, - ISqlExpressionFactory sqlExpressionFactory, - CosmosQueryCompilationContext queryCompilationContext) + QueryTranslationPostprocessorDependencies dependencies, + ISqlExpressionFactory sqlExpressionFactory, + CosmosQueryCompilationContext queryCompilationContext) : QueryTranslationPostprocessor(dependencies, queryCompilationContext) { /// diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosQueryTranslationPostprocessorFactory.cs b/src/EFCore.Cosmos/Query/Internal/CosmosQueryTranslationPostprocessorFactory.cs index 313976e3e92..ee03bfcfd04 100644 --- a/src/EFCore.Cosmos/Query/Internal/CosmosQueryTranslationPostprocessorFactory.cs +++ b/src/EFCore.Cosmos/Query/Internal/CosmosQueryTranslationPostprocessorFactory.cs @@ -10,8 +10,8 @@ namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public class CosmosQueryTranslationPostprocessorFactory( - QueryTranslationPostprocessorDependencies dependencies, - ISqlExpressionFactory sqlExpressionFactory) + QueryTranslationPostprocessorDependencies dependencies, + ISqlExpressionFactory sqlExpressionFactory) : IQueryTranslationPostprocessorFactory { /// diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosQueryTranslationPreprocessor.cs b/src/EFCore.Cosmos/Query/Internal/CosmosQueryTranslationPreprocessor.cs index cc8cadf8b0d..f96c98fdb10 100644 --- a/src/EFCore.Cosmos/Query/Internal/CosmosQueryTranslationPreprocessor.cs +++ b/src/EFCore.Cosmos/Query/Internal/CosmosQueryTranslationPreprocessor.cs @@ -10,8 +10,8 @@ namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public class CosmosQueryTranslationPreprocessor( - QueryTranslationPreprocessorDependencies dependencies, - CosmosQueryCompilationContext cosmosQueryCompilationContext) + QueryTranslationPreprocessorDependencies dependencies, + CosmosQueryCompilationContext cosmosQueryCompilationContext) : QueryTranslationPreprocessor(dependencies, cosmosQueryCompilationContext) { /// diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitor.cs b/src/EFCore.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitor.cs index 18d2d9bc2de..9b446a78152 100644 --- a/src/EFCore.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitor.cs +++ b/src/EFCore.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitor.cs @@ -1,9 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using Microsoft.EntityFrameworkCore.Cosmos.Internal; -using Microsoft.EntityFrameworkCore.Cosmos.Metadata.Internal; using Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.Expressions; using Microsoft.EntityFrameworkCore.Cosmos.Storage.Internal; using Microsoft.EntityFrameworkCore.Internal; @@ -141,12 +139,13 @@ public override Expression Translate(Expression expression) // Wrap the shaper for the entire query in a PagingExpression which also contains the paging arguments, and update // the final cardinality to Single (since we'll be returning a single Page). return shapedQuery - .UpdateShaperExpression(new PagingExpression( - shapedQuery.ShaperExpression, - translatedMaxItemCount, - translatedContinuationToken, - translatedResponseContinuationTokenLimitInKb, - typeof(CosmosPage<>).MakeGenericType(shapedQuery.ShaperExpression.Type))) + .UpdateShaperExpression( + new PagingExpression( + shapedQuery.ShaperExpression, + translatedMaxItemCount, + translatedContinuationToken, + translatedResponseContinuationTokenLimitInKb, + typeof(CosmosPage<>).MakeGenericType(shapedQuery.ShaperExpression.Type))) .UpdateResultCardinality(ResultCardinality.Single); } @@ -173,23 +172,15 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp var innerQueryable = Visit(methodCallExpression.Arguments[0]); - var firstValue = _sqlTranslator.Translate(methodCallExpression.Arguments[1], applyDefaultTypeMapping: false); - if (firstValue is not SqlConstantExpression and not SqlParameterExpression) + for (var i = 1; i < methodCallExpression.Arguments.Count; i++) { - throw new InvalidOperationException(CosmosStrings.WithPartitionKeyNotConstantOrParameter); - } - - _queryCompilationContext.PartitionKeyPropertyValues.Add(firstValue); - - if (methodCallExpression.Arguments.Count == 3) - { - var remainingValuesArray = _sqlTranslator.Translate(methodCallExpression.Arguments[2], applyDefaultTypeMapping: false); - if (remainingValuesArray is not SqlParameterExpression) + var value = _sqlTranslator.Translate(methodCallExpression.Arguments[i], applyDefaultTypeMapping: false); + if (value is not SqlConstantExpression and not SqlParameterExpression) { throw new InvalidOperationException(CosmosStrings.WithPartitionKeyNotConstantOrParameter); } - _queryCompilationContext.PartitionKeyPropertyValues.Add(remainingValuesArray); + _queryCompilationContext.PartitionKeyPropertyValues.Add(value); } return innerQueryable; @@ -223,7 +214,7 @@ when methodCallExpression.Arguments[0] is MethodCallExpression { #pragma warning disable EF1001 // Internal EF Core API usage. var translation = _sqlTranslator.Translate( - Microsoft.EntityFrameworkCore.Infrastructure.ExpressionExtensions.CreateEFPropertyExpression( + EntityFrameworkCore.Infrastructure.ExpressionExtensions.CreateEFPropertyExpression( elementAtTranslation.ShaperExpression, elementAtTranslation.ShaperExpression.Type, boundMember.Type, @@ -340,8 +331,9 @@ protected override QueryableMethodTranslatingExpressionVisitor CreateSubqueryVis selectExpression, _sqlExpressionFactory.In( (SqlExpression)discriminatorColumn, - concreteEntityTypes.Select(et => _sqlExpressionFactory.Constant(et.GetDiscriminatorValue(), discriminatorColumn.Type)) - .ToArray())); + concreteEntityTypes.Select( + et => _sqlExpressionFactory.Constant(et.GetDiscriminatorValue(), discriminatorColumn.Type)) + .ToArray())); Check.DebugAssert(success, "Couldn't apply predicate when creating a new ShapedQueryExpression"); } } @@ -422,7 +414,7 @@ private ShapedQueryExpression CreateShapedQueryExpression(SelectExpression selec var simplifiedTranslation = _sqlExpressionFactory.GreaterThan( _sqlExpressionFactory.Function( "ARRAY_LENGTH", new[] { array }, typeof(int), _typeMappingSource.FindMapping(typeof(int))), - _sqlExpressionFactory.Constant(0)); + _sqlExpressionFactory.Constant(0)); var select = new SelectExpression(simplifiedTranslation); return source.Update(select, new ProjectionBindingExpression(select, new ProjectionMember(), typeof(int))); @@ -519,7 +511,7 @@ protected override ShapedQueryExpression TranslateCast(ShapedQueryExpression sou // Translate to EXISTS var anyLambdaParameter = Expression.Parameter(item.Type, "p"); var anyLambda = Expression.Lambda( - Microsoft.EntityFrameworkCore.Infrastructure.ExpressionExtensions.CreateEqualsExpression(anyLambdaParameter, item), + EntityFrameworkCore.Infrastructure.ExpressionExtensions.CreateEqualsExpression(anyLambdaParameter, item), anyLambdaParameter); return TranslateAny(source, anyLambda); @@ -598,7 +590,7 @@ protected override ShapedQueryExpression TranslateCast(ShapedQueryExpression sou // ElementAtOrDefault over an array of scalars case SqlExpression scalarArray when projection is SqlExpression element: { - SqlExpression translation = _sqlExpressionFactory.ArrayIndex( + var translation = _sqlExpressionFactory.ArrayIndex( scalarArray, translatedIndex, element.Type, element.TypeMapping); // ElementAt may access indexes beyond the end of the array; Cosmos returns undefined for those cases. @@ -633,7 +625,8 @@ protected override ShapedQueryExpression TranslateCast(ShapedQueryExpression sou } var translatedSelect = - new SelectExpression(new EntityProjectionExpression(translation, (IEntityType)projectedStructuralTypeShaper.StructuralType)); + new SelectExpression( + new EntityProjectionExpression(translation, (IEntityType)projectedStructuralTypeShaper.StructuralType)); return source.Update( translatedSelect, new StructuralTypeShaperExpression( @@ -1283,7 +1276,10 @@ protected override ShapedQueryExpression TranslateSelect(ShapedQueryExpression s case SqlExpression scalarArray when projection is SqlExpression element: { // Take() is composed over Skip(), combine the two together to a single ARRAY_SLICE() - var slice = array is SqlFunctionExpression { Name: "ARRAY_SLICE", Arguments: [var nestedArray, var skipCount] } previousSlice + var slice = array is SqlFunctionExpression + { + Name: "ARRAY_SLICE", Arguments: [var nestedArray, var skipCount] + } previousSlice ? previousSlice.Update([nestedArray, skipCount, translatedCount]) : _sqlExpressionFactory.Function( "ARRAY_SLICE", [scalarArray, TranslateExpression(Expression.Constant(0))!, translatedCount], scalarArray.Type, @@ -1301,10 +1297,14 @@ protected override ShapedQueryExpression TranslateSelect(ShapedQueryExpression s case not null when projectedStructuralTypeShaper is not null: { // Take() is composed over Skip(), combine the two together to a single ARRAY_SLICE() - var slice = array is ObjectFunctionExpression { Name: "ARRAY_SLICE", Arguments: [var nestedArray, var skipCount] } previousSlice + var slice = array is ObjectFunctionExpression + { + Name: "ARRAY_SLICE", Arguments: [var nestedArray, var skipCount] + } previousSlice ? previousSlice.Update([nestedArray, skipCount, translatedCount]) : new ObjectFunctionExpression( - "ARRAY_SLICE", [array, TranslateExpression(Expression.Constant(0))!, translatedCount], projectedStructuralTypeShaper.Type); + "ARRAY_SLICE", [array, TranslateExpression(Expression.Constant(0))!, translatedCount], + projectedStructuralTypeShaper.Type); var alias = _aliasManager.GenerateSourceAlias(slice); var translatedSelect = SelectExpression.CreateForCollection( diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosReadItemAndPartitionKeysExtractor.cs b/src/EFCore.Cosmos/Query/Internal/CosmosReadItemAndPartitionKeysExtractor.cs index 03d412a8b04..a0311a5c457 100644 --- a/src/EFCore.Cosmos/Query/Internal/CosmosReadItemAndPartitionKeysExtractor.cs +++ b/src/EFCore.Cosmos/Query/Internal/CosmosReadItemAndPartitionKeysExtractor.cs @@ -6,7 +6,8 @@ namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; /// -/// Identifies Cosmos queries that can be transformed to optimized ReadItem form and performs the transformation. +/// Identifies Cosmos queries that can be transformed to optimized ReadItem form and performs the transformation; also extracts out +/// partition key comparisons from the predicate. /// /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -23,7 +24,7 @@ public class CosmosReadItemAndPartitionKeysExtractor : ExpressionVisitor private bool _discriminatorHandled; private string? _discriminatorJsonPropertyName; private Dictionary _jsonIdPropertyValues = null!; - private Dictionary _partitionKeyPropertyValues = null!; + private Dictionary _partitionKeyPropertyValues = null!; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -74,51 +75,48 @@ public virtual Expression ExtractPartitionKeysAndId( _jsonIdPropertyValues = jsonIdProperties.ToDictionary(p => p, _ => (Expression?)null); var partitionKeyProperties = _entityType.GetPartitionKeyProperties(); - _partitionKeyPropertyValues = partitionKeyProperties.ToDictionary(p => p, _ => (Expression?)null); + _partitionKeyPropertyValues = partitionKeyProperties.ToDictionary( + p => p, _ => (ValueExpression: (Expression?)null, (Expression?)null)); + _discriminatorJsonPropertyName = _entityType.FindDiscriminatorProperty()?.GetJsonPropertyName(); // Visit the predicate. - // This will populate _jsonIdPropertyValues and _partitionKeyPropertyValues with comparisons found in the predicate, and return - // a rewritten predicate where the partition key comparisons have been removed. - var predicateWithoutPartitionKeyComparisons = (SqlExpression)Visit(predicate); + // This will populate _jsonIdPropertyValues and _partitionKeyPropertyValues with comparisons found in the predicate. + // It does not modify the predicate (this may happen below if we lift our partition key comparisons). + var samePredicate = (SqlExpression)Visit(predicate); + Check.DebugAssert(ReferenceEquals(samePredicate, predicate), "Visitation shouldn't have changed the predicate."); var allIdPropertiesSpecified = _jsonIdPropertyValues.Values.All(p => p is not null) && _jsonIdPropertyValues.Count > 0; - var allPartitionKeyPropertiesSpecified = _partitionKeyPropertyValues.Values.All(p => p is not null); - - // First, take care of the partition key properties; if the visitation above returned a different predicate, that means that some - // partition key comparisons were extracted (and therefore found). Lift these up to the query compilation context and rewrite - // the SelectExpression with the new, reduced predicate. - // Note that if the user called WithPartitionKey(), we'll have already populated the partition key property values from there, and - // we skip lifting the predicate comparisons. - if (allPartitionKeyPropertiesSpecified - && queryCompilationContext.PartitionKeyPropertyValues.Count == 0) + + // First, go over the partition key properties and lift them from the predicate to the query compilation context, as possible. + // We do this only as long as all partition key values are provided; the moment there's a gap we stop (so if PK1 and PK3 are + // provided but not PK2, only PK1 will be lifted out). + // Note that if the user called WithPartitionKey(), we'll have already populated the partition key property values from there; for + // this case, we skip lifting the predicate comparisons and leave the predicate exactly as it is (it may conflict with the values + // given in WithPartitionKey and return zero results - that's the expected behavior). + var liftPartitionKeys = queryCompilationContext.PartitionKeyPropertyValues.Count == 0; + foreach (var property in partitionKeyProperties) { - foreach (var partitionKeyProperty in partitionKeyProperties) + if (liftPartitionKeys && _partitionKeyPropertyValues[property].ValueExpression is Expression valueExpression) { - queryCompilationContext.PartitionKeyPropertyValues.Add(_partitionKeyPropertyValues[partitionKeyProperty]!); + queryCompilationContext.PartitionKeyPropertyValues.Add(valueExpression); + } + else + { + // We either have a gap in the partition key comparisons in the predicate (so we can't lift later ones), or the user + // specified a partition key value via WithPartitionKey. In either case, we need to not lift out comparisons and null out + // _partitionKeyPropertyValues, to prevent us removing the comparisons from the predicate below. + liftPartitionKeys = false; + _partitionKeyPropertyValues[property] = (null, null); } - - select = select.Update( - select.Sources.ToList(), - predicateWithoutPartitionKeyComparisons is SqlConstantExpression { Value: true } - ? null - : predicateWithoutPartitionKeyComparisons, - select.Projection.ToList(), - select.Orderings.ToList(), - select.Offset, - select.Limit); - - shapedQuery = shapedQuery.UpdateQueryExpression(select); } - // Now, attempt to also transform the query to ReadItem form if possible. + // Now, attempt to also transform the query to ReadItem form; this is only possible if all JSON ID properties were compared in the + // predicate, and *all* partition key values are specified(in the predicate or via WithPartitionKey) if (_isPredicateCompatibleWithReadItem && allIdPropertiesSpecified - // Note that queryCompilationContext.PartitionKeyPropertyValues may have been populated with WithPartitionKey(), which has - // a params object[] argument that gets parameterized as a single array. So the number of property values may not match the - // number of partition key properties. - && (partitionKeyProperties.Count == 0 || queryCompilationContext.PartitionKeyPropertyValues.Count > 0) + && queryCompilationContext.PartitionKeyPropertyValues.Count == partitionKeyProperties.Count && select is { Offset: null or SqlConstantExpression { Value: 0 }, @@ -132,6 +130,28 @@ public virtual Expression ExtractPartitionKeysAndId( return shapedQuery.UpdateQueryExpression(select.WithReadItemInfo(new ReadItemInfo(_jsonIdPropertyValues!))); } + // We couldn't transform to ReadItem - some JSON ID or partition key property comparison was missing in the predicate. + // However, comparisons might still be there for some (or all) of the partition key properties. These have already been lifted + // up to the query compilation context (above), but we still need to remove them from the predicate. + if (partitionKeyProperties.Count > 0 && _partitionKeyPropertyValues[partitionKeyProperties[0]].ValueExpression is not null) + { + var predicateWithoutPartitionKeyComparisons = (SqlExpression)new PredicateComparisonRemover( + _sqlExpressionFactory, + _partitionKeyPropertyValues.Values.Select(p => p.OriginalExpression).OfType().ToList()) + .Visit(predicate); + Check.DebugAssert(!ReferenceEquals(predicateWithoutPartitionKeyComparisons, predicate), "Predicate should have changed."); + + select = select.Update( + select.Sources.ToList(), + predicateWithoutPartitionKeyComparisons, + select.Projection.ToList(), + select.Orderings.ToList(), + select.Offset, + select.Limit); + + shapedQuery = shapedQuery.UpdateQueryExpression(select); + } + return shapedQuery; Expression Unwrap(Expression shaper) @@ -194,6 +214,7 @@ protected override Expression VisitExtension(Expression node) _isPredicateCompatibleWithReadItem = false; return node; } + case SqlBinaryExpression { OperatorType: ExpressionType.Equal, Left: var left, Right: var right } binary: { // TODO: Handle property accesses into complex types/owned entity types, #25548 @@ -209,7 +230,8 @@ left is ScalarAccessExpression leftScalarAccess if (scalarAccess?.Object is ObjectReferenceExpression { Name: var referencedSourceAlias } && referencedSourceAlias == _rootAlias) { - return ProcessPropertyComparison(scalarAccess.PropertyName, propertyValue!, binary); + ProcessPropertyComparison(scalarAccess.PropertyName, propertyValue!, binary); + return node; } _isPredicateCompatibleWithReadItem = false; @@ -218,7 +240,8 @@ left is ScalarAccessExpression leftScalarAccess // Bool property access (e.g. Where(b => b.BoolPartitionKey)) case ScalarAccessExpression { PropertyName: var propertyName } scalarAccess: - return ProcessPropertyComparison(propertyName, _sqlExpressionFactory.Constant(true), scalarAccess); + ProcessPropertyComparison(propertyName, _sqlExpressionFactory.Constant(true), scalarAccess); + return node; // Negated bool property access (e.g. Where(b => !b.BoolPartitionKey)) case SqlUnaryExpression @@ -226,15 +249,11 @@ left is ScalarAccessExpression leftScalarAccess OperatorType: ExpressionType.Not, Operand: ScalarAccessExpression { PropertyName: var propertyName } } unary: - return ProcessPropertyComparison(propertyName, _sqlExpressionFactory.Constant(false), unary); + ProcessPropertyComparison(propertyName, _sqlExpressionFactory.Constant(false), unary); + return node; case SqlBinaryExpression { OperatorType: ExpressionType.AndAlso } binary: - return _sqlExpressionFactory.MakeBinary( - ExpressionType.AndAlso, - (SqlExpression)Visit(binary.Left), - (SqlExpression)Visit(binary.Right), - binary.TypeMapping, - binary)!; + return binary.Update((SqlExpression)Visit(binary.Left), (SqlExpression)Visit(binary.Right)); default: // Anything else in the predicate, e.g. an OR, immediately disqualifies it from being a ReadItem query, and means we @@ -243,7 +262,7 @@ left is ScalarAccessExpression leftScalarAccess return node; } - SqlExpression ProcessPropertyComparison(string propertyName, SqlExpression propertyValue, SqlExpression originalExpression) + void ProcessPropertyComparison(string propertyName, SqlExpression propertyValue, SqlExpression originalExpression) { // We assume that the comparison is incompatible with ReadItem until proven otherwise, i.e. the comparison is for a JSON ID // property, a partition key property, or certain cases involving the discriminator property. @@ -271,6 +290,7 @@ SqlExpression ProcessPropertyComparison(string propertyName, SqlExpression prope _jsonIdPropertyValues[property] = propertyValue; isCompatibleComparisonForReadItem = true; } + break; } } @@ -282,11 +302,11 @@ SqlExpression ProcessPropertyComparison(string propertyName, SqlExpression prope // Extract its value expression and elide the comparison from the predicate - it'll be lifted out to the Cosmos SDK // call. Note that this is always considered a compatible comparison for ReadItem. if (propertyName == property.GetJsonPropertyName() - && _partitionKeyPropertyValues.TryGetValue(property, out var previousValue) - && (previousValue is null || previousValue.Equals(propertyValue))) + && _partitionKeyPropertyValues.TryGetValue(property, out var previousValues) + && (previousValues.ValueExpression is null || previousValues.Equals(propertyValue))) { - _partitionKeyPropertyValues[property] = propertyValue; - return _sqlExpressionFactory.Constant(true); + _partitionKeyPropertyValues[property] = (ValueExpression: propertyValue, OriginalExpression: originalExpression); + return; } } @@ -294,8 +314,29 @@ SqlExpression ProcessPropertyComparison(string propertyName, SqlExpression prope { _isPredicateCompatibleWithReadItem = false; } - - return originalExpression; } } + + private sealed class PredicateComparisonRemover(ISqlExpressionFactory sqlExpressionFactory, List comparisonsToRemove) + : ExpressionVisitor + { + protected override Expression VisitExtension(Expression node) + => node switch + { + _ when comparisonsToRemove.Contains(node) + => sqlExpressionFactory.Constant(true), + + // This elides `AND true` from the predicate. + // TODO: We shouldn't need to do this explicitly, see #34556. + SqlBinaryExpression { OperatorType: ExpressionType.AndAlso } binary + => sqlExpressionFactory.MakeBinary( + ExpressionType.AndAlso, + (SqlExpression)Visit(binary.Left), + (SqlExpression)Visit(binary.Right), + binary.TypeMapping, + binary)!, + + _ => base.VisitExtension(node) + }; + } } diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.CosmosProjectionBindingRemovingExpressionVisitorBase.cs b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.CosmosProjectionBindingRemovingExpressionVisitorBase.cs index f327c511cd3..d349d73e609 100644 --- a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.CosmosProjectionBindingRemovingExpressionVisitorBase.cs +++ b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.CosmosProjectionBindingRemovingExpressionVisitorBase.cs @@ -97,6 +97,7 @@ protected override Expression VisitBinary(BinaryExpression binaryExpression) { storeName = projection.Alias; } + break; } @@ -114,7 +115,8 @@ protected override Expression VisitBinary(BinaryExpression binaryExpression) { case ObjectArrayAccessExpression objectArrayProjectionExpression: _projectionBindings[objectArrayProjectionExpression] = parameterExpression; - valueExpression = CreateGetValueExpression(objectArrayProjectionExpression.Object, storeName, parameterExpression.Type); + valueExpression = CreateGetValueExpression( + objectArrayProjectionExpression.Object, storeName, parameterExpression.Type); break; case EntityProjectionExpression entityProjectionExpression: @@ -144,11 +146,13 @@ protected override Expression VisitBinary(BinaryExpression binaryExpression) { valueExpression = CreateGetValueExpression(valueExpression, storeNames[i], typeof(JObject)); } + break; default: throw new InvalidOperationException( CoreStrings.TranslationFailed(binaryExpression.Print())); } + break; default: diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.InExpressionValuesExpandingExpressionVisitor.cs b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.InExpressionValuesExpandingExpressionVisitor.cs index 173bd1403ed..98563fd0a2a 100644 --- a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.InExpressionValuesExpandingExpressionVisitor.cs +++ b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.InExpressionValuesExpandingExpressionVisitor.cs @@ -4,7 +4,6 @@ #nullable disable using System.Collections; -using Microsoft.EntityFrameworkCore.Cosmos.Internal; namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; @@ -37,6 +36,7 @@ protected override Expression VisitExtension(Expression expression) { mutableValues.Add(sqlExpressionFactory.Constant(value, value?.GetType() ?? typeof(object), typeMapping)); } + values = mutableValues; break; } diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.PagingQueryingEnumerable.cs b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.PagingQueryingEnumerable.cs index 006d87c4645..e90c24664a5 100644 --- a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.PagingQueryingEnumerable.cs +++ b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.PagingQueryingEnumerable.cs @@ -3,9 +3,7 @@ #nullable disable -using System.Collections; using Microsoft.EntityFrameworkCore.Cosmos.Diagnostics.Internal; -using Microsoft.EntityFrameworkCore.Cosmos.Internal; using Microsoft.EntityFrameworkCore.Cosmos.Storage.Internal; using Newtonsoft.Json.Linq; diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.ReadItemQueryingEnumerable.cs b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.ReadItemQueryingEnumerable.cs index 2aa09cd6614..9e833adbb3c 100644 --- a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.ReadItemQueryingEnumerable.cs +++ b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.ReadItemQueryingEnumerable.cs @@ -74,7 +74,8 @@ public string ToQueryString() private bool TryGetResourceId(out string resourceId) { var jsonIdDefinition = _rootEntityType.GetJsonIdDefinition(); - Check.DebugAssert(jsonIdDefinition != null, + Check.DebugAssert( + jsonIdDefinition != null, "Should not be using this enumerable if not using ReadItem, which needs an id definition."); var values = new List(jsonIdDefinition.Properties.Count); diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.cs b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.cs index 2ad551a6521..e8aa6e16db2 100644 --- a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.cs +++ b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.cs @@ -145,8 +145,7 @@ private static PartitionKey GeneratePartitionKey( var partitionKeyProperties = rootEntityType.GetPartitionKeyProperties(); - int i; - for (i = 0; i < partitionKeyPropertyValues.Count && i < partitionKeyProperties.Count; i++) + for (var i = 0; i < partitionKeyPropertyValues.Count && i < partitionKeyProperties.Count; i++) { var property = partitionKeyProperties[i]; @@ -156,25 +155,6 @@ private static PartitionKey GeneratePartitionKey( builder.Add(constant.Value, property); continue; - // If WithPartitionKey() was used, its second argument is a params object[] array, which gets parameterized as a single - // parameter. Extract the object[] and iterate over the values within here. - case SqlParameterExpression parameter when parameter.Type == typeof(object[]): - { - if (!parameterValues.TryGetValue(parameter.Name, out var value) - || value is not object[] remainingValuesArray - || i != 1) - { - throw new UnreachableException("Couldn't find partition key parameter value"); - } - - for (var j = 0; j < remainingValuesArray.Length; j++, i++) - { - builder.Add(remainingValuesArray[j], partitionKeyProperties[i]); - } - - goto End; - } - case SqlParameterExpression parameter: { builder.Add( @@ -190,13 +170,6 @@ private static PartitionKey GeneratePartitionKey( } } - End: - if (i != partitionKeyProperties.Count) - { - throw new InvalidOperationException( - CosmosStrings.IncorrectPartitionKeyNumber(rootEntityType.DisplayName(), i, partitionKeyProperties.Count)); - } - return builder.Build(); } } diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosSqlTranslatingExpressionVisitor.cs b/src/EFCore.Cosmos/Query/Internal/CosmosSqlTranslatingExpressionVisitor.cs index 4882efcd955..470c2263716 100644 --- a/src/EFCore.Cosmos/Query/Internal/CosmosSqlTranslatingExpressionVisitor.cs +++ b/src/EFCore.Cosmos/Query/Internal/CosmosSqlTranslatingExpressionVisitor.cs @@ -5,6 +5,7 @@ using System.Diagnostics.CodeAnalysis; using Microsoft.EntityFrameworkCore.Cosmos.Internal; using Microsoft.EntityFrameworkCore.Internal; +using static Microsoft.EntityFrameworkCore.Query.QueryHelpers; namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; @@ -15,12 +16,12 @@ namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public class CosmosSqlTranslatingExpressionVisitor( - QueryCompilationContext queryCompilationContext, - ISqlExpressionFactory sqlExpressionFactory, - ITypeMappingSource typeMappingSource, - IMemberTranslatorProvider memberTranslatorProvider, - IMethodCallTranslatorProvider methodCallTranslatorProvider, - QueryableMethodTranslatingExpressionVisitor queryableMethodTranslatingExpressionVisitor) + QueryCompilationContext queryCompilationContext, + ISqlExpressionFactory sqlExpressionFactory, + ITypeMappingSource typeMappingSource, + IMemberTranslatorProvider memberTranslatorProvider, + IMethodCallTranslatorProvider methodCallTranslatorProvider, + QueryableMethodTranslatingExpressionVisitor queryableMethodTranslatingExpressionVisitor) : ExpressionVisitor { private const string RuntimeParameterPrefix = QueryCompilationContext.QueryParameterPrefix + "entity_equality_"; @@ -346,22 +347,22 @@ protected override Expression VisitExtension(Expression extensionExpression) case StructuralTypeShaperExpression shaper: return new EntityReferenceExpression(shaper); - // var result = Visit(entityShaperExpression.ValueBufferExpression); - // - // if (result is UnaryExpression - // { - // NodeType: ExpressionType.Convert, - // Operand.NodeType: ExpressionType.Convert - // } outerUnary - // && outerUnary.Type == typeof(ValueBuffer) - // && outerUnary.Operand.Type == typeof(object)) - // { - // result = ((UnaryExpression)outerUnary.Operand).Operand; - // } - // - // return result is EntityProjectionExpression entityProjectionExpression - // ? new EntityReferenceExpression(entityProjectionExpression) - // : QueryCompilationContext.NotTranslatedExpression; + // var result = Visit(entityShaperExpression.ValueBufferExpression); + // + // if (result is UnaryExpression + // { + // NodeType: ExpressionType.Convert, + // Operand.NodeType: ExpressionType.Convert + // } outerUnary + // && outerUnary.Type == typeof(ValueBuffer) + // && outerUnary.Operand.Type == typeof(object)) + // { + // result = ((UnaryExpression)outerUnary.Operand).Operand; + // } + // + // return result is EntityProjectionExpression entityProjectionExpression + // ? new EntityReferenceExpression(entityProjectionExpression) + // : QueryCompilationContext.NotTranslatedExpression; case ProjectionBindingExpression projectionBindingExpression: return projectionBindingExpression.ProjectionMember != null @@ -517,10 +518,9 @@ protected override Expression VisitMemberInit(MemberInitExpression memberInitExp /// protected override Expression VisitMethodCall(MethodCallExpression methodCallExpression) { - if (methodCallExpression.TryGetEFPropertyArguments(out var source, out var propertyName) - || methodCallExpression.TryGetIndexerArguments(_model, out source, out propertyName)) + if (IsMemberAccess(methodCallExpression, _model, out var source, out var memberIdentity)) { - return TryBindMember(Visit(source), MemberIdentity.Create(propertyName), out var result, out _) + return TryBindMember(Visit(source), memberIdentity, out var result, out _) ? result : QueryCompilationContext.NotTranslatedExpression; } @@ -820,18 +820,28 @@ protected override Expression VisitUnary(UnaryExpression unaryExpression) ExpressionType.Negate or ExpressionType.NegateChecked => sqlExpressionFactory.Negate(sqlOperand!), - ExpressionType.Convert or ExpressionType.ConvertChecked - when operand.Type.IsInterface - && unaryExpression.Type.GetInterfaces().Any(e => e == operand.Type) + // Convert nodes can be an explicit user gesture in the query, or they may get introduced by the compiler (e.g. when a Child is + // passed as an argument for a parameter of type Parent). The latter type should generally get stripped out as a pure C#/LINQ + // artifact that shouldn't affect translation, but the latter may be an indication from the user that they want to apply a + // type change. + ExpressionType.Convert or ExpressionType.ConvertChecked or ExpressionType.TypeAs + when operand.Type.IsInterface && unaryExpression.Type.GetInterfaces().Any(e => e == operand.Type) + // We strip out implicit conversions, e.g. float[] -> ReadOnlyMemory (for vector search) + || (unaryExpression.Method is { IsSpecialName: true, Name: "op_Implicit" } + && IsReadOnlyMemory(unaryExpression.Type.UnwrapNullableType())) || unaryExpression.Type.UnwrapNullableType() == operand.Type || unaryExpression.Type.UnwrapNullableType() == typeof(Enum) // Object convert needs to be converted to explicit cast when mismatching types - // But we let is pass here since we don't have explicit cast mechanism here and in some cases object convert is due to value types + // But we let it pass here since we don't have explicit cast mechanism here and in some cases object convert is due to value types || unaryExpression.Type == typeof(object) => sqlOperand!, _ => QueryCompilationContext.NotTranslatedExpression }; + + static bool IsReadOnlyMemory(Type type) + => type is { IsGenericType: true, IsGenericTypeDefinition: false } + && type.GetGenericTypeDefinition() == typeof(ReadOnlyMemory<>); } /// @@ -855,7 +865,7 @@ protected override Expression VisitTypeBinary(TypeBinaryExpression typeBinaryExp MemberIdentity.Create(entityType.GetDiscriminatorPropertyName()), out var discriminatorMember, out _) - && discriminatorMember is SqlExpression discriminatorColumn) + && discriminatorMember is SqlExpression discriminatorColumn) { var concreteEntityTypes = derivedType.GetConcreteDerivedTypesInclusive().ToList(); diff --git a/src/EFCore.Cosmos/Query/Internal/Expressions/ArrayConstantExpression.cs b/src/EFCore.Cosmos/Query/Internal/Expressions/ArrayConstantExpression.cs index 05c0700da2a..3ecc6cdcc46 100644 --- a/src/EFCore.Cosmos/Query/Internal/Expressions/ArrayConstantExpression.cs +++ b/src/EFCore.Cosmos/Query/Internal/Expressions/ArrayConstantExpression.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; /// diff --git a/src/EFCore.Cosmos/Query/Internal/Expressions/CollectionShaperExpression.cs b/src/EFCore.Cosmos/Query/Internal/Expressions/CollectionShaperExpression.cs index 2e158a9f39a..0a1621ee8fe 100644 --- a/src/EFCore.Cosmos/Query/Internal/Expressions/CollectionShaperExpression.cs +++ b/src/EFCore.Cosmos/Query/Internal/Expressions/CollectionShaperExpression.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.Query.Internal; /// diff --git a/src/EFCore.Cosmos/Query/Internal/Expressions/ExistsExpression.cs b/src/EFCore.Cosmos/Query/Internal/Expressions/ExistsExpression.cs index 2548d510b5b..e11956a62ee 100644 --- a/src/EFCore.Cosmos/Query/Internal/Expressions/ExistsExpression.cs +++ b/src/EFCore.Cosmos/Query/Internal/Expressions/ExistsExpression.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; /// @@ -30,9 +31,7 @@ public class ExistsExpression : SqlExpression /// public ExistsExpression(SelectExpression subquery, CoreTypeMapping? typeMapping) : base(typeof(bool), typeMapping) - { - Subquery = subquery; - } + => Subquery = subquery; /// /// The subquery for which to check for element existence. diff --git a/src/EFCore.Cosmos/Query/Internal/Expressions/FragmentExpression.cs b/src/EFCore.Cosmos/Query/Internal/Expressions/FragmentExpression.cs index 0a14e2f7430..cdb0bbff323 100644 --- a/src/EFCore.Cosmos/Query/Internal/Expressions/FragmentExpression.cs +++ b/src/EFCore.Cosmos/Query/Internal/Expressions/FragmentExpression.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.EntityFrameworkCore.Cosmos.Storage.Internal; + // ReSharper disable once CheckNamespace namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; diff --git a/src/EFCore.Cosmos/Query/Internal/Expressions/FromSqlExpression.cs b/src/EFCore.Cosmos/Query/Internal/Expressions/FromSqlExpression.cs index 728e7a1c736..93f181e2413 100644 --- a/src/EFCore.Cosmos/Query/Internal/Expressions/FromSqlExpression.cs +++ b/src/EFCore.Cosmos/Query/Internal/Expressions/FromSqlExpression.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; /// diff --git a/src/EFCore.Cosmos/Query/Internal/Expressions/FromSqlQueryRootExpression.cs b/src/EFCore.Cosmos/Query/Internal/Expressions/FromSqlQueryRootExpression.cs index d303f31ab28..80cb5f8d077 100644 --- a/src/EFCore.Cosmos/Query/Internal/Expressions/FromSqlQueryRootExpression.cs +++ b/src/EFCore.Cosmos/Query/Internal/Expressions/FromSqlQueryRootExpression.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; /// diff --git a/src/EFCore.Cosmos/Query/Internal/Expressions/IAccessExpression.cs b/src/EFCore.Cosmos/Query/Internal/Expressions/IAccessExpression.cs index ab442871509..50c94d21dce 100644 --- a/src/EFCore.Cosmos/Query/Internal/Expressions/IAccessExpression.cs +++ b/src/EFCore.Cosmos/Query/Internal/Expressions/IAccessExpression.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; /// diff --git a/src/EFCore.Cosmos/Query/Internal/Expressions/ObjectArrayExpression.cs b/src/EFCore.Cosmos/Query/Internal/Expressions/ObjectArrayExpression.cs index 56101fa3537..34ca49ea85d 100644 --- a/src/EFCore.Cosmos/Query/Internal/Expressions/ObjectArrayExpression.cs +++ b/src/EFCore.Cosmos/Query/Internal/Expressions/ObjectArrayExpression.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; /// diff --git a/src/EFCore.Cosmos/Query/Internal/Expressions/ObjectArrayIndexExpression.cs b/src/EFCore.Cosmos/Query/Internal/Expressions/ObjectArrayIndexExpression.cs index 3bda0c53100..d29a23d05ad 100644 --- a/src/EFCore.Cosmos/Query/Internal/Expressions/ObjectArrayIndexExpression.cs +++ b/src/EFCore.Cosmos/Query/Internal/Expressions/ObjectArrayIndexExpression.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; /// diff --git a/src/EFCore.Cosmos/Query/Internal/Expressions/ObjectBinaryExpression.cs b/src/EFCore.Cosmos/Query/Internal/Expressions/ObjectBinaryExpression.cs index 433fc59c4dc..273167825ae 100644 --- a/src/EFCore.Cosmos/Query/Internal/Expressions/ObjectBinaryExpression.cs +++ b/src/EFCore.Cosmos/Query/Internal/Expressions/ObjectBinaryExpression.cs @@ -85,7 +85,7 @@ public override ExpressionType NodeType /// protected override Expression VisitChildren(ExpressionVisitor visitor) { - var left = (Expression)visitor.Visit(Left); + var left = visitor.Visit(Left); var right = (Expression)visitor.Visit(Right); return Update(left, right); diff --git a/src/EFCore.Cosmos/Query/Internal/Expressions/ObjectFunctionExpression.cs b/src/EFCore.Cosmos/Query/Internal/Expressions/ObjectFunctionExpression.cs index 13b66a39449..8b0f1641486 100644 --- a/src/EFCore.Cosmos/Query/Internal/Expressions/ObjectFunctionExpression.cs +++ b/src/EFCore.Cosmos/Query/Internal/Expressions/ObjectFunctionExpression.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; /// diff --git a/src/EFCore.Cosmos/Query/Internal/Expressions/ObjectReferenceExpression.cs b/src/EFCore.Cosmos/Query/Internal/Expressions/ObjectReferenceExpression.cs index 5e5b55e3d36..b2fee0d2605 100644 --- a/src/EFCore.Cosmos/Query/Internal/Expressions/ObjectReferenceExpression.cs +++ b/src/EFCore.Cosmos/Query/Internal/Expressions/ObjectReferenceExpression.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; /// diff --git a/src/EFCore.Cosmos/Query/Internal/Expressions/OrderingExpression.cs b/src/EFCore.Cosmos/Query/Internal/Expressions/OrderingExpression.cs index 88b8357145f..e5291c27787 100644 --- a/src/EFCore.Cosmos/Query/Internal/Expressions/OrderingExpression.cs +++ b/src/EFCore.Cosmos/Query/Internal/Expressions/OrderingExpression.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; /// diff --git a/src/EFCore.Cosmos/Query/Internal/Expressions/ProjectionExpression.cs b/src/EFCore.Cosmos/Query/Internal/Expressions/ProjectionExpression.cs index 3ce6b129add..b4378b9e757 100644 --- a/src/EFCore.Cosmos/Query/Internal/Expressions/ProjectionExpression.cs +++ b/src/EFCore.Cosmos/Query/Internal/Expressions/ProjectionExpression.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; /// diff --git a/src/EFCore.Cosmos/Query/Internal/Expressions/ReadItemInfo.cs b/src/EFCore.Cosmos/Query/Internal/Expressions/ReadItemInfo.cs index 9a93540830f..9a023f49544 100644 --- a/src/EFCore.Cosmos/Query/Internal/Expressions/ReadItemInfo.cs +++ b/src/EFCore.Cosmos/Query/Internal/Expressions/ReadItemInfo.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; /// diff --git a/src/EFCore.Cosmos/Query/Internal/Expressions/ScalarAccessExpression.cs b/src/EFCore.Cosmos/Query/Internal/Expressions/ScalarAccessExpression.cs index 23df20780ea..412180a6f8e 100644 --- a/src/EFCore.Cosmos/Query/Internal/Expressions/ScalarAccessExpression.cs +++ b/src/EFCore.Cosmos/Query/Internal/Expressions/ScalarAccessExpression.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; /// diff --git a/src/EFCore.Cosmos/Query/Internal/Expressions/ScalarArrayExpression.cs b/src/EFCore.Cosmos/Query/Internal/Expressions/ScalarArrayExpression.cs index 3e483420717..ad1d5d59713 100644 --- a/src/EFCore.Cosmos/Query/Internal/Expressions/ScalarArrayExpression.cs +++ b/src/EFCore.Cosmos/Query/Internal/Expressions/ScalarArrayExpression.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; /// diff --git a/src/EFCore.Cosmos/Query/Internal/Expressions/ScalarReferenceExpression.cs b/src/EFCore.Cosmos/Query/Internal/Expressions/ScalarReferenceExpression.cs index 7879c8a3cda..e11286240fd 100644 --- a/src/EFCore.Cosmos/Query/Internal/Expressions/ScalarReferenceExpression.cs +++ b/src/EFCore.Cosmos/Query/Internal/Expressions/ScalarReferenceExpression.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; /// diff --git a/src/EFCore.Cosmos/Query/Internal/Expressions/ScalarSubqueryExpression.cs b/src/EFCore.Cosmos/Query/Internal/Expressions/ScalarSubqueryExpression.cs index 2a1f8638671..7fa2c1affcc 100644 --- a/src/EFCore.Cosmos/Query/Internal/Expressions/ScalarSubqueryExpression.cs +++ b/src/EFCore.Cosmos/Query/Internal/Expressions/ScalarSubqueryExpression.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; /// @@ -31,15 +32,11 @@ public ScalarSubqueryExpression(SelectExpression subquery) subquery.Projection[0].Expression is SqlExpression sqlExpression ? sqlExpression.TypeMapping : throw new UnreachableException("Can't construct scalar subquery over SelectExpression with non-SqlExpression projection")) - { - Subquery = subquery; - } + => Subquery = subquery; private ScalarSubqueryExpression(SelectExpression subquery, CoreTypeMapping? typeMapping) : base(subquery.Projection[0].Type, typeMapping) - { - Subquery = subquery; - } + => Subquery = subquery; /// /// The subquery projecting single row with single scalar projection. diff --git a/src/EFCore.Cosmos/Query/Internal/Expressions/SelectExpression.cs b/src/EFCore.Cosmos/Query/Internal/Expressions/SelectExpression.cs index 1b90e563fc3..3f31abdf5a8 100644 --- a/src/EFCore.Cosmos/Query/Internal/Expressions/SelectExpression.cs +++ b/src/EFCore.Cosmos/Query/Internal/Expressions/SelectExpression.cs @@ -1,8 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Cosmos.Internal; +using Microsoft.EntityFrameworkCore.Internal; // ReSharper disable once CheckNamespace namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; @@ -48,7 +48,7 @@ public SelectExpression( SqlExpression? limit) { _sources = sources; - Predicate = predicate; + Predicate = predicate is SqlConstantExpression { Value: true } ? null : predicate; _projection = projections; IsDistinct = distinct; _orderings = orderings; @@ -534,7 +534,7 @@ public override Type Type /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public sealed override ExpressionType NodeType + public override ExpressionType NodeType => ExpressionType.Extension; /// @@ -632,8 +632,7 @@ public SelectExpression Update( return new SelectExpression(sources, predicate, projections, IsDistinct, orderings, offset, limit) { - _projectionMapping = projectionMapping, - ReadItemInfo = ReadItemInfo + _projectionMapping = projectionMapping, ReadItemInfo = ReadItemInfo }; } @@ -646,8 +645,7 @@ public SelectExpression Update( public SelectExpression WithReadItemInfo(ReadItemInfo readItemInfo) => new(Sources.ToList(), Predicate, Projection.ToList(), IsDistinct, Orderings.ToList(), Offset, Limit) { - _projectionMapping = _projectionMapping, - ReadItemInfo = readItemInfo + _projectionMapping = _projectionMapping, ReadItemInfo = readItemInfo }; /// diff --git a/src/EFCore.Cosmos/Query/Internal/Expressions/SourceExpression.cs b/src/EFCore.Cosmos/Query/Internal/Expressions/SourceExpression.cs index 8c0a8a716af..1bc688fcb60 100644 --- a/src/EFCore.Cosmos/Query/Internal/Expressions/SourceExpression.cs +++ b/src/EFCore.Cosmos/Query/Internal/Expressions/SourceExpression.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; /// diff --git a/src/EFCore.Cosmos/Query/Internal/Expressions/SqlConditionalExpression.cs b/src/EFCore.Cosmos/Query/Internal/Expressions/SqlConditionalExpression.cs index f321fd1ecef..241ba92f2c5 100644 --- a/src/EFCore.Cosmos/Query/Internal/Expressions/SqlConditionalExpression.cs +++ b/src/EFCore.Cosmos/Query/Internal/Expressions/SqlConditionalExpression.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; /// diff --git a/src/EFCore.Cosmos/Query/Internal/Expressions/SqlFunctionExpression.cs b/src/EFCore.Cosmos/Query/Internal/Expressions/SqlFunctionExpression.cs index 9b1513285dd..91b53ca7039 100644 --- a/src/EFCore.Cosmos/Query/Internal/Expressions/SqlFunctionExpression.cs +++ b/src/EFCore.Cosmos/Query/Internal/Expressions/SqlFunctionExpression.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; /// diff --git a/src/EFCore.Cosmos/Query/Internal/Expressions/SqlParameterExpression.cs b/src/EFCore.Cosmos/Query/Internal/Expressions/SqlParameterExpression.cs index f8f7dfa640a..fe317979f5a 100644 --- a/src/EFCore.Cosmos/Query/Internal/Expressions/SqlParameterExpression.cs +++ b/src/EFCore.Cosmos/Query/Internal/Expressions/SqlParameterExpression.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; /// diff --git a/src/EFCore.Cosmos/Query/Internal/ISqlExpressionFactory.cs b/src/EFCore.Cosmos/Query/Internal/ISqlExpressionFactory.cs index 1745ba0d8a2..12c46524fc0 100644 --- a/src/EFCore.Cosmos/Query/Internal/ISqlExpressionFactory.cs +++ b/src/EFCore.Cosmos/Query/Internal/ISqlExpressionFactory.cs @@ -282,5 +282,4 @@ public interface ISqlExpressionFactory /// doing so can result in application failures when updating to a new Entity Framework Core release. /// SqlExpression Constant(object? value, Type type, CoreTypeMapping? typeMapping = null); - } diff --git a/src/EFCore.Cosmos/Query/Internal/SqlExpressionFactory.cs b/src/EFCore.Cosmos/Query/Internal/SqlExpressionFactory.cs index 9a25d3f209b..b4cfb0938a5 100644 --- a/src/EFCore.Cosmos/Query/Internal/SqlExpressionFactory.cs +++ b/src/EFCore.Cosmos/Query/Internal/SqlExpressionFactory.cs @@ -166,7 +166,9 @@ private SqlExpression ApplyTypeMappingOnSqlBinary( // TODO: This infers based on the CLR type; need to properly infer based on the element type mapping // TODO: being applied here (e.g. WHERE @p[1] = c.PropertyWithValueConverter). #34026 var arrayTypeMapping = left.TypeMapping - ?? (typeMapping is null ? null : typeMappingSource.FindMapping(typeof(IEnumerable<>).MakeGenericType(typeMapping.ClrType))); + ?? (typeMapping is null + ? null + : typeMappingSource.FindMapping(typeof(IEnumerable<>).MakeGenericType(typeMapping.ClrType))); return new SqlBinaryExpression( ExpressionType.ArrayIndex, ApplyTypeMapping(left, arrayTypeMapping), @@ -435,12 +437,14 @@ private SqlExpression AndAlso(SqlExpression left, SqlExpression right, SqlExpres { return left; } + // true && x -> x // x && false -> false if (left is SqlConstantExpression { Value: true } || right is SqlConstantExpression { Value: false }) { return right; } + // x is null && x is not null -> false // x is not null && x is null -> false if (left is SqlUnaryExpression { OperatorType: ExpressionType.Equal or ExpressionType.NotEqual } leftUnary @@ -450,6 +454,7 @@ private SqlExpression AndAlso(SqlExpression left, SqlExpression right, SqlExpres // the case in which left and right are the same expression is handled above return Constant(false); } + if (existingExpression is SqlBinaryExpression { OperatorType: ExpressionType.AndAlso } binaryExpr && left == binaryExpr.Left && right == binaryExpr.Right) @@ -480,6 +485,7 @@ private SqlExpression OrElse(SqlExpression left, SqlExpression right, SqlExpress { return left; } + // false || x -> x // x || true -> true if (left is SqlConstantExpression { Value: false } @@ -487,6 +493,7 @@ private SqlExpression OrElse(SqlExpression left, SqlExpression right, SqlExpress { return right; } + // x is null || x is not null -> true // x is not null || x is null -> true if (left is SqlUnaryExpression { OperatorType: ExpressionType.Equal or ExpressionType.NotEqual } leftUnary @@ -496,6 +503,7 @@ private SqlExpression OrElse(SqlExpression left, SqlExpression right, SqlExpress // the case in which left and right are the same expression is handled above return Constant(true); } + if (existingExpression is SqlBinaryExpression { OperatorType: ExpressionType.OrElse } binaryExpr && left == binaryExpr.Left && right == binaryExpr.Right) diff --git a/src/EFCore.Cosmos/Query/Internal/Translators/CosmosDateTimeMemberTranslator.cs b/src/EFCore.Cosmos/Query/Internal/Translators/CosmosDateTimeMemberTranslator.cs index 7ab28e58fcd..508995534f0 100644 --- a/src/EFCore.Cosmos/Query/Internal/Translators/CosmosDateTimeMemberTranslator.cs +++ b/src/EFCore.Cosmos/Query/Internal/Translators/CosmosDateTimeMemberTranslator.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; /// diff --git a/src/EFCore.Cosmos/Query/Internal/Translators/CosmosDateTimeMethodTranslator.cs b/src/EFCore.Cosmos/Query/Internal/Translators/CosmosDateTimeMethodTranslator.cs index bbec5002a50..c2e4504dcb3 100644 --- a/src/EFCore.Cosmos/Query/Internal/Translators/CosmosDateTimeMethodTranslator.cs +++ b/src/EFCore.Cosmos/Query/Internal/Translators/CosmosDateTimeMethodTranslator.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; /// diff --git a/src/EFCore.Cosmos/Query/Internal/Translators/CosmosEqualsTranslator.cs b/src/EFCore.Cosmos/Query/Internal/Translators/CosmosEqualsTranslator.cs index 89610cb278a..87a9b8b8e4d 100644 --- a/src/EFCore.Cosmos/Query/Internal/Translators/CosmosEqualsTranslator.cs +++ b/src/EFCore.Cosmos/Query/Internal/Translators/CosmosEqualsTranslator.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; /// diff --git a/src/EFCore.Cosmos/Query/Internal/Translators/CosmosMathTranslator.cs b/src/EFCore.Cosmos/Query/Internal/Translators/CosmosMathTranslator.cs index 66dade5a1f0..3dab9722b31 100644 --- a/src/EFCore.Cosmos/Query/Internal/Translators/CosmosMathTranslator.cs +++ b/src/EFCore.Cosmos/Query/Internal/Translators/CosmosMathTranslator.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; /// diff --git a/src/EFCore.Cosmos/Query/Internal/Translators/CosmosRandomTranslator.cs b/src/EFCore.Cosmos/Query/Internal/Translators/CosmosRandomTranslator.cs index 60b4d81d5d4..5269e7d3ba5 100644 --- a/src/EFCore.Cosmos/Query/Internal/Translators/CosmosRandomTranslator.cs +++ b/src/EFCore.Cosmos/Query/Internal/Translators/CosmosRandomTranslator.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; /// diff --git a/src/EFCore.Cosmos/Query/Internal/Translators/CosmosStringMemberTranslator.cs b/src/EFCore.Cosmos/Query/Internal/Translators/CosmosStringMemberTranslator.cs index 2823f3f77ac..ab59359ce7b 100644 --- a/src/EFCore.Cosmos/Query/Internal/Translators/CosmosStringMemberTranslator.cs +++ b/src/EFCore.Cosmos/Query/Internal/Translators/CosmosStringMemberTranslator.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; /// diff --git a/src/EFCore.Cosmos/Query/Internal/Translators/CosmosStringMethodTranslator.cs b/src/EFCore.Cosmos/Query/Internal/Translators/CosmosStringMethodTranslator.cs index 7a15a8ace21..845409fdc99 100644 --- a/src/EFCore.Cosmos/Query/Internal/Translators/CosmosStringMethodTranslator.cs +++ b/src/EFCore.Cosmos/Query/Internal/Translators/CosmosStringMethodTranslator.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; /// diff --git a/src/EFCore.Cosmos/Storage/Internal/ByteArrayConverter.cs b/src/EFCore.Cosmos/Storage/Internal/ByteArrayConverter.cs index 75ca94f1a4e..fe63cd57d67 100644 --- a/src/EFCore.Cosmos/Storage/Internal/ByteArrayConverter.cs +++ b/src/EFCore.Cosmos/Storage/Internal/ByteArrayConverter.cs @@ -51,7 +51,7 @@ public override void WriteJson( public override object ReadJson( JsonReader reader, Type objectType, - object existingValue, + object? existingValue, JsonSerializer serializer) { if (reader.TokenType != JsonToken.StartArray) diff --git a/src/EFCore.Cosmos/Storage/Internal/CosmosClientWrapper.cs b/src/EFCore.Cosmos/Storage/Internal/CosmosClientWrapper.cs index 7eeb334862f..a5c89b6b37d 100644 --- a/src/EFCore.Cosmos/Storage/Internal/CosmosClientWrapper.cs +++ b/src/EFCore.Cosmos/Storage/Internal/CosmosClientWrapper.cs @@ -359,7 +359,7 @@ private static async Task CreateItemOnceAsync( response.Diagnostics.GetClientElapsedTime(), response.Headers.RequestCharge, response.Headers.ActivityId, - parameters.Document["id"].ToString(), + parameters.Document["id"]!.ToString(), parameters.ContainerId, partitionKeyValue); diff --git a/src/EFCore.Cosmos/Storage/Internal/CosmosDatabaseCreator.cs b/src/EFCore.Cosmos/Storage/Internal/CosmosDatabaseCreator.cs index d55b7a63f9e..79a6f678d0c 100644 --- a/src/EFCore.Cosmos/Storage/Internal/CosmosDatabaseCreator.cs +++ b/src/EFCore.Cosmos/Storage/Internal/CosmosDatabaseCreator.cs @@ -18,6 +18,8 @@ public class CosmosDatabaseCreator : IDatabaseCreator private readonly IDesignTimeModel _designTimeModel; private readonly IUpdateAdapterFactory _updateAdapterFactory; private readonly IDatabase _database; + private readonly ICurrentDbContext _currentContext; + private readonly IDbContextOptions _contextOptions; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -29,12 +31,16 @@ public CosmosDatabaseCreator( ICosmosClientWrapper cosmosClient, IDesignTimeModel designTimeModel, IUpdateAdapterFactory updateAdapterFactory, - IDatabase database) + IDatabase database, + ICurrentDbContext currentContext, + IDbContextOptions contextOptions) { _cosmosClient = cosmosClient; _designTimeModel = designTimeModel; _updateAdapterFactory = updateAdapterFactory; _database = database; + _currentContext = currentContext; + _contextOptions = contextOptions; } /// @@ -55,9 +61,11 @@ public virtual bool EnsureCreated() if (created) { - Seed(); + InsertData(); } + SeedData(created); + return created; } @@ -81,9 +89,11 @@ public virtual async Task EnsureCreatedAsync(CancellationToken cancellatio if (created) { - await SeedAsync(cancellationToken).ConfigureAwait(false); + await InsertDataAsync(cancellationToken).ConfigureAwait(false); } + await SeedDataAsync(created, cancellationToken).ConfigureAwait(false); + return created; } @@ -122,6 +132,7 @@ private static IEnumerable GetContainersToCreate(IModel mod { partitionKeyStoreNames = GetPartitionKeyStoreNames(entityType); } + analyticalTtl ??= entityType.GetAnalyticalStoreTimeToLive(); defaultTtl ??= entityType.GetDefaultTimeToLive(); throughput ??= entityType.GetThroughput(); @@ -153,9 +164,9 @@ private static IEnumerable GetContainersToCreate(IModel mod /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public virtual void Seed() + public virtual void InsertData() { - var updateAdapter = AddSeedData(); + var updateAdapter = AddModelData(); _database.SaveChanges(updateAdapter.GetEntriesToSave()); } @@ -166,14 +177,14 @@ public virtual void Seed() /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public virtual Task SeedAsync(CancellationToken cancellationToken = default) + public virtual Task InsertDataAsync(CancellationToken cancellationToken = default) { - var updateAdapter = AddSeedData(); + var updateAdapter = AddModelData(); return _database.SaveChangesAsync(updateAdapter.GetEntriesToSave(), cancellationToken); } - private IUpdateAdapter AddSeedData() + private IUpdateAdapter AddModelData() { var updateAdapter = _updateAdapterFactory.CreateStandalone(); foreach (var entityType in _designTimeModel.Model.GetEntityTypes()) @@ -189,6 +200,52 @@ private IUpdateAdapter AddSeedData() return updateAdapter; } + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + public virtual void SeedData(bool created) + { + var coreOptionsExtension = + _contextOptions.FindExtension() + ?? new CoreOptionsExtension(); + + var seed = coreOptionsExtension.Seeder; + if (seed != null) + { + seed(_currentContext.Context, created); + } + else if (coreOptionsExtension.AsyncSeeder != null) + { + throw new InvalidOperationException(CoreStrings.MissingSeeder); + } + } + + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + public virtual async Task SeedDataAsync(bool created, CancellationToken cancellationToken = default) + { + var coreOptionsExtension = + _contextOptions.FindExtension() + ?? new CoreOptionsExtension(); + + var seedAsync = coreOptionsExtension.AsyncSeeder; + if (seedAsync != null) + { + await seedAsync(_currentContext.Context, created, cancellationToken).ConfigureAwait(false); + } + else if (coreOptionsExtension.Seeder != null) + { + throw new InvalidOperationException(CoreStrings.MissingSeeder); + } + } + /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in diff --git a/src/EFCore.Cosmos/Storage/Internal/CosmosDatabaseWrapper.cs b/src/EFCore.Cosmos/Storage/Internal/CosmosDatabaseWrapper.cs index 4eed39b426f..0fa8e4e7025 100644 --- a/src/EFCore.Cosmos/Storage/Internal/CosmosDatabaseWrapper.cs +++ b/src/EFCore.Cosmos/Storage/Internal/CosmosDatabaseWrapper.cs @@ -246,7 +246,7 @@ private bool Save(IUpdateEntry entry) if (propertyName != null) { document[propertyName] = - JToken.FromObject(entityType.GetDiscriminatorValue(), CosmosClientWrapper.Serializer); + JToken.FromObject(entityType.GetDiscriminatorValue()!, CosmosClientWrapper.Serializer); } } @@ -377,7 +377,7 @@ private Task SaveAsync(IUpdateEntry entry, CancellationToken cancellationT if (propertyName != null) { document[propertyName] = - JToken.FromObject(entityType.GetDiscriminatorValue(), CosmosClientWrapper.Serializer); + JToken.FromObject(entityType.GetDiscriminatorValue()!, CosmosClientWrapper.Serializer); } } diff --git a/src/EFCore.Cosmos/Storage/Internal/CosmosTypeMappingSource.cs b/src/EFCore.Cosmos/Storage/Internal/CosmosTypeMappingSource.cs index 7588e248520..25f36155528 100644 --- a/src/EFCore.Cosmos/Storage/Internal/CosmosTypeMappingSource.cs +++ b/src/EFCore.Cosmos/Storage/Internal/CosmosTypeMappingSource.cs @@ -28,8 +28,7 @@ public class CosmosTypeMappingSource : TypeMappingSource /// public CosmosTypeMappingSource(TypeMappingSourceDependencies dependencies) : base(dependencies) - { - _clrTypeMappings + => _clrTypeMappings = new Dictionary { { @@ -37,8 +36,6 @@ public CosmosTypeMappingSource(TypeMappingSourceDependencies dependencies) typeof(JObject), jsonValueReaderWriter: dependencies.JsonValueReaderWriterSource.FindReaderWriter(typeof(JObject))) } }; - } - /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Cosmos/Storage/Internal/CosmosVectorTypeMapping.cs b/src/EFCore.Cosmos/Storage/Internal/CosmosVectorTypeMapping.cs index 717e7f92d34..e9279c00e62 100644 --- a/src/EFCore.Cosmos/Storage/Internal/CosmosVectorTypeMapping.cs +++ b/src/EFCore.Cosmos/Storage/Internal/CosmosVectorTypeMapping.cs @@ -24,9 +24,9 @@ public class CosmosVectorTypeMapping : CosmosTypeMapping /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public static new CosmosVectorTypeMapping Default { get; } - // Note that this default is not valid because dimensions cannot be zero. But since there is no reasonable - // default dimensions size for a vector type, this is intentionally not valid rather than just being wrong. - // The fundamental problem here is that type mappings are "required" to have some default now. + // Note that this default is not valid because dimensions cannot be zero. But since there is no reasonable + // default dimensions size for a vector type, this is intentionally not valid rather than just being wrong. + // The fundamental problem here is that type mappings are "required" to have some default now. = new(typeof(byte[]), new CosmosVectorType(DistanceFunction.Cosine, 0)); /// @@ -64,7 +64,8 @@ public CosmosVectorTypeMapping(CosmosTypeMapping mapping, CosmosVectorType vecto : this( new CoreTypeMappingParameters( mapping.ClrType, - converter: mapping.Converter, + // This is a hack to allow both arrays and ROM types without different function overloads or type mappings. + converter: mapping.Converter?.GetType() == typeof(BytesToStringConverter) ? null : mapping.Converter, mapping.Comparer, mapping.KeyComparer, elementMapping: mapping.ElementTypeMapping, @@ -81,9 +82,7 @@ public CosmosVectorTypeMapping(CosmosTypeMapping mapping, CosmosVectorType vecto /// protected CosmosVectorTypeMapping(CoreTypeMappingParameters parameters, CosmosVectorType vectorType) : base(parameters) - { - VectorType = vectorType; - } + => VectorType = vectorType; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -117,4 +116,35 @@ public override CoreTypeMapping WithComposedConverter( /// protected override CoreTypeMapping Clone(CoreTypeMappingParameters parameters) => new CosmosVectorTypeMapping(parameters, VectorType); + + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + public override JToken? GenerateJToken(object? value) + { + // This is a hack to allow both arrays and ROM types without different function overloads or type mappings. + var type = value?.GetType(); + if (type?.IsArray is false) + { + if (type == typeof(ReadOnlyMemory)) + { + value = ((ReadOnlyMemory)value!).ToArray(); + } + else if (type == typeof(ReadOnlyMemory)) + { + value = ((ReadOnlyMemory)value!).ToArray(); + } + else if (type == typeof(ReadOnlyMemory)) + { + value = ((ReadOnlyMemory)value!).ToArray(); + } + } + + return value == null + ? null + : JToken.FromObject(value, CosmosClientWrapper.Serializer); + } } diff --git a/src/EFCore.Cosmos/Storage/Internal/HttpException.cs b/src/EFCore.Cosmos/Storage/Internal/HttpException.cs index 7a3b43ac727..6948fe6a121 100644 --- a/src/EFCore.Cosmos/Storage/Internal/HttpException.cs +++ b/src/EFCore.Cosmos/Storage/Internal/HttpException.cs @@ -19,10 +19,8 @@ public class HttpException : Exception /// public HttpException(HttpResponseMessage response) : base(response.ReasonPhrase) - { - // An error occurred while sending the request. - Response = response; - } + // An error occurred while sending the request. + => Response = response; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Cosmos/Storage/Internal/JsonCosmosSerializer.cs b/src/EFCore.Cosmos/Storage/Internal/JsonCosmosSerializer.cs index 9028cd3b0e6..291e6747e20 100644 --- a/src/EFCore.Cosmos/Storage/Internal/JsonCosmosSerializer.cs +++ b/src/EFCore.Cosmos/Storage/Internal/JsonCosmosSerializer.cs @@ -28,7 +28,7 @@ public override T FromStream(Stream stream) using var streamReader = new StreamReader(stream); using var jsonTextReader = new JsonTextReader(streamReader); - return GetSerializer().Deserialize(jsonTextReader); + return GetSerializer().Deserialize(jsonTextReader)!; } } diff --git a/src/EFCore.Cosmos/Storage/Internal/ReadOnlyMemoryConverter.cs b/src/EFCore.Cosmos/Storage/Internal/ReadOnlyMemoryConverter.cs index e086b4ccaa0..811e8c1d546 100644 --- a/src/EFCore.Cosmos/Storage/Internal/ReadOnlyMemoryConverter.cs +++ b/src/EFCore.Cosmos/Storage/Internal/ReadOnlyMemoryConverter.cs @@ -56,7 +56,7 @@ public static T[] ToArray(ReadOnlyMemory memory) public static ReadOnlyMemory ToMemory(T[] array) // If the array is empty, then return the default ReadOnlyMemory instance because this will compare the same as other empty // ReadOnlyMemory instances, while the instance created with an empty array is considered not equal to the default. - => array.Length == 0 ? default : new(array); + => array.Length == 0 ? default : new ReadOnlyMemory(array); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Design/Design/FluentApiCodeFragment.cs b/src/EFCore.Design/Design/FluentApiCodeFragment.cs index 7ab2eb3d67a..e6bc6f0f24d 100644 --- a/src/EFCore.Design/Design/FluentApiCodeFragment.cs +++ b/src/EFCore.Design/Design/FluentApiCodeFragment.cs @@ -15,9 +15,7 @@ public class FluentApiCodeFragment : IMethodCallCodeFragment /// /// The method's name. public FluentApiCodeFragment(string method) - { - Method = method; - } + => Method = method; /// /// Gets the namespace of the method's declaring type. diff --git a/src/EFCore.Design/Design/Internal/CSharpHelper.cs b/src/EFCore.Design/Design/Internal/CSharpHelper.cs index cb9b7394f84..bcdc1e862e7 100644 --- a/src/EFCore.Design/Design/Internal/CSharpHelper.cs +++ b/src/EFCore.Design/Design/Internal/CSharpHelper.cs @@ -8,11 +8,8 @@ using System.Security; using System.Text; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Editing; -using Microsoft.CodeAnalysis.Simplification; -using Microsoft.CodeAnalysis.Text; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Query.Internal; @@ -1024,11 +1021,11 @@ protected virtual string GetCompositeEnumValue(Type type, Enum flags, bool fullN } return allValues.Aggregate( - (string?)null, - (previous, current) => - previous == null - ? GetSimpleEnumValue(type, Enum.GetName(type, current)!, fullName) - : previous + " | " + GetSimpleEnumValue(type, Enum.GetName(type, current)!, fullName)) + (string?)null, + (previous, current) => + previous == null + ? GetSimpleEnumValue(type, Enum.GetName(type, current)!, fullName) + : previous + " | " + GetSimpleEnumValue(type, Enum.GetName(type, current)!, fullName)) ?? $"({Reference(type)}){UnknownLiteral(Convert.ChangeType(flags, Enum.GetUnderlyingType(type)))}"; } diff --git a/src/EFCore.Design/Design/Internal/DbContextOperations.cs b/src/EFCore.Design/Design/Internal/DbContextOperations.cs index 0c4ae03d1af..d076d3ac68e 100644 --- a/src/EFCore.Design/Design/Internal/DbContextOperations.cs +++ b/src/EFCore.Design/Design/Internal/DbContextOperations.cs @@ -1,14 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.IO; using System.Text; using Microsoft.Build.Locator; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Editing; -using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.MSBuild; -using Microsoft.CodeAnalysis.Simplification; using Microsoft.EntityFrameworkCore.Infrastructure.Internal; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata.Internal; @@ -134,7 +131,13 @@ public virtual string ScriptDbContext(string? contextType) /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual IReadOnlyList Optimize( - string? outputDir, string? modelNamespace, string? contextTypeName, string? suffix, bool scaffoldModel, bool precompileQueries) + string? outputDir, + string? modelNamespace, + string? contextTypeName, + string? suffix, + bool scaffoldModel, + bool precompileQueries, + bool nativeAot) { var optimizeAllInAssembly = contextTypeName == "*"; var contexts = optimizeAllInAssembly ? CreateAllContexts() : [CreateContext(contextTypeName)]; @@ -154,6 +157,7 @@ public virtual IReadOnlyList Optimize( precompileQueries, context, optimizeAllInAssembly, + nativeAot, generatedFiles, generatedFileNames); contextOptimized = true; @@ -184,6 +188,7 @@ private void Optimize( bool precompileQueries, DbContext context, bool optimizeAllInAssembly, + bool nativeAot, List generatedFiles, HashSet generatedFileNames) { @@ -195,7 +200,9 @@ private void Optimize( if (scaffoldModel && (!optimizeAllInAssembly || contextType.Assembly == _assembly)) { - generatedFiles.AddRange(ScaffoldCompiledModel(outputDir, modelNamespace, context, suffix, services, generatedFileNames)); + generatedFiles.AddRange( + ScaffoldCompiledModel( + outputDir, modelNamespace, context, suffix, nativeAot, services, generatedFileNames)); if (precompileQueries) { memberAccessReplacements = ((IRuntimeModel)context.GetService().Model).GetUnsafeAccessors(); @@ -204,13 +211,14 @@ private void Optimize( if (precompileQueries) { - generatedFiles.AddRange(PrecompileQueries( - outputDir, - context, - suffix, - services, - memberAccessReplacements ?? ((IRuntimeModel)context.Model).GetUnsafeAccessors(), - generatedFileNames)); + generatedFiles.AddRange( + PrecompileQueries( + outputDir, + context, + suffix, + services, + memberAccessReplacements ?? ((IRuntimeModel)context.Model).GetUnsafeAccessors(), + generatedFileNames)); } } @@ -219,14 +227,16 @@ private IReadOnlyList ScaffoldCompiledModel( string? modelNamespace, DbContext context, string? suffix, + bool nativeAot, IServiceProvider services, ISet generatedFileNames) { var contextType = context.GetType(); if (contextType.Assembly != _assembly) { - _reporter.WriteWarning(DesignStrings.ContextAssemblyMismatch( - _assembly.GetName().Name, contextType.ShortDisplayName(), contextType.Assembly.GetName().Name)); + _reporter.WriteWarning( + DesignStrings.ContextAssemblyMismatch( + _assembly.GetName().Name, contextType.ShortDisplayName(), contextType.Assembly.GetName().Name)); } if (outputDir == null) @@ -257,6 +267,7 @@ private IReadOnlyList ScaffoldCompiledModel( Language = _language, UseNullableReferenceTypes = _nullable, Suffix = suffix, + ForNativeAot = nativeAot, GeneratedFileNames = generatedFileNames }); @@ -277,7 +288,13 @@ private IReadOnlyList ScaffoldCompiledModel( return scaffoldedFiles; } - private IReadOnlyList PrecompileQueries(string? outputDir, DbContext context, string? suffix, IServiceProvider services, IReadOnlyDictionary memberAccessReplacements, ISet generatedFileNames) + private IReadOnlyList PrecompileQueries( + string? outputDir, + DbContext context, + string? suffix, + IServiceProvider services, + IReadOnlyDictionary memberAccessReplacements, + ISet generatedFileNames) { outputDir = Path.GetFullPath(Path.Combine(_projectDir, outputDir ?? "Generated")); @@ -285,6 +302,7 @@ private IReadOnlyList PrecompileQueries(string? outputDir, DbContext con { MSBuildLocator.RegisterDefaults(); } + // TODO: pass through properties var workspace = MSBuildWorkspace.Create(); workspace.LoadMetadataForReferencedProjects = true; @@ -293,6 +311,7 @@ private IReadOnlyList PrecompileQueries(string? outputDir, DbContext con { throw new NotSupportedException(DesignStrings.UncompilableProject(_project)); } + var compilation = project.GetCompilationAsync().GetAwaiter().GetResult()!; var errorDiagnostics = compilation.GetDiagnostics().Where(d => d.Severity == DiagnosticSeverity.Error).ToArray(); if (errorDiagnostics.Any()) @@ -456,8 +475,9 @@ private DbContext CreateContext(string? contextType, KeyValuePair public DesignTimeConnectionStringResolver(Func? applicationServiceProviderAccessor) - { - _applicationServiceProviderAccessor = applicationServiceProviderAccessor; - } + => _applicationServiceProviderAccessor = applicationServiceProviderAccessor; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Design/Design/Internal/LanguageBasedSelector.cs b/src/EFCore.Design/Design/Internal/LanguageBasedSelector.cs index ef792f73cd3..3c586217eb7 100644 --- a/src/EFCore.Design/Design/Internal/LanguageBasedSelector.cs +++ b/src/EFCore.Design/Design/Internal/LanguageBasedSelector.cs @@ -21,9 +21,7 @@ public abstract class LanguageBasedSelector /// doing so can result in application failures when updating to a new Entity Framework Core release. /// protected LanguageBasedSelector(IEnumerable services) - { - Services = services; - } + => Services = services; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Design/Design/Internal/MigrationsOperations.cs b/src/EFCore.Design/Design/Internal/MigrationsOperations.cs index 419d658cd2e..e841e680ac9 100644 --- a/src/EFCore.Design/Design/Internal/MigrationsOperations.cs +++ b/src/EFCore.Design/Design/Internal/MigrationsOperations.cs @@ -220,8 +220,7 @@ public virtual void UpdateDatabase( EnsureServices(services); var migrator = services.GetRequiredService(); - - migrator.Migrate(targetMigration: targetMigration); + migrator.Migrate(targetMigration); } _reporter.WriteInformation(DesignStrings.Done); diff --git a/src/EFCore.Design/Design/Internal/OperationLoggerProvider.cs b/src/EFCore.Design/Design/Internal/OperationLoggerProvider.cs index d03a884a82b..5bc19daf586 100644 --- a/src/EFCore.Design/Design/Internal/OperationLoggerProvider.cs +++ b/src/EFCore.Design/Design/Internal/OperationLoggerProvider.cs @@ -20,9 +20,7 @@ public class OperationLoggerProvider : ILoggerProvider /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public OperationLoggerProvider(IOperationReporter reporter) - { - _reporter = reporter; - } + => _reporter = reporter; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Design/Design/Internal/OperationReporter.cs b/src/EFCore.Design/Design/Internal/OperationReporter.cs index 84c3e097e39..80522b4a3ba 100644 --- a/src/EFCore.Design/Design/Internal/OperationReporter.cs +++ b/src/EFCore.Design/Design/Internal/OperationReporter.cs @@ -20,9 +20,7 @@ public class OperationReporter : IOperationReporter /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public OperationReporter(IOperationReportHandler? handler) - { - _handler = handler; - } + => _handler = handler; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Design/Design/OperationExecutor.cs b/src/EFCore.Design/Design/OperationExecutor.cs index 70953d2bc88..2c01e920389 100644 --- a/src/EFCore.Design/Design/OperationExecutor.cs +++ b/src/EFCore.Design/Design/OperationExecutor.cs @@ -541,13 +541,29 @@ public OptimizeContext( var suffix = (string?)args["suffix"]; var scaffoldModel = (bool)(args["scaffoldModel"] ?? true); var precompileQueries = (bool)(args["precompileQueries"] ?? false); + var nativeAot = (bool)(args["nativeAot"] ?? false); - Execute(() => executor.OptimizeContextImpl(outputDir, modelNamespace, contextType, suffix, scaffoldModel, precompileQueries)); + Execute( + () => executor.OptimizeContextImpl( + outputDir, + modelNamespace, + contextType, + suffix, + scaffoldModel, + precompileQueries, + nativeAot)); } } + private IReadOnlyList OptimizeContextImpl( - string? outputDir, string? modelNamespace, string? contextType, string? suffix, bool scaffoldModel, bool precompileQueries) - => ContextOperations.Optimize(outputDir, modelNamespace, contextType, suffix, scaffoldModel, precompileQueries); + string? outputDir, + string? modelNamespace, + string? contextType, + string? suffix, + bool scaffoldModel, + bool precompileQueries, + bool nativeAot) + => ContextOperations.Optimize(outputDir, modelNamespace, contextType, suffix, scaffoldModel, precompileQueries, nativeAot); /// /// Represents an operation to scaffold a and entity types for a database. @@ -748,9 +764,7 @@ public abstract class OperationBase : MarshalByRefObject /// /// The . protected OperationBase(IOperationResultHandler resultHandler) - { - _resultHandler = resultHandler; - } + => _resultHandler = resultHandler; /// /// Executes an action passing exceptions to the . diff --git a/src/EFCore.Design/EFCore.Design.csproj b/src/EFCore.Design/EFCore.Design.csproj index 8916afeb532..caae39e9f4f 100644 --- a/src/EFCore.Design/EFCore.Design.csproj +++ b/src/EFCore.Design/EFCore.Design.csproj @@ -8,7 +8,7 @@ true true true - EF9100 + $(NoWarn);EF9100 @@ -56,13 +56,13 @@ - - - - - - - + + + + + + + diff --git a/src/EFCore.Design/Migrations/Design/CSharpMigrationOperationGenerator.cs b/src/EFCore.Design/Migrations/Design/CSharpMigrationOperationGenerator.cs index fd3f544b2c2..ec5b7528229 100644 --- a/src/EFCore.Design/Migrations/Design/CSharpMigrationOperationGenerator.cs +++ b/src/EFCore.Design/Migrations/Design/CSharpMigrationOperationGenerator.cs @@ -19,9 +19,7 @@ public class CSharpMigrationOperationGenerator : ICSharpMigrationOperationGenera /// /// The dependencies. public CSharpMigrationOperationGenerator(CSharpMigrationOperationGeneratorDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore.Design/Migrations/Design/CSharpMigrationOperationGeneratorDependencies.cs b/src/EFCore.Design/Migrations/Design/CSharpMigrationOperationGeneratorDependencies.cs index cfb4ba2f596..0be3c5a308b 100644 --- a/src/EFCore.Design/Migrations/Design/CSharpMigrationOperationGeneratorDependencies.cs +++ b/src/EFCore.Design/Migrations/Design/CSharpMigrationOperationGeneratorDependencies.cs @@ -38,9 +38,7 @@ public sealed record CSharpMigrationOperationGeneratorDependencies /// [EntityFrameworkInternal] public CSharpMigrationOperationGeneratorDependencies(ICSharpHelper csharpHelper) - { - CSharpHelper = csharpHelper; - } + => CSharpHelper = csharpHelper; /// /// The C# helper. diff --git a/src/EFCore.Design/Migrations/Design/CSharpMigrationsGenerator.cs b/src/EFCore.Design/Migrations/Design/CSharpMigrationsGenerator.cs index 5695838b618..80222f83196 100644 --- a/src/EFCore.Design/Migrations/Design/CSharpMigrationsGenerator.cs +++ b/src/EFCore.Design/Migrations/Design/CSharpMigrationsGenerator.cs @@ -21,9 +21,7 @@ public CSharpMigrationsGenerator( MigrationsCodeGeneratorDependencies dependencies, CSharpMigrationsGeneratorDependencies csharpDependencies) : base(dependencies) - { - CSharpDependencies = csharpDependencies; - } + => CSharpDependencies = csharpDependencies; /// /// Dependencies for this service. diff --git a/src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs b/src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs index 78412fd398e..d5efd7f6a81 100644 --- a/src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs +++ b/src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs @@ -36,9 +36,7 @@ private static readonly MethodInfo HasTypeAnnotationMethodInfo /// /// The dependencies. public CSharpSnapshotGenerator(CSharpSnapshotGeneratorDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. @@ -445,7 +443,8 @@ protected virtual void GenerateProperty( var clrType = (FindValueConverter(property)?.ProviderClrType ?? property.ClrType) .MakeNullable(property.IsNullable); - var propertyBuilderName = $"{entityTypeBuilderName}.Property<{Code.Reference(clrType)}>({Code.Literal(property.Name)})"; + var propertyCall = property.IsPrimitiveCollection ? "PrimitiveCollection" : "Property"; + var propertyBuilderName = $"{entityTypeBuilderName}.{propertyCall}<{Code.Reference(clrType)}>({Code.Literal(property.Name)})"; stringBuilder .AppendLine() diff --git a/src/EFCore.Design/Migrations/Design/MigrationsCodeGenerator.cs b/src/EFCore.Design/Migrations/Design/MigrationsCodeGenerator.cs index cea08eaa47d..6fdb07fc11f 100644 --- a/src/EFCore.Design/Migrations/Design/MigrationsCodeGenerator.cs +++ b/src/EFCore.Design/Migrations/Design/MigrationsCodeGenerator.cs @@ -19,9 +19,7 @@ public abstract class MigrationsCodeGenerator : IMigrationsCodeGenerator /// /// The dependencies. protected MigrationsCodeGenerator(MigrationsCodeGeneratorDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Gets the file extension code files should use. diff --git a/src/EFCore.Design/Query/Internal/CSharpToLinqTranslator.cs b/src/EFCore.Design/Query/Internal/CSharpToLinqTranslator.cs index ff6284edc1e..7fef6d89de0 100644 --- a/src/EFCore.Design/Query/Internal/CSharpToLinqTranslator.cs +++ b/src/EFCore.Design/Query/Internal/CSharpToLinqTranslator.cs @@ -78,9 +78,9 @@ private readonly Stack> _parame /// /// The Roslyn syntax node to be translated. /// - /// The for the Roslyn of which is a part. + /// The for the Roslyn of which is a part. /// - /// A LINQ expression tree translated from the provided . + /// A LINQ expression tree translated from the provided . /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in @@ -158,8 +158,9 @@ public override Expression VisitAnonymousObjectCreationExpression(AnonymousObjec var position = Array.FindIndex(parameters, p => p.Name == name); var parameter = parameters[position]; - var parameterType = ResolveType(parameter.Type) ?? throw new InvalidOperationException( - "Could not resolve type symbol for: " + parameter.Type); + var parameterType = ResolveType(parameter.Type) + ?? throw new InvalidOperationException( + "Could not resolve type symbol for: " + parameter.Type); parameterInfos[position] = new FakeParameterInfo(name, parameterType, position); arguments[position] = Visit(initializer.Expression); @@ -240,7 +241,8 @@ public override Expression VisitBinaryExpression(BinaryExpressionSyntax binary) // String concatenation SyntaxKind.AddExpression when left.Type == typeof(string) && right.Type == typeof(string) - => Add(left, right, + => Add( + left, right, _stringConcatMethod ??= typeof(string).GetMethod(nameof(string.Concat), new[] { typeof(string), typeof(string) })), @@ -258,11 +260,15 @@ public override Expression VisitBinaryExpression(BinaryExpressionSyntax binary) // For bitwise operations over enums, we cast the enum to its underlying type before the bitwise operation, and then back to the // enum afterwards (this is corresponds to the LINQ expression tree that the compiler generates) SyntaxKind.BitwiseOrExpression when left.Type.IsEnum || right.Type.IsEnum - => Convert(Or(Convert(left, left.Type.GetEnumUnderlyingType()), Convert(right, right.Type.GetEnumUnderlyingType())), left.Type), + => Convert( + Or(Convert(left, left.Type.GetEnumUnderlyingType()), Convert(right, right.Type.GetEnumUnderlyingType())), left.Type), SyntaxKind.BitwiseAndExpression when left.Type.IsEnum || right.Type.IsEnum - => Convert(And(Convert(left, left.Type.GetEnumUnderlyingType()), Convert(right, right.Type.GetEnumUnderlyingType())), left.Type), + => Convert( + And(Convert(left, left.Type.GetEnumUnderlyingType()), Convert(right, right.Type.GetEnumUnderlyingType())), left.Type), SyntaxKind.ExclusiveOrExpression when left.Type.IsEnum || right.Type.IsEnum - => Convert(ExclusiveOr(Convert(left, left.Type.GetEnumUnderlyingType()), Convert(right, right.Type.GetEnumUnderlyingType())), left.Type), + => Convert( + ExclusiveOr(Convert(left, left.Type.GetEnumUnderlyingType()), Convert(right, right.Type.GetEnumUnderlyingType())), + left.Type), SyntaxKind.BitwiseOrExpression => Or(left, right), SyntaxKind.BitwiseAndExpression => And(left, right), @@ -274,14 +280,16 @@ SyntaxKind.ExclusiveOrExpression when left.Type.IsEnum || right.Type.IsEnum SyntaxKind.LessThanOrEqualExpression => LessThanOrEqual(left, right), SyntaxKind.GreaterThanExpression => GreaterThan(left, right), SyntaxKind.GreaterThanOrEqualExpression => GreaterThanOrEqual(left, right), - SyntaxKind.IsExpression => TypeIs(left, right is ConstantExpression { Value : Type type } - ? type - : throw new InvalidOperationException( - $"Encountered {SyntaxKind.IsExpression} with non-constant type right argument: {right}")), - SyntaxKind.AsExpression => TypeAs(left, right is ConstantExpression { Value : Type type } - ? type - : throw new InvalidOperationException( - $"Encountered {SyntaxKind.AsExpression} with non-constant type right argument: {right}")), + SyntaxKind.IsExpression => TypeIs( + left, right is ConstantExpression { Value : Type type } + ? type + : throw new InvalidOperationException( + $"Encountered {SyntaxKind.IsExpression} with non-constant type right argument: {right}")), + SyntaxKind.AsExpression => TypeAs( + left, right is ConstantExpression { Value : Type type } + ? type + : throw new InvalidOperationException( + $"Encountered {SyntaxKind.AsExpression} with non-constant type right argument: {right}")), SyntaxKind.CoalesceExpression => Coalesce(left, right), _ => throw new ArgumentOutOfRangeException($"BinaryExpressionSyntax with {binary.Kind()}") @@ -323,7 +331,8 @@ public override Expression VisitElementAccessExpression(ElementAccessExpressionS switch (_semanticModel.GetTypeInfo(elementAccessExpression.Expression).ConvertedType) { case IArrayTypeSymbol: - Check.DebugAssert(elementAccessExpression.ArgumentList.Arguments.Count == 1, + Check.DebugAssert( + elementAccessExpression.ArgumentList.Arguments.Count == 1, $"ElementAccessExpressionSyntax over array with {arguments.Count} arguments"); return ArrayIndex(visitedExpression, Visit(arguments[0].Expression)); @@ -471,6 +480,7 @@ public override Expression VisitInterpolatedStringExpression(InterpolatedStringE { interpolationExpression = Convert(interpolationExpression, typeof(object)); } + arguments.Add(interpolationExpression); formatBuilder.Append('{').Append(arguments.Count - 1).Append('}'); break; @@ -545,48 +555,50 @@ public override Expression VisitInvocationExpression(InvocationExpressionSyntax var typeTypeParameterMap = new Dictionary(GetTypeTypeParameters(methodSymbol.ContainingType)); var definitionMethodInfos = declaringType.GetMethods() - .Where(m => - { - if (m.Name == methodSymbol.Name - && m.IsGenericMethodDefinition - && m.GetGenericArguments() is var candidateGenericArguments - && candidateGenericArguments.Length == originalDefinition.TypeParameters.Length - && m.GetParameters() is var candidateParams - && candidateParams.Length == originalDefinition.Parameters.Length) + .Where( + m => { - var methodTypeParameterMap = new Dictionary(typeTypeParameterMap); - - // Prepare a dictionary that will be used to resolve generic type parameters (ITypeParameterSymbol) to the - // corresponding reflection Type. This is needed to correctly (and recursively) resolve the type of parameters - // below. - foreach (var (symbol, type) in methodSymbol.TypeParameters.Zip(candidateGenericArguments)) + if (m.Name == methodSymbol.Name + && m.IsGenericMethodDefinition + && m.GetGenericArguments() is var candidateGenericArguments + && candidateGenericArguments.Length == originalDefinition.TypeParameters.Length + && m.GetParameters() is var candidateParams + && candidateParams.Length == originalDefinition.Parameters.Length) { - if (symbol.Name != type.Name) + var methodTypeParameterMap = new Dictionary(typeTypeParameterMap); + + // Prepare a dictionary that will be used to resolve generic type parameters (ITypeParameterSymbol) to the + // corresponding reflection Type. This is needed to correctly (and recursively) resolve the type of parameters + // below. + foreach (var (symbol, type) in methodSymbol.TypeParameters.Zip(candidateGenericArguments)) { - return false; - } + if (symbol.Name != type.Name) + { + return false; + } - methodTypeParameterMap[symbol.Name] = type; - } + methodTypeParameterMap[symbol.Name] = type; + } - for (var i = 0; i < candidateParams.Length; i++) - { - var translatedParamType = ResolveType(originalDefinition.Parameters[i].Type, methodTypeParameterMap); - if (translatedParamType != candidateParams[i].ParameterType) + for (var i = 0; i < candidateParams.Length; i++) { - return false; + var translatedParamType = ResolveType(originalDefinition.Parameters[i].Type, methodTypeParameterMap); + if (translatedParamType != candidateParams[i].ParameterType) + { + return false; + } } - } - return true; - } + return true; + } - return false; - }).ToArray(); + return false; + }).ToArray(); if (definitionMethodInfos.Length != 1) { - throw new InvalidOperationException($"Invocation: Found {definitionMethodInfos.Length} matches for generic method: {invocation}"); + throw new InvalidOperationException( + $"Invocation: Found {definitionMethodInfos.Length} matches for generic method: {invocation}"); } var definitionMethodInfo = definitionMethodInfos[0]; @@ -1025,8 +1037,8 @@ private Expression VisitLambdaExpression(AnonymousFunctionExpressionSyntax lambd var translatedParameters = new List(); foreach (var parameter in lambdaParameters) { - if (_semanticModel.GetDeclaredSymbol(parameter) is not { } parameterSymbol || - ResolveType(parameterSymbol.Type) is not { } parameterType) + if (_semanticModel.GetDeclaredSymbol(parameter) is not { } parameterSymbol + || ResolveType(parameterSymbol.Type) is not { } parameterType) { throw new InvalidOperationException("Could not found symbol for parameter lambda: " + parameter); } @@ -1034,8 +1046,11 @@ private Expression VisitLambdaExpression(AnonymousFunctionExpressionSyntax lambd translatedParameters.Add(Parameter(parameterType, parameter.Identifier.Text)); } - _parameterStack.Push(_parameterStack.Peek() - .AddRange(translatedParameters.Select(p => new KeyValuePair(p.Name ?? throw new NotImplementedException(), p)))); + _parameterStack.Push( + _parameterStack.Peek() + .AddRange( + translatedParameters.Select( + p => new KeyValuePair(p.Name ?? throw new NotImplementedException(), p)))); try { @@ -1074,7 +1089,8 @@ private Type ResolveType(ITypeSymbol typeSymbol, Dictionary? gener case INamedTypeSymbol { IsAnonymousType: true } anonymousTypeSymbol: _anonymousTypeDefinitions ??= LoadAnonymousTypes(anonymousTypeSymbol.ContainingAssembly); var properties = anonymousTypeSymbol.GetMembers().OfType().ToArray(); - var found = _anonymousTypeDefinitions.TryGetValue(properties.Select(p => p.Name).ToArray(), + var found = _anonymousTypeDefinitions.TryGetValue( + properties.Select(p => p.Name).ToArray(), out var anonymousTypeGenericDefinition); Check.DebugAssert(found, "Anonymous type not found"); @@ -1241,7 +1257,8 @@ public override bool IsDefined(Type attributeType, bool inherit) public override string Name { get; } = name; - public override Type? ReflectedType => null; + public override Type? ReflectedType + => null; // We implement GetValue since ExpressionTreeFuncletizer calls it to get the parameter value. In AOT generation time, we obviously // have no parameter values, nor do we need them for the first part of the query pipeline. @@ -1252,7 +1269,11 @@ public override bool IsDefined(Type attributeType, bool inherit) ? "" : null; - public override void SetValue(object? obj, object? value, BindingFlags invokeAttr, Binder? binder, + public override void SetValue( + object? obj, + object? value, + BindingFlags invokeAttr, + Binder? binder, CultureInfo? culture) => throw new NotSupportedException(); @@ -1296,11 +1317,18 @@ public override MethodAttributes Attributes public override RuntimeMethodHandle MethodHandle => throw new NotSupportedException(); - public override object Invoke(object? obj, BindingFlags invokeAttr, Binder? binder, object?[]? parameters, + public override object Invoke( + object? obj, + BindingFlags invokeAttr, + Binder? binder, + object?[]? parameters, CultureInfo? culture) => throw new NotSupportedException(); - public override object Invoke(BindingFlags invokeAttr, Binder? binder, object?[]? parameters, + public override object Invoke( + BindingFlags invokeAttr, + Binder? binder, + object?[]? parameters, CultureInfo? culture) => throw new NotSupportedException(); } diff --git a/src/EFCore.Design/Query/Internal/LinqToCSharpSyntaxTranslator.cs b/src/EFCore.Design/Query/Internal/LinqToCSharpSyntaxTranslator.cs index 7e3537c1559..ce59c297756 100644 --- a/src/EFCore.Design/Query/Internal/LinqToCSharpSyntaxTranslator.cs +++ b/src/EFCore.Design/Query/Internal/LinqToCSharpSyntaxTranslator.cs @@ -50,6 +50,7 @@ internal LiftedState CreateChild() { child.Variables.Add(parameter, name); } + child.VariableNames.UnionWith(VariableNames); return child; @@ -81,9 +82,7 @@ internal LiftedState CreateChild() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public LinqToCSharpSyntaxTranslator(SyntaxGenerator syntaxGenerator) - { - _g = syntaxGenerator; - } + => _g = syntaxGenerator; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -645,10 +644,8 @@ protected override Expression VisitBlock(BlockExpression block) { throw new NotImplementedException("Label on last expression of an expression block"); } - else - { - statements.Add(pendingLabeledStatement.WithStatement(EmptyStatement())); - } + + statements.Add(pendingLabeledStatement.WithStatement(EmptyStatement())); } // Above we transform top-level assignments (i = 8) to var-declarations with initializers (var i = 8); those variables have @@ -657,7 +654,8 @@ protected override Expression VisitBlock(BlockExpression block) // and either add them to the block, or lift them if we're an expression block. var unassignedVariableDeclarations = unassignedVariables.Select( - v => (LocalDeclarationStatementSyntax)_g.LocalDeclarationStatement(Generate(v.Type), LookupVariableName(v), initializer: _g.DefaultExpression(Generate(v.Type)))); + v => (LocalDeclarationStatementSyntax)_g.LocalDeclarationStatement( + Generate(v.Type), LookupVariableName(v), initializer: _g.DefaultExpression(Generate(v.Type)))); if (blockContext == ExpressionContext.Expression) { @@ -990,25 +988,25 @@ protected virtual ExpressionSyntax GenerateValue(object? value) return value switch { int or long or uint or ulong or short or sbyte or ushort or byte or double or float or decimal or char - or string or bool or null + or string or bool or null => (ExpressionSyntax)_g.LiteralExpression(value), Type t => TypeOfExpression(Generate(t)), Enum e => HandleEnum(e), Guid g => ObjectCreationExpression(IdentifierName(nameof(Guid))) - .WithArgumentList( - ArgumentList( - SingletonSeparatedList( - Argument( - LiteralExpression( - SyntaxKind.StringLiteralExpression, - Literal(g.ToString())))))), + .WithArgumentList( + ArgumentList( + SingletonSeparatedList( + Argument( + LiteralExpression( + SyntaxKind.StringLiteralExpression, + Literal(g.ToString())))))), ITuple tuple when tuple.GetType() is { IsGenericType: true } tupleType - && tupleType.Name.StartsWith("ValueTuple`", StringComparison.Ordinal) - && tupleType.Namespace == "System" + && tupleType.Name.StartsWith("ValueTuple`", StringComparison.Ordinal) + && tupleType.Namespace == "System" => HandleValueTuple(tuple), ReferenceEqualityComparer equalityComparer @@ -1184,7 +1182,8 @@ protected virtual ExpressionSyntax GenerateUnknownValue(object value) throw new NotSupportedException( $"Encountered a constant of unsupported type '{value.GetType().Name}'. Only primitive constant nodes are supported." - + Environment.NewLine + value); + + Environment.NewLine + + value); } /// @@ -1339,30 +1338,19 @@ protected virtual bool TryGenerate(Type type, [NotNullWhen(true)] out TypeSyntax { return false; } - genericArguments.Add(syntax); - } - var generic = GenericName( - Identifier(type.Name.Substring(0, type.Name.IndexOf('`'))), - TypeArgumentList(SeparatedList(genericArguments))); - if (type.IsNested) - { - result = QualifiedName( - (NameSyntax)Generate(type.DeclaringType!), - generic); - return true; + genericArguments.Add(syntax); } - AddNamespace(type); - - result = generic; + result = GenerateGenericType(type, genericArguments, genericArguments.Count); return true; } if (type.IsArray) { result = ArrayType(Generate(type.GetElementType()!)) - .WithRankSpecifiers(SingletonList(ArrayRankSpecifier(SingletonSeparatedList(OmittedArraySizeExpression())))); + .WithRankSpecifiers( + SingletonList(ArrayRankSpecifier(SingletonSeparatedList(OmittedArraySizeExpression())))); return true; } @@ -1470,17 +1458,35 @@ protected virtual bool TryGenerate(Type type, [NotNullWhen(true)] out TypeSyntax return true; } - if (type.IsNested) - { - AddNamespace(type.DeclaringType!); - } - else if (type.Namespace != null) + if (type.Namespace != null) { _collectedNamespaces.Add(type.Namespace); } result = IdentifierName(type.Name); return true; + + NameSyntax GenerateGenericType(Type type, List genericArguments, int length) + { + var offset = type.DeclaringType != null ? type.DeclaringType.GetGenericArguments().Length : 0; + + var genericPartIndex = type.Name.IndexOf('`'); + SimpleNameSyntax nameSyntax = genericPartIndex <= 0 + ? IdentifierName(type.Name) + : GenericName( + Identifier(type.Name.Substring(0, genericPartIndex)), + TypeArgumentList(SeparatedList(genericArguments.Skip(offset).Take(length - offset)))); + if (type.DeclaringType == null) + { + AddNamespace(type); + + return nameSyntax; + } + + return QualifiedName( + GenerateGenericType(type.DeclaringType, genericArguments, offset), + nameSyntax); + } } /// @@ -1537,7 +1543,7 @@ protected override Expression VisitLambda(Expression lambda) SeparatedList( lambda.Parameters.Select( p => Parameter(Identifier(LookupVariableName(p))) - .WithType(p.Type.IsAnonymousType() ? null : Generate(p.Type))))), + .WithType(p.Type.IsAnonymousType() ? null : Generate(p.Type))))), blockBody, expressionBody); @@ -1617,7 +1623,7 @@ protected override Expression VisitMember(MemberExpression member) case { Member: FieldInfo closureField, Expression: ConstantExpression constantExpression } when constantExpression.Type.Attributes.HasFlag(TypeAttributes.NestedPrivate) - && System.Attribute.IsDefined(constantExpression.Type, typeof(CompilerGeneratedAttribute), inherit: true): + && System.Attribute.IsDefined(constantExpression.Type, typeof(CompilerGeneratedAttribute), inherit: true): // Unwrap closure VisitConstant(Expression.Constant(closureField.GetValue(constantExpression.Value), member.Type)); break; @@ -1943,7 +1949,7 @@ protected override Expression VisitMethodCall(MethodCallExpression call) // Extension syntax if (call.Method.IsDefined(typeof(ExtensionAttribute), inherit: false) - && !(arguments[0].Expression is LiteralExpressionSyntax literal && literal.IsKind(SyntaxKind.NullLiteralExpression))) + && !IsNull(arguments[0].Expression)) { Result = InvocationExpression( MemberAccessExpression( @@ -1963,7 +1969,7 @@ protected override Expression VisitMethodCall(MethodCallExpression call) { var expression = call switch { - { Method.IsStatic: true } => GetMemberAccessesForAllDeclaringTypes(call.Method.DeclaringType), + { Method.IsStatic: true } => Generate(call.Method.DeclaringType), // If the member isn't declared on the same type as the expression, (e.g. explicit interface implementation), add // a cast up to the declaring type. @@ -1973,14 +1979,6 @@ protected override Expression VisitMethodCall(MethodCallExpression call) _ => Translate(call.Object) }; - ExpressionSyntax GetMemberAccessesForAllDeclaringTypes(Type type) - => type.DeclaringType is null - ? Generate(type) - : MemberAccessExpression( - SyntaxKind.SimpleMemberAccessExpression, - GetMemberAccessesForAllDeclaringTypes(type.DeclaringType), - IdentifierName(type.Name)); - if (call.Method.Name.StartsWith("get_", StringComparison.Ordinal) && call.Method.GetParameters().Length == 1 && call.Method is { IsHideBySig: true, IsSpecialName: true }) @@ -2031,6 +2029,14 @@ void ProcessType(Type type) } } } + + static bool IsNull(ExpressionSyntax expr) => expr switch + { + LiteralExpressionSyntax literal when literal.IsKind(SyntaxKind.NullLiteralExpression) => true, + CastExpressionSyntax cast => IsNull(cast.Expression), + ParenthesizedExpressionSyntax parenthesized => IsNull(parenthesized.Expression), + _ => false + }; } /// @@ -2704,7 +2710,13 @@ private ExpressionSyntax[] TranslateList(IReadOnlyList list) var liftedStatementsPosition = _liftedState.Statements.Count; - var translated = Translate(expression); + var translated = expression switch + { + // Add an explicit cast to avoid overload resolution ambiguity + ConstantExpression c + when c.Value is null => (ExpressionSyntax)_g.ConvertExpression(Generate(c.Type), GenerateValue(c.Value)), + _ => Translate(expression) + }; if (_liftedState.Statements.Count > liftedStatementsPosition) { diff --git a/src/EFCore.Design/Query/Internal/PrecompiledQueryCodeGenerator.cs b/src/EFCore.Design/Query/Internal/PrecompiledQueryCodeGenerator.cs index cde91a000ab..de2957a65d7 100644 --- a/src/EFCore.Design/Query/Internal/PrecompiledQueryCodeGenerator.cs +++ b/src/EFCore.Design/Query/Internal/PrecompiledQueryCodeGenerator.cs @@ -38,8 +38,9 @@ public class PrecompiledQueryCodeGenerator : IPrecompiledQueryCodeGenerator private const string InterceptorsNamespace = "Microsoft.EntityFrameworkCore.GeneratedInterceptors"; - /// - public string? Language => "C#"; + /// + public string? Language + => "C#"; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -221,7 +222,7 @@ public virtual IReadOnlyList GeneratePrecompiledQueries( } catch (Exception e) { - precompilationErrors.Add(new(querySyntax, e)); + precompilationErrors.Add(new QueryPrecompilationError(querySyntax, e)); continue; } @@ -245,6 +246,7 @@ public virtual IReadOnlyList GeneratePrecompiledQueries( { _code.AppendLine(unsafeAccessor.NormalizeWhitespace().ToFullString()); } + _code.AppendLine("#endregion Unsafe accessors"); } @@ -314,7 +316,7 @@ public InterceptsLocationAttribute(string filePath, int line, int column) { } generatedFileNames, ".EFInterceptors" + suffix + Path.GetExtension(syntaxTree.FilePath), CompiledModelScaffolder.MaxFileNameLength); - return new(name, _code.ToString()); + return new ScaffoldedFile(name, _code.ToString()); } /// @@ -467,7 +469,7 @@ private void GenerateOperatorInterceptor( ? (reducedOperatorSymbol.Parameters[0].Name, reducedOperatorSymbol.Parameters[0].Type) : ("source", reducedOperatorSymbol.ReceiverType!); - if (sourceTypeSymbol is not INamedTypeSymbol { TypeArguments: [var sourceElementTypeSymbol]}) + if (sourceTypeSymbol is not INamedTypeSymbol { TypeArguments: [var sourceElementTypeSymbol] }) { throw new UnreachableException($"Non-IQueryable first parameter in LINQ operator '{operatorSymbol.Name}'"); } @@ -498,7 +500,8 @@ when namedReturnType2.AllInterfaces.Prepend(namedReturnType2) // Output the interceptor method signature preceded by the [InterceptsLocation] attribute. var startPosition = operatorSyntax.SyntaxTree.GetLineSpan(memberAccessSyntax.Name.Span, cancellationToken).StartLinePosition; var interceptorName = $"Query{queryNum}_{memberAccessSyntax.Name}{operatorNum}"; - code.AppendLine($"""[InterceptsLocation(@"{operatorSyntax.SyntaxTree.FilePath.Replace("\"","\"\"")}", {startPosition.Line + 1}, {startPosition.Character + 1})]"""); + code.AppendLine( + $"""[InterceptsLocation(@"{operatorSyntax.SyntaxTree.FilePath.Replace("\"", "\"\"")}", {startPosition.Line + 1}, {startPosition.Character + 1})]"""); GenerateInterceptorMethodSignature(); code.AppendLine("{").IncrementIndent(); @@ -550,8 +553,8 @@ when namedReturnType2.AllInterfaces.Prepend(namedReturnType2) || genericDefinition == typeof(IAsyncEnumerable<>)); var isQueryable = !isAsync - && operatorExpression.Type.IsGenericType - && operatorExpression.Type.GetGenericTypeDefinition() == typeof(IQueryable<>); + && operatorExpression.Type.IsGenericType + && operatorExpression.Type.GetGenericTypeDefinition() == typeof(IQueryable<>); var returnValue = isAsync ? $"IAsyncEnumerable<{sourceElementTypeName}>" @@ -583,7 +586,8 @@ when namedReturnType2.AllInterfaces.Prepend(namedReturnType2) // TODO: This is an additional runtime allocation; if we had System.Linq.Async we wouldn't need this. We could // have additional versions of all async terminating operators over IAsyncEnumerable (effectively duplicating // System.Linq.Async) as an alternative. - code.AppendLine($"var asyncQueryingEnumerable = new PrecompiledQueryableAsyncEnumerableAdapter<{sourceElementTypeName}>(queryingEnumerable);"); + code.AppendLine( + $"var asyncQueryingEnumerable = new PrecompiledQueryableAsyncEnumerableAdapter<{sourceElementTypeName}>(queryingEnumerable);"); code.Append("return asyncQueryingEnumerable"); } else @@ -636,13 +640,16 @@ void GenerateInterceptorMethodSignature() .Append(' ') .Append(interceptorName); - var (typeParameters, constraints) = (reducedOperatorSymbol.IsGenericMethod, reducedOperatorSymbol.ContainingType.IsGenericType) switch - { - (true, false) => (reducedOperatorSymbol.TypeParameters, ((MethodDeclarationSyntax)_g.MethodDeclaration(reducedOperatorSymbol)).ConstraintClauses), - (false, true) => (reducedOperatorSymbol.ContainingType.TypeParameters, ((TypeDeclarationSyntax)_g.Declaration(reducedOperatorSymbol.ContainingType)).ConstraintClauses), - (false, false) => ([], []), - (true, true) => throw new NotImplementedException("Generic method on generic type not supported") - }; + var (typeParameters, constraints) = + (reducedOperatorSymbol.IsGenericMethod, reducedOperatorSymbol.ContainingType.IsGenericType) switch + { + (true, false) => (reducedOperatorSymbol.TypeParameters, + ((MethodDeclarationSyntax)_g.MethodDeclaration(reducedOperatorSymbol)).ConstraintClauses), + (false, true) => (reducedOperatorSymbol.ContainingType.TypeParameters, + ((TypeDeclarationSyntax)_g.Declaration(reducedOperatorSymbol.ContainingType)).ConstraintClauses), + (false, false) => ([], []), + (true, true) => throw new NotImplementedException("Generic method on generic type not supported") + }; if (typeParameters.Length > 0) { @@ -774,7 +781,8 @@ void GenerateCapturedVariableExtractors( var collectedNamespaces = new HashSet(); var unsafeAccessors = new HashSet(); var roslynPathSegment = _linqToCSharpTranslator.TranslateExpression( - linqPathSegment, constantReplacements: null, _memberAccessReplacements, collectedNamespaces, unsafeAccessors); + linqPathSegment, constantReplacements: null, _memberAccessReplacements, collectedNamespaces, + unsafeAccessors); var variableName = capturedVariablesPathTree.ExpressionType.Name; variableName = char.ToLower(variableName[0]) + variableName[1..^"Expression".Length] + ++variableCounter; @@ -1066,10 +1074,14 @@ or nameof(EntityFrameworkQueryableExtensions.ToListAsync) method.GetParameters()[1].ParameterType.GenericTypeArguments[0].GenericTypeArguments[1])), // ExecuteDelete/Update behave just like other scalar-returning operators - nameof(EntityFrameworkQueryableExtensions.ExecuteDeleteAsync) when method.DeclaringType == typeof(EntityFrameworkQueryableExtensions) - => RewriteToSync(typeof(EntityFrameworkQueryableExtensions).GetMethod(nameof(EntityFrameworkQueryableExtensions.ExecuteDelete))), - nameof(EntityFrameworkQueryableExtensions.ExecuteUpdateAsync) when method.DeclaringType == typeof(EntityFrameworkQueryableExtensions) - => RewriteToSync(typeof(EntityFrameworkQueryableExtensions).GetMethod(nameof(EntityFrameworkQueryableExtensions.ExecuteUpdate))), + nameof(EntityFrameworkQueryableExtensions.ExecuteDeleteAsync) when method.DeclaringType + == typeof(EntityFrameworkQueryableExtensions) + => RewriteToSync( + typeof(EntityFrameworkQueryableExtensions).GetMethod(nameof(EntityFrameworkQueryableExtensions.ExecuteDelete))), + nameof(EntityFrameworkQueryableExtensions.ExecuteUpdateAsync) when method.DeclaringType + == typeof(EntityFrameworkQueryableExtensions) + => RewriteToSync( + typeof(EntityFrameworkQueryableExtensions).GetMethod(nameof(EntityFrameworkQueryableExtensions.ExecuteUpdate))), // In the regular case (sync terminating operator which needs to stay in the query tree), simply compose the terminating // operator over the penultimate and return that. diff --git a/src/EFCore.Design/Query/Internal/QueryLocator.cs b/src/EFCore.Design/Query/Internal/QueryLocator.cs index aa2ed595246..4e30a445f55 100644 --- a/src/EFCore.Design/Query/Internal/QueryLocator.cs +++ b/src/EFCore.Design/Query/Internal/QueryLocator.cs @@ -33,7 +33,6 @@ public class QueryLocator : CSharpSyntaxWalker private List _locatedQueries = null!; private List _precompilationErrors = null!; - /// /// Loads a new , representing a user project in which to locate queries. /// @@ -55,7 +54,7 @@ public virtual void Initialize(Compilation compilation) /// /// A in which to locate EF LINQ queries. /// - /// A list of errors populated with dynamic LINQ queries detected in . + /// A list of errors populated with dynamic LINQ queries detected in . /// /// A to observe while waiting for the task to complete. /// A list of EF LINQ queries confirmed to be compatible with precompilation. @@ -82,7 +81,7 @@ public virtual IReadOnlyList LocateQueries( _cancellationToken = cancellationToken; _semanticModel = _compilation.GetSemanticModel(syntaxTree); - _locatedQueries = new(); + _locatedQueries = new List(); _precompilationErrors = precompilationErrors; Visit(syntaxTree.GetRoot(cancellationToken)); @@ -247,7 +246,8 @@ private bool ProcessQueryCandidate(InvocationExpressionSyntax query) if (innerExpression is QueryExpressionSyntax or ParenthesizedExpressionSyntax { Expression: QueryExpressionSyntax }) { _precompilationErrors.Add( - new(query, new InvalidOperationException(DesignStrings.QueryComprehensionSyntaxNotSupportedInPrecompiledQueries))); + new PrecompiledQueryCodeGenerator.QueryPrecompilationError( + query, new InvalidOperationException(DesignStrings.QueryComprehensionSyntaxNotSupportedInPrecompiledQueries))); return false; } @@ -273,7 +273,9 @@ private bool ProcessQueryCandidate(InvocationExpressionSyntax query) return true; } - _precompilationErrors.Add(new(query, new InvalidOperationException(DesignStrings.DynamicQueryNotSupported))); + _precompilationErrors.Add( + new PrecompiledQueryCodeGenerator.QueryPrecompilationError( + query, new InvalidOperationException(DesignStrings.DynamicQueryNotSupported))); return false; bool IsDbContext(ExpressionSyntax expression) diff --git a/src/EFCore.Design/Query/Internal/RuntimeModelLinqToCSharpSyntaxTranslator.cs b/src/EFCore.Design/Query/Internal/RuntimeModelLinqToCSharpSyntaxTranslator.cs index def66e6c68c..06ef309ed3d 100644 --- a/src/EFCore.Design/Query/Internal/RuntimeModelLinqToCSharpSyntaxTranslator.cs +++ b/src/EFCore.Design/Query/Internal/RuntimeModelLinqToCSharpSyntaxTranslator.cs @@ -1,14 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -// ReSharper disable once CheckNamespace - using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Editing; using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; using Microsoft.EntityFrameworkCore.Design.Internal; +// ReSharper disable once CheckNamespace using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; namespace Microsoft.EntityFrameworkCore.Query.Internal; @@ -29,7 +28,8 @@ public class RuntimeModelLinqToCSharpSyntaxTranslator : LinqToCSharpSyntaxTransl /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public RuntimeModelLinqToCSharpSyntaxTranslator(SyntaxGenerator syntaxGenerator) : base(syntaxGenerator) + public RuntimeModelLinqToCSharpSyntaxTranslator(SyntaxGenerator syntaxGenerator) + : base(syntaxGenerator) { } @@ -118,7 +118,10 @@ protected override void TranslateNonPublicMemberAccess(MemberExpression memberEx /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - protected override void TranslateNonPublicMemberAssignment(MemberExpression memberExpression, Expression value, SyntaxKind assignmentKind) + protected override void TranslateNonPublicMemberAssignment( + MemberExpression memberExpression, + Expression value, + SyntaxKind assignmentKind) { var propertyInfo = memberExpression.Member as PropertyInfo; var member = propertyInfo?.SetMethod ?? memberExpression.Member; @@ -134,15 +137,18 @@ protected override void TranslateNonPublicMemberAssignment(MemberExpression memb Result = InvocationExpression( IdentifierName(methodName.Name), - ArgumentList(SeparatedList(new[] - { - Argument(Translate(memberExpression.Expression)), - Argument(Translate(value)) - }))); + ArgumentList( + SeparatedList( + new[] + { + Argument(Translate(memberExpression.Expression)), + Argument(Translate(value)) + }))); } else { - Result = AssignmentExpression(assignmentKind, + Result = AssignmentExpression( + assignmentKind, InvocationExpression( IdentifierName(methodName.Name), ArgumentList(SeparatedList(new[] { Argument(Translate(memberExpression.Expression)) }))), diff --git a/src/EFCore.Design/Scaffolding/CompiledModelCodeGenerationOptions.cs b/src/EFCore.Design/Scaffolding/CompiledModelCodeGenerationOptions.cs index 409565d74a8..74774ea74dc 100644 --- a/src/EFCore.Design/Scaffolding/CompiledModelCodeGenerationOptions.cs +++ b/src/EFCore.Design/Scaffolding/CompiledModelCodeGenerationOptions.cs @@ -38,6 +38,12 @@ public class CompiledModelCodeGenerationOptions /// The suffix to attach to the name of all the generated files. public virtual string? Suffix { get; set; } + /// + /// Gets or sets a value indicating whether the generated code should be compatible with NativeAOT. + /// + /// A value indicating whether the generated code should be compatible with NativeAOT. + public virtual bool ForNativeAot { get; set; } + /// /// Gets or sets the set of file names generated so far. /// diff --git a/src/EFCore.Design/Scaffolding/Internal/CSharpModelGenerator.cs b/src/EFCore.Design/Scaffolding/Internal/CSharpModelGenerator.cs index a2eb3f45bfa..7bdbd7366c3 100644 --- a/src/EFCore.Design/Scaffolding/Internal/CSharpModelGenerator.cs +++ b/src/EFCore.Design/Scaffolding/Internal/CSharpModelGenerator.cs @@ -80,10 +80,11 @@ public override ScaffoldedModel GenerateModel( var resultingFiles = new ScaffoldedModel { ContextFile = new ScaffoldedFile - (options.ContextDir != null + ( + options.ContextDir != null ? Path.Combine(options.ContextDir, dbContextFileName) : dbContextFileName, - generatedCode) + generatedCode) }; foreach (var entityType in model.GetEntityTypes()) diff --git a/src/EFCore.Design/Scaffolding/Internal/CSharpRuntimeModelCodeGenerator.cs b/src/EFCore.Design/Scaffolding/Internal/CSharpRuntimeModelCodeGenerator.cs index bc65c7aeed0..8a6f8f35c99 100644 --- a/src/EFCore.Design/Scaffolding/Internal/CSharpRuntimeModelCodeGenerator.cs +++ b/src/EFCore.Design/Scaffolding/Internal/CSharpRuntimeModelCodeGenerator.cs @@ -68,59 +68,63 @@ public virtual IReadOnlyCollection GenerateModel( var assemblyAttributesCode = CreateAssemblyAttributes(options.ModelNamespace, options.ContextType, nullable); var assemblyInfoFileName = UniquifyFileName(options.ContextType.ShortDisplayName() + AssemblyAttributesSuffix, options); - scaffoldedFiles.Add(new(assemblyInfoFileName, assemblyAttributesCode)); + scaffoldedFiles.Add(new ScaffoldedFile(assemblyInfoFileName, assemblyAttributesCode)); - var unsafeAccessorClassNames = new BidirectionalDictionary(); - var unsafeAccessorTypes = new Dictionary>(); var memberAccessReplacements = new Dictionary(); - foreach (var entityType in model.GetEntityTypes()) + if (options.ForNativeAot) { - RegisterPrivateAccessors(entityType, options, unsafeAccessorClassNames, unsafeAccessorTypes, memberAccessReplacements); - - foreach (var navigation in entityType.GetDeclaredNavigations()) + var unsafeAccessorClassNames = new BidirectionalDictionary(); + var unsafeAccessorTypes = new Dictionary>(); + foreach (var entityType in model.GetEntityTypes()) { - RegisterPrivateAccessors( - navigation, options.ModelNamespace, unsafeAccessorClassNames, unsafeAccessorTypes, memberAccessReplacements); - } + RegisterPrivateAccessors(entityType, options, unsafeAccessorClassNames, unsafeAccessorTypes, memberAccessReplacements); - foreach (var navigation in entityType.GetDeclaredSkipNavigations()) - { - RegisterPrivateAccessors( - navigation, options.ModelNamespace, unsafeAccessorClassNames, unsafeAccessorTypes, memberAccessReplacements); + foreach (var navigation in entityType.GetDeclaredNavigations()) + { + RegisterPrivateAccessors( + navigation, options.ModelNamespace, unsafeAccessorClassNames, unsafeAccessorTypes, memberAccessReplacements); + } + + foreach (var navigation in entityType.GetDeclaredSkipNavigations()) + { + RegisterPrivateAccessors( + navigation, options.ModelNamespace, unsafeAccessorClassNames, unsafeAccessorTypes, memberAccessReplacements); + } } - } - foreach (var unsafeAccessorPair in unsafeAccessorTypes) - { - (var unsafeAccessorType, var members) = unsafeAccessorPair; - var generatedCode = GenerateUnsafeAccessorType( - unsafeAccessorType, - members, - options.ModelNamespace, - unsafeAccessorClassNames[unsafeAccessorType], - memberAccessReplacements, - nullable); + foreach (var unsafeAccessorPair in unsafeAccessorTypes) + { + var (unsafeAccessorType, members) = unsafeAccessorPair; + var generatedCode = GenerateUnsafeAccessorType( + unsafeAccessorType, + members, + options.ModelNamespace, + unsafeAccessorClassNames[unsafeAccessorType], + memberAccessReplacements, + nullable); - var entityTypeFileName = UniquifyFileName(unsafeAccessorClassNames[unsafeAccessorType], options); - scaffoldedFiles.Add(new(entityTypeFileName, generatedCode)); + var entityTypeFileName = UniquifyFileName(unsafeAccessorClassNames[unsafeAccessorType], options); + scaffoldedFiles.Add(new ScaffoldedFile(entityTypeFileName, generatedCode)); + } } var modelCode = CreateModel(options.ModelNamespace, options.ContextType, nullable); var modelFileName = UniquifyFileName(options.ContextType.ShortDisplayName() + ModelSuffix, options); - scaffoldedFiles.Add(new(modelFileName, modelCode)); + scaffoldedFiles.Add(new ScaffoldedFile(modelFileName, modelCode)); var configurationClassNames = new Dictionary(); var modelBuilderCode = CreateModelBuilder( - model, options.ModelNamespace, options.ContextType, configurationClassNames, nullable); + model, options.ModelNamespace, options.ContextType, configurationClassNames, nullable, options.ForNativeAot); var modelBuilderFileName = UniquifyFileName(options.ContextType.ShortDisplayName() + ModelBuilderSuffix, options); - scaffoldedFiles.Add(new(modelBuilderFileName, modelBuilderCode)); + scaffoldedFiles.Add(new ScaffoldedFile(modelBuilderFileName, modelBuilderCode)); foreach (var entityType in model.GetEntityTypesInHierarchicalOrder()) { - var generatedCode = GenerateEntityType(entityType, options.ModelNamespace, configurationClassNames, memberAccessReplacements, nullable); + var generatedCode = GenerateEntityType( + entityType, options.ModelNamespace, configurationClassNames, memberAccessReplacements, nullable, options.ForNativeAot); var entityTypeFileName = UniquifyFileName(configurationClassNames[entityType], options); - scaffoldedFiles.Add(new(entityTypeFileName, generatedCode)); + scaffoldedFiles.Add(new ScaffoldedFile(entityTypeFileName, generatedCode)); } return scaffoldedFiles; @@ -173,11 +177,7 @@ private string CreateAssemblyAttributes( bool nullable) { var mainBuilder = new IndentedStringBuilder(); - var namespaces = new SortedSet(new NamespaceComparer()) - { - typeof(DbContextModelAttribute).Namespace!, - @namespace - }; + var namespaces = new SortedSet(new NamespaceComparer()) { typeof(DbContextModelAttribute).Namespace!, @namespace }; AddNamespace(contextType, namespaces); @@ -188,7 +188,8 @@ private string CreateAssemblyAttributes( return GenerateHeader(namespaces, currentNamespace: "", nullable) + mainBuilder; } - private string GetModelClassName(Type contextType) => _code.Identifier(contextType.ShortDisplayName()) + ModelSuffix; + private string GetModelClassName(Type contextType) + => _code.Identifier(contextType.ShortDisplayName()) + ModelSuffix; private string GenerateUnsafeAccessorType( Type type, @@ -218,7 +219,7 @@ private string GenerateUnsafeAccessorType( var genericParameters = type.GetGenericArguments(); mainBuilder .Append("<") - .AppendJoin(genericParameters.Select(a => _code.Reference(a)), ", ") + .AppendJoin(genericParameters.Select(a => _code.Reference(a))) .AppendLine(">"); using (mainBuilder.Indent()) @@ -226,7 +227,8 @@ private string GenerateUnsafeAccessorType( foreach (var genericParameter in genericParameters) { if (genericParameter.GetGenericParameterConstraints().Length == 0 - && (genericParameter.GenericParameterAttributes & GenericParameterAttributes.SpecialConstraintMask) == GenericParameterAttributes.None) + && (genericParameter.GenericParameterAttributes & GenericParameterAttributes.SpecialConstraintMask) + == GenericParameterAttributes.None) { continue; } @@ -248,12 +250,14 @@ private string GenerateUnsafeAccessorType( constraintList.Add("class"); } - if (constraintAttributes.HasFlag(GenericParameterAttributes.DefaultConstructorConstraint)) + if (constraintAttributes.HasFlag(GenericParameterAttributes.DefaultConstructorConstraint) + && !constraintAttributes.HasFlag(GenericParameterAttributes.NotNullableValueTypeConstraint)) { constraintList.Add("new()"); } - Check.DebugAssert(!constraintAttributes.HasFlag(GenericParameterAttributes.VarianceMask), + Check.DebugAssert( + !constraintAttributes.HasFlag(GenericParameterAttributes.VarianceMask), "Variance constraints not supported for type: " + type.DisplayName()); } @@ -262,13 +266,18 @@ private string GenerateUnsafeAccessorType( { foreach (var constraint in constraints) { + if (constraint == typeof(ValueType)) + { + continue; + } + AddNamespace(constraint, namespaces); constraintList.Add(_code.Reference(constraint)); } } mainBuilder - .AppendJoin(constraintList, ", ") + .AppendJoin(constraintList) .AppendLine(); } } @@ -291,7 +300,8 @@ private string GenerateUnsafeAccessorType( scopeVariables.Inverse, scopeVariables, configurationClassNames: [], - nullable); + nullable, + nativeAot: true); mainBuilder .Append("{"); @@ -347,7 +357,8 @@ private string CreateModel( .Append("public partial class ").Append(className).AppendLine(" : " + nameof(RuntimeModel)) .AppendLine("{") .AppendLine(" private static readonly bool _useOldBehavior31751 =") - .AppendLine(@" System.AppContext.TryGetSwitch(""Microsoft.EntityFrameworkCore.Issue31751"", out var enabled31751) && enabled31751;") + .AppendLine( + @" System.AppContext.TryGetSwitch(""Microsoft.EntityFrameworkCore.Issue31751"", out var enabled31751) && enabled31751;") .AppendLine(); using (mainBuilder.Indent()) @@ -407,7 +418,8 @@ private string CreateModelBuilder( string @namespace, Type contextType, Dictionary configurationClassNames, - bool nullable) + bool nullable, + bool nativeAot) { var mainBuilder = new IndentedStringBuilder(); var methodBuilder = new IndentedStringBuilder(); @@ -581,7 +593,8 @@ private string CreateModelBuilder( scopeVariables.Inverse, scopeVariables, configurationClassNames, - nullable); + nullable, + nativeAot); foreach (var typeConfiguration in model.GetTypeMappingConfigurations()) { @@ -692,7 +705,8 @@ private string GenerateEntityType( string @namespace, Dictionary entityClassNames, Dictionary memberAccessReplacements, - bool nullable) + bool nullable, + bool nativeAot) { var mainBuilder = new IndentedStringBuilder(); var methodBuilder = new IndentedStringBuilder(); @@ -717,26 +731,36 @@ private string GenerateEntityType( .AppendLine("{"); using (mainBuilder.Indent()) { - CreateEntityType(entityType, @namespace, mainBuilder, methodBuilder, namespaces, entityClassNames, memberAccessReplacements, nullable); + CreateEntityType( + entityType, @namespace, mainBuilder, methodBuilder, namespaces, entityClassNames, memberAccessReplacements, nullable, + nativeAot); foreach (var complexProperty in entityType.GetDeclaredComplexProperties()) { - CreateComplexProperty(complexProperty, @namespace, mainBuilder, methodBuilder, namespaces, entityClassNames, memberAccessReplacements, className, nullable); + CreateComplexProperty( + complexProperty, @namespace, mainBuilder, methodBuilder, namespaces, entityClassNames, memberAccessReplacements, + className, nullable, nativeAot); } var foreignKeyNumber = 1; foreach (var foreignKey in entityType.GetDeclaredForeignKeys()) { - CreateForeignKey(foreignKey, foreignKeyNumber++, @namespace, mainBuilder, methodBuilder, namespaces, entityClassNames, memberAccessReplacements, className, nullable); + CreateForeignKey( + foreignKey, foreignKeyNumber++, @namespace, mainBuilder, methodBuilder, namespaces, entityClassNames, + memberAccessReplacements, className, nullable, nativeAot); } var navigationNumber = 1; foreach (var navigation in entityType.GetDeclaredSkipNavigations()) { - CreateSkipNavigation(navigation, navigationNumber++, @namespace, mainBuilder, methodBuilder, namespaces, entityClassNames, memberAccessReplacements, className, nullable); + CreateSkipNavigation( + navigation, navigationNumber++, @namespace, mainBuilder, methodBuilder, namespaces, entityClassNames, + memberAccessReplacements, className, nullable, nativeAot); } - CreateAnnotations(entityType, @namespace, mainBuilder, methodBuilder, namespaces, entityClassNames, memberAccessReplacements, nullable); + CreateAnnotations( + entityType, @namespace, mainBuilder, methodBuilder, namespaces, entityClassNames, memberAccessReplacements, nullable, + nativeAot); var methods = methodBuilder.ToString(); if (!string.IsNullOrEmpty(methods)) @@ -764,7 +788,8 @@ private void CreateEntityType( SortedSet namespaces, Dictionary configurationClassNames, Dictionary memberAccessReplacements, - bool nullable) + bool nullable, + bool nativeAot) { mainBuilder .Append("public static RuntimeEntityType Create") @@ -800,7 +825,8 @@ private void CreateEntityType( scopeVariables.Inverse, scopeVariables, configurationClassNames, - nullable); + nullable, + nativeAot); Create(entityType, parameters); @@ -1155,7 +1181,7 @@ private void Create( { AddNamespace(valueComparerType, parameters.Namespaces); - var valueComparerString = $"new {_code.Reference(valueComparerType)}()" ; + var valueComparerString = $"new {_code.Reference(valueComparerType)}()"; if (property.ClrType.IsNullableValueType()) { var valueComparerElementType = ((ValueComparer)Activator.CreateInstance(valueComparerType)!).Type; @@ -1209,67 +1235,72 @@ private void Create( SetPropertyBaseProperties(property, memberAccessReplacements, propertyParameters); - mainBuilder.Append(variableName).Append(".TypeMapping = "); - _annotationCodeGenerator.Create(property.GetTypeMapping(), property, propertyParameters); - mainBuilder.AppendLine(";"); + var shouldSetConverter = providerClrType == null + && valueConverterType == null + && converter != null + && property[CoreAnnotationNames.ValueConverter] != null + && !parameters.ForNativeAot; + + if (parameters.ForNativeAot + || (shouldSetConverter && converter!.MappingHints != null)) + { + shouldSetConverter = false; + mainBuilder.Append(variableName).Append(".TypeMapping = "); + _annotationCodeGenerator.Create(property.GetTypeMapping(), property, propertyParameters); + mainBuilder.AppendLine(";"); + } + + if (parameters.ForNativeAot + && (property.IsKey() + || property.IsForeignKey() + || property.IsUniqueIndex())) + { + var currentComparerType = CurrentValueComparerFactory.Instance.GetComparerType(property); + AddNamespace(currentComparerType, parameters.Namespaces); + + mainBuilder + .Append(variableName).Append(".SetCurrentValueComparer(new ") + .Append(_code.Reference(currentComparerType)) + .AppendLine($"({variableName}));"); + } + + if (shouldSetConverter) + { + mainBuilder.Append(variableName).Append(".SetValueConverter("); + _annotationCodeGenerator.Create(converter!, parameters); + mainBuilder.AppendLine(");"); + } var valueComparer = property.GetValueComparer(); var typeMappingComparer = property.GetTypeMapping().Comparer; if (valueComparerType == null - && valueComparer != typeMappingComparer) + && (!parameters.ForNativeAot || valueComparer != typeMappingComparer) + && (parameters.ForNativeAot || property[CoreAnnotationNames.ValueComparer] != null)) { - mainBuilder - .Append(variableName) - .Append(".SetValueComparer("); - CreateValueComparer(valueComparer, typeMappingComparer, nameof(CoreTypeMapping.Comparer), propertyParameters); - - mainBuilder - .AppendLine(");"); + SetValueComparer(valueComparer, typeMappingComparer, nameof(CoreTypeMapping.Comparer), propertyParameters); } var keyValueComparer = property.GetKeyValueComparer(); var typeMappingKeyComparer = property.GetTypeMapping().KeyComparer; if (valueComparer != keyValueComparer - && keyValueComparer != typeMappingKeyComparer) + && (!parameters.ForNativeAot || keyValueComparer != typeMappingKeyComparer) + && (parameters.ForNativeAot || property[CoreAnnotationNames.ValueComparer] != null)) { - mainBuilder - .Append(variableName) - .Append(".SetKeyValueComparer("); - CreateValueComparer(keyValueComparer, typeMappingKeyComparer, nameof(CoreTypeMapping.KeyComparer), propertyParameters); - - mainBuilder - .AppendLine(");"); + SetValueComparer(keyValueComparer, typeMappingKeyComparer, nameof(CoreTypeMapping.KeyComparer), propertyParameters); } var providerValueComparer = property.GetProviderValueComparer(); var defaultProviderValueComparer = property.ClrType.UnwrapNullableType() - == (property.GetTypeMapping().Converter?.ProviderClrType ?? property.ClrType).UnwrapNullableType() - ? property.GetKeyValueComparer() - : property.GetTypeMapping().ProviderValueComparer; + == (property.GetTypeMapping().Converter?.ProviderClrType ?? property.ClrType).UnwrapNullableType() + ? property.GetKeyValueComparer() + : property.GetTypeMapping().ProviderValueComparer; if (providerValueComparerType == null - && providerValueComparer != defaultProviderValueComparer) - { - mainBuilder - .Append(variableName) - .Append(".SetProviderValueComparer("); - CreateValueComparer( - providerValueComparer, property.GetTypeMapping().ProviderValueComparer, nameof(CoreTypeMapping.ProviderValueComparer), propertyParameters); - - mainBuilder - .AppendLine(");"); - } - - if (property.IsKey() - || property.IsForeignKey() - || property.IsUniqueIndex()) + && (!parameters.ForNativeAot || providerValueComparer != defaultProviderValueComparer) + && (parameters.ForNativeAot || property[CoreAnnotationNames.ProviderValueComparer] != null)) { - var currentComparerType = CurrentValueComparerFactory.Instance.GetComparerType(property); - AddNamespace(currentComparerType, parameters.Namespaces); - - mainBuilder - .Append(variableName).Append(".SetCurrentValueComparer(new ") - .Append(_code.Reference(currentComparerType)) - .AppendLine($"({variableName}));"); + SetValueComparer( + providerValueComparer, property.GetTypeMapping().ProviderValueComparer, nameof(CoreTypeMapping.ProviderValueComparer), + propertyParameters); } if (sentinel != null @@ -1288,41 +1319,61 @@ private void Create( mainBuilder.AppendLine(); } - private void CreateValueComparer( + private void SetValueComparer( ValueComparer valueComparer, ValueComparer typeMappingComparer, string typeMappingComparerProperty, CSharpRuntimeAnnotationCodeGeneratorParameters parameters) { + var mainBuilder = parameters.MainBuilder; var valueComparerType = valueComparer.GetType(); if (valueComparer is IInfrastructure { Instance: ValueComparer underlyingValueComparer } && typeMappingComparer == underlyingValueComparer && valueComparerType.GetDeclaredConstructor([typeof(ValueComparer)]) != null) { - AddNamespace(valueComparerType, parameters.Namespaces); + if (!parameters.ForNativeAot + && valueComparerType.IsGenericType + && valueComparerType.GetGenericTypeDefinition() == typeof(NullableValueComparer<>)) + { + return; + } - parameters.MainBuilder - .Append("new ") - .Append(_code.Reference(valueComparerType)) - .Append("(") - .Append(parameters.TargetName) - .Append(".TypeMapping.") - .Append(typeMappingComparerProperty) - .Append(")"); - } - else - { - _annotationCodeGenerator.Create(valueComparer, parameters); + if (parameters.ForNativeAot) + { + AddNamespace(valueComparerType, parameters.Namespaces); + + mainBuilder + .Append(parameters.TargetName) + .Append(".Set").Append(typeMappingComparerProperty).Append("(") + .Append("new ").Append(_code.Reference(valueComparerType)).Append("(") + .Append(parameters.TargetName).Append(".TypeMapping.").Append(typeMappingComparerProperty) + .AppendLine("));"); + + return; + } } + + mainBuilder + .Append(parameters.TargetName) + .Append(".Set").Append(typeMappingComparerProperty).Append("("); + + _annotationCodeGenerator.Create(valueComparer, parameters); + + mainBuilder + .AppendLine(");"); } private void SetPropertyBaseProperties( - IPropertyBase property, - Dictionary? memberAccessReplacements, - CSharpRuntimeAnnotationCodeGeneratorParameters parameters, - bool createPrivateAccessors = true) + IPropertyBase property, + Dictionary? memberAccessReplacements, + CSharpRuntimeAnnotationCodeGeneratorParameters parameters) { + if (!parameters.ForNativeAot) + { + return; + } + var variableName = parameters.TargetName; var mainBuilder = parameters.MainBuilder; var unsafeAccessors = new HashSet(); @@ -1340,13 +1391,25 @@ private void mainBuilder .Append(variableName).AppendLine(".SetGetter(") .IncrementIndent() - .AppendLines(_code.Expression(getterExpression, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true) + .AppendLines( + _code.Expression( + getterExpression, parameters.Namespaces, unsafeAccessors, + (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true) .AppendLine(",") - .AppendLines(_code.Expression(hasSentinelExpression, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true) + .AppendLines( + _code.Expression( + hasSentinelExpression, parameters.Namespaces, unsafeAccessors, + (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true) .AppendLine(",") - .AppendLines(_code.Expression(structuralGetterExpression, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true) + .AppendLines( + _code.Expression( + structuralGetterExpression, parameters.Namespaces, unsafeAccessors, + (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true) .AppendLine(",") - .AppendLines(_code.Expression(hasStructuralSentinelExpression, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true) + .AppendLines( + _code.Expression( + hasStructuralSentinelExpression, parameters.Namespaces, unsafeAccessors, + (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true) .AppendLine(");") .DecrementIndent(); @@ -1355,7 +1418,10 @@ private void mainBuilder .Append(variableName).AppendLine(".SetSetter(") .IncrementIndent() - .AppendLines(_code.Expression(setterExpression, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true) + .AppendLines( + _code.Expression( + setterExpression, parameters.Namespaces, unsafeAccessors, + (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true) .AppendLine(");") .DecrementIndent(); @@ -1364,14 +1430,18 @@ private void mainBuilder .Append(variableName).AppendLine(".SetMaterializationSetter(") .IncrementIndent() - .AppendLines(_code.Expression(materializationSetterExpression, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true) + .AppendLines( + _code.Expression( + materializationSetterExpression, parameters.Namespaces, unsafeAccessors, + (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true) .AppendLine(");") .DecrementIndent(); } if (property is not IServiceProperty) { - PropertyAccessorsFactory.Instance.Create(property, + PropertyAccessorsFactory.Instance.Create( + property, out var currentValueGetter, out var preStoreGeneratedCurrentValueGetter, out var originalValueGetter, @@ -1381,24 +1451,41 @@ private void mainBuilder .Append(variableName).AppendLine(".SetAccessors(") .IncrementIndent() - .AppendLines(_code.Expression(currentValueGetter, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true) + .AppendLines( + _code.Expression( + currentValueGetter, parameters.Namespaces, unsafeAccessors, + (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true) .AppendLine(",") - .AppendLines(_code.Expression(preStoreGeneratedCurrentValueGetter, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true) + .AppendLines( + _code.Expression( + preStoreGeneratedCurrentValueGetter, parameters.Namespaces, unsafeAccessors, + (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true) .AppendLine(",") - .AppendLines(originalValueGetter == null - ? "null" - : _code.Expression(originalValueGetter, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true) + .AppendLines( + originalValueGetter == null + ? "null" + : _code.Expression( + originalValueGetter, parameters.Namespaces, unsafeAccessors, + (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), + skipFinalNewline: true) .AppendLine(",") - .AppendLines(_code.Expression(relationshipSnapshotGetter, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true) + .AppendLines( + _code.Expression( + relationshipSnapshotGetter, parameters.Namespaces, unsafeAccessors, + (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true) .AppendLine(",") - .AppendLines(valueBufferGetter == null - ? "null" - : _code.Expression(valueBufferGetter, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true) + .AppendLines( + valueBufferGetter == null + ? "null" + : _code.Expression( + valueBufferGetter, parameters.Namespaces, unsafeAccessors, + (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), + skipFinalNewline: true) .AppendLine(");") .DecrementIndent(); - Check.DebugAssert(unsafeAccessors.Count == 0, "Generated unsafe accessors not handled: " + - string.Join(Environment.NewLine, unsafeAccessors)); + Check.DebugAssert( + unsafeAccessors.Count == 0, "Generated unsafe accessors not handled: " + string.Join(Environment.NewLine, unsafeAccessors)); } var propertyIndexes = ((IRuntimePropertyBase)property).PropertyIndexes; @@ -1412,6 +1499,7 @@ private void .Append("storeGenerationIndex: ").Append(_code.Literal(propertyIndexes.StoreGenerationIndex)).AppendLine(");") .DecrementIndent(); } + private void RegisterPrivateAccessors( ITypeBase structuralType, CompiledModelCodeGenerationOptions options, @@ -1449,13 +1537,17 @@ private void RegisterPrivateAccessors( } var getter = RegisterPrivateAccessor( - property, forMaterialization: false, forSet: false, @namespace, unsafeAccessorClassNames, unsafeAccessorTypes, ref memberAccessReplacements); + property, forMaterialization: false, forSet: false, @namespace, unsafeAccessorClassNames, unsafeAccessorTypes, + ref memberAccessReplacements); var setter = RegisterPrivateAccessor( - property, forMaterialization: false, forSet: true, @namespace, unsafeAccessorClassNames, unsafeAccessorTypes, ref memberAccessReplacements); + property, forMaterialization: false, forSet: true, @namespace, unsafeAccessorClassNames, unsafeAccessorTypes, + ref memberAccessReplacements); var queryGetter = RegisterPrivateAccessor( - property, forMaterialization: true, forSet: false, @namespace, unsafeAccessorClassNames, unsafeAccessorTypes, ref memberAccessReplacements); + property, forMaterialization: true, forSet: false, @namespace, unsafeAccessorClassNames, unsafeAccessorTypes, + ref memberAccessReplacements); var querySetter = RegisterPrivateAccessor( - property, forMaterialization: true, forSet: true, @namespace, unsafeAccessorClassNames, unsafeAccessorTypes, ref memberAccessReplacements); + property, forMaterialization: true, forSet: true, @namespace, unsafeAccessorClassNames, unsafeAccessorTypes, + ref memberAccessReplacements); if (getter != null || setter != null @@ -1536,7 +1628,8 @@ private void RegisterPrivateAccessors( if (!unsafeAccessorClassNames.TryGetValue(declaringType, out var className)) { className = Uniquifier.Uniquify( - declaringType.Name[..declaringType.Name.IndexOf('`')], unsafeAccessorClassNames.Inverse, UnsafeAccessorsSuffix, int.MaxValue); + declaringType.Name[..declaringType.Name.IndexOf('`')], unsafeAccessorClassNames.Inverse, UnsafeAccessorsSuffix, + int.MaxValue); unsafeAccessorClassNames[declaringType] = className; } @@ -1604,8 +1697,9 @@ private void GeneratePrivateAccessor( if (methodInfo.GetParameters().Length > 0) { parameters.MainBuilder - .Append($", ") - .AppendJoin(methodInfo.GetParameters().Select(p => _code.Reference(p.ParameterType) + " " + _code.Identifier(p.Name!)), ", "); + .Append(", ") + .AppendJoin( + methodInfo.GetParameters().Select(p => _code.Reference(p.ParameterType) + " " + _code.Identifier(p.Name!))); } parameters.MainBuilder.AppendLine(");"); @@ -1623,7 +1717,7 @@ private void GeneratePrivateAccessor( return annotation != null ? (Type?)annotation.Value : ((Property)property).GetConversion(throwOnProviderClrTypeConflict: false, throwOnValueConverterConflict: false) - .ValueConverterType; + .ValueConverterType; } private void GeneratePropertyBaseParameters( @@ -1853,7 +1947,8 @@ private void CreateComplexProperty( Dictionary configurationClassNames, Dictionary memberAccessReplacements, string topClassName, - bool nullable) + bool nullable, + bool nativeAot) { var className = _code.Identifier(complexProperty.Name, capitalize: true); mainBuilder @@ -1913,7 +2008,8 @@ private void CreateComplexProperty( scopeVariables.Inverse, scopeVariables, configurationClassNames, - nullable); + nullable, + nativeAot); GeneratePropertyBaseParameters(complexProperty, parameters, skipType: true); @@ -2024,7 +2120,8 @@ private void CreateComplexProperty( configurationClassNames, memberAccessReplacements, topClassName, - nullable); + nullable, + nativeAot); } } @@ -2047,7 +2144,8 @@ private void CreateForeignKey( Dictionary configurationClassNames, Dictionary memberAccessReplacements, string className, - bool nullable) + bool nullable, + bool nativeAot) { const string declaringEntityType = "declaringEntityType"; const string principalEntityType = "principalEntityType"; @@ -2063,8 +2161,12 @@ private void CreateForeignKey( var scopeVariables = new BidirectionalDictionary { { foreignKey.DeclaringEntityType, declaringEntityType }, - { foreignKey.DeclaringEntityType != foreignKey.PrincipalEntityType - ? foreignKey.PrincipalEntityType : new object(), principalEntityType }, + { + foreignKey.DeclaringEntityType != foreignKey.PrincipalEntityType + ? foreignKey.PrincipalEntityType + : new object(), + principalEntityType + }, { foreignKey, foreignKeyVariable } }; @@ -2137,7 +2239,8 @@ private void CreateForeignKey( scopeVariables.Inverse, scopeVariables, configurationClassNames, - nullable); + nullable, + nativeAot); var navigation = foreignKey.DependentToPrincipal; if (navigation != null) @@ -2212,56 +2315,80 @@ private void SetNavigationBaseProperties( Dictionary memberAccessReplacements, CSharpRuntimeAnnotationCodeGeneratorParameters parameters) { - SetPropertyBaseProperties(navigation, memberAccessReplacements, parameters, createPrivateAccessors: false); + SetPropertyBaseProperties(navigation, memberAccessReplacements, parameters); if (!navigation.IsCollection) { return; } - var mainBuilder = parameters.MainBuilder; - ClrCollectionAccessorFactory.Instance.Create( - navigation, - out var entityType, - out var propertyType, - out var elementType, - out var getCollection, - out var setCollection, - out var setCollectionForMaterialization, - out var createAndSetCollection, - out var createCollection); + if (parameters.ForNativeAot) + { + var mainBuilder = parameters.MainBuilder; + ClrCollectionAccessorFactory.Instance.Create( + navigation, + out var entityType, + out var propertyType, + out var elementType, + out var getCollection, + out var setCollection, + out var setCollectionForMaterialization, + out var createAndSetCollection, + out var createCollection); - var unsafeAccessors = new HashSet(); + var unsafeAccessors = new HashSet(); - AddNamespace(propertyType, parameters.Namespaces); - mainBuilder - .Append(parameters.TargetName) - .AppendLine($".SetCollectionAccessor<{_code.Reference(entityType)}, {_code.Reference(propertyType)}, {_code.Reference(elementType)}>(") - .IncrementIndent() - .AppendLines(getCollection == null - ? "null" - : _code.Expression(getCollection, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true) - .AppendLine(",") - .AppendLines(setCollection == null - ? "null" - : _code.Expression(setCollection, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true) - .AppendLine(",") - .AppendLines(setCollectionForMaterialization == null - ? "null" - : _code.Expression(setCollectionForMaterialization, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true) - .AppendLine(",") - .AppendLines(createAndSetCollection == null - ? "null" - : _code.Expression(createAndSetCollection, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true) - .AppendLine(",") - .AppendLines(createCollection == null - ? "null" - : _code.Expression(createCollection, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true) - .AppendLine(");") - .DecrementIndent(); + AddNamespace(propertyType, parameters.Namespaces); + mainBuilder + .Append(parameters.TargetName) + .AppendLine( + $".SetCollectionAccessor<{_code.Reference(entityType)}, {_code.Reference(propertyType)}, {_code.Reference(elementType)}>(") + .IncrementIndent() + .AppendLines( + getCollection == null + ? "null" + : _code.Expression( + getCollection, parameters.Namespaces, unsafeAccessors, + (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), + skipFinalNewline: true) + .AppendLine(",") + .AppendLines( + setCollection == null + ? "null" + : _code.Expression( + setCollection, parameters.Namespaces, unsafeAccessors, + (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), + skipFinalNewline: true) + .AppendLine(",") + .AppendLines( + setCollectionForMaterialization == null + ? "null" + : _code.Expression( + setCollectionForMaterialization, parameters.Namespaces, unsafeAccessors, + (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), + skipFinalNewline: true) + .AppendLine(",") + .AppendLines( + createAndSetCollection == null + ? "null" + : _code.Expression( + createAndSetCollection, parameters.Namespaces, unsafeAccessors, + (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), + skipFinalNewline: true) + .AppendLine(",") + .AppendLines( + createCollection == null + ? "null" + : _code.Expression( + createCollection, parameters.Namespaces, unsafeAccessors, + (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), + skipFinalNewline: true) + .AppendLine(");") + .DecrementIndent(); - Check.DebugAssert(unsafeAccessors.Count == 0, "Generated unsafe accessors not handled: " + - string.Join(Environment.NewLine, unsafeAccessors)); + Check.DebugAssert( + unsafeAccessors.Count == 0, "Generated unsafe accessors not handled: " + string.Join(Environment.NewLine, unsafeAccessors)); + } } private void CreateSkipNavigation( @@ -2274,7 +2401,8 @@ private void CreateSkipNavigation( Dictionary configurationClassNames, Dictionary memberAccessReplacements, string className, - bool nullable) + bool nullable, + bool nativeAot) { const string declaringEntityType = "declaringEntityType"; const string targetEntityType = "targetEntityType"; @@ -2312,7 +2440,8 @@ private void CreateSkipNavigation( scopeVariables.Inverse, scopeVariables, configurationClassNames, - nullable); + nullable, + nativeAot); mainBuilder .Append("var ").Append(navigationVariable).Append(" = ") @@ -2423,7 +2552,8 @@ private void CreateAnnotations( SortedSet namespaces, Dictionary configurationClassNames, Dictionary memberAccessReplacements, - bool nullable) + bool nullable, + bool nativeAot) { mainBuilder.AppendLine() .Append("public static void CreateAnnotations") @@ -2437,146 +2567,187 @@ private void CreateAnnotations( var scopeVariables = new BidirectionalDictionary { { entityType, entityTypeVariable } }; var parameters = new CSharpRuntimeAnnotationCodeGeneratorParameters( - entityTypeVariable, - className, - @namespace, - mainBuilder, - methodBuilder, - namespaces, - scopeVariables.Inverse, - scopeVariables, - configurationClassNames, - nullable); - - GenerateMemberReferences(entityType, parameters); + entityTypeVariable, + className, + @namespace, + mainBuilder, + methodBuilder, + namespaces, + scopeVariables.Inverse, + scopeVariables, + configurationClassNames, + nullable, + nativeAot); - foreach (var key in entityType.GetDeclaredKeys()) + if (parameters.ForNativeAot) { - if (scopeVariables == null - || !scopeVariables.TryGetValue(key, out var keyVariableName)) - { - keyVariableName = _code.Identifier("key", key, parameters.ScopeObjects); + GenerateMemberReferences(entityType, parameters); - mainBuilder - .Append($"var {keyVariableName} = {entityTypeVariable}.{nameof(RuntimeEntityType.FindKey)}("); - FindProperties(entityTypeVariable, key.Properties, mainBuilder, nullable, parameters.ScopeVariables); - mainBuilder.AppendLine(");"); - } - - var createKeyValueFactoryMethod = nameof(KeyValueFactoryFactory.CreateCompositeFactory); - var keyType = key.GetKeyType(); - if (key.Properties.Count == 1) + foreach (var key in entityType.GetDeclaredKeys()) { - AddNamespace(keyType, parameters.Namespaces); - - if (keyType.IsNullableType()) + if (scopeVariables == null + || !scopeVariables.TryGetValue(key, out var keyVariableName)) { - var nonNullableKeyType = keyType.UnwrapNullableType(); - if (nonNullableKeyType == keyType) + keyVariableName = _code.Identifier("key", key, parameters.ScopeObjects); + + mainBuilder + .Append($"var {keyVariableName} = {entityTypeVariable}.{nameof(RuntimeEntityType.FindKey)}("); + FindProperties(entityTypeVariable, key.Properties, mainBuilder, nullable, parameters.ScopeVariables); + mainBuilder.Append(")"); + if (nullable) { - // This is just a dummy type to satisfy the generic constraint, it won't actually be used - nonNullableKeyType = typeof(int); + mainBuilder.Append("!"); } - createKeyValueFactoryMethod = - $"{nameof(KeyValueFactoryFactory.CreateSimpleNullableFactory)}<{_code.Reference(keyType)}, {_code.Reference(nonNullableKeyType)}>"; + mainBuilder.AppendLine(";"); } - else + + var createKeyValueFactoryMethod = nameof(KeyValueFactoryFactory.CreateCompositeFactory); + var keyType = key.GetKeyType(); + if (key.Properties.Count == 1) { - createKeyValueFactoryMethod = - $"{nameof(KeyValueFactoryFactory.CreateSimpleNonNullableFactory)}<{_code.Reference(keyType)}>"; + AddNamespace(keyType, parameters.Namespaces); + + if (keyType.IsNullableType()) + { + var nonNullableKeyType = keyType.UnwrapNullableType(); + if (nonNullableKeyType == keyType) + { + // This is just a dummy type to satisfy the generic constraint, it won't actually be used + nonNullableKeyType = typeof(int); + } + + createKeyValueFactoryMethod = + $"{nameof(KeyValueFactoryFactory.CreateSimpleNullableFactory)}<{_code.Reference(keyType)}, {_code.Reference(nonNullableKeyType)}>"; + } + else + { + createKeyValueFactoryMethod = + $"{nameof(KeyValueFactoryFactory.CreateSimpleNonNullableFactory)}<{_code.Reference(keyType)}>"; + } } - } - mainBuilder - .Append($"{keyVariableName}.{nameof(RuntimeKey.SetPrincipalKeyValueFactory)}(") - .AppendLine($"{_code.Reference(typeof(KeyValueFactoryFactory))}.{createKeyValueFactoryMethod}({keyVariableName}));"); + mainBuilder + .Append($"{keyVariableName}.{nameof(RuntimeKey.SetPrincipalKeyValueFactory)}(") + .AppendLine( + $"{_code.Reference(typeof(KeyValueFactoryFactory))}.{createKeyValueFactoryMethod}({keyVariableName}));"); - mainBuilder - .Append($"{keyVariableName}.{nameof(RuntimeKey.SetIdentityMapFactory)}(") - .Append($"{_code.Reference(typeof(IdentityMapFactoryFactory))}.{nameof(IdentityMapFactoryFactory.CreateFactory)}") - .AppendLine($"<{_code.Reference(keyType)}>({keyVariableName}));"); - } + mainBuilder + .Append($"{keyVariableName}.{nameof(RuntimeKey.SetIdentityMapFactory)}(") + .Append($"{_code.Reference(typeof(IdentityMapFactoryFactory))}.{nameof(IdentityMapFactoryFactory.CreateFactory)}") + .AppendLine($"<{_code.Reference(keyType)}>({keyVariableName}));"); + } - foreach (var navigation in entityType.GetNavigations()) - { - var variableName = _code.Identifier(navigation.Name, navigation, parameters.ScopeObjects, capitalize: false); + foreach (var navigation in entityType.GetNavigations()) + { + var variableName = _code.Identifier(navigation.Name, navigation, parameters.ScopeObjects, capitalize: false); - mainBuilder - .Append($"var {variableName} = ") - .AppendLine($"{parameters.TargetName}.FindNavigation({_code.Literal(navigation.Name)})!;"); - } + mainBuilder + .Append($"var {variableName} = ") + .Append($"{parameters.TargetName}.FindNavigation({_code.Literal(navigation.Name)})"); + if (nullable) + { + mainBuilder.Append("!"); + } - var runtimeType = (IRuntimeEntityType)entityType; + mainBuilder.AppendLine(";"); + } - var unsafeAccessors = new HashSet(); + var runtimeType = (IRuntimeEntityType)entityType; + var unsafeAccessors = new HashSet(); - var originalValuesFactory = OriginalValuesFactoryFactory.Instance.CreateExpression(runtimeType); - mainBuilder - .Append(parameters.TargetName).AppendLine(".SetOriginalValuesFactory(") - .IncrementIndent() - .AppendLines(_code.Expression(originalValuesFactory, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true) - .AppendLine(");") - .DecrementIndent(); + var originalValuesFactory = OriginalValuesFactoryFactory.Instance.CreateExpression(runtimeType); + mainBuilder + .Append(parameters.TargetName).AppendLine(".SetOriginalValuesFactory(") + .IncrementIndent() + .AppendLines( + _code.Expression( + originalValuesFactory, parameters.Namespaces, unsafeAccessors, + (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), + skipFinalNewline: true) + .AppendLine(");") + .DecrementIndent(); - var storeGeneratedValuesFactory = StoreGeneratedValuesFactoryFactory.Instance.CreateEmptyExpression(runtimeType); - mainBuilder - .Append(parameters.TargetName).AppendLine(".SetStoreGeneratedValuesFactory(") - .IncrementIndent() - .AppendLines(_code.Expression(storeGeneratedValuesFactory, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true) - .AppendLine(");") - .DecrementIndent(); + var storeGeneratedValuesFactory = StoreGeneratedValuesFactoryFactory.Instance.CreateEmptyExpression(runtimeType); + mainBuilder + .Append(parameters.TargetName).AppendLine(".SetStoreGeneratedValuesFactory(") + .IncrementIndent() + .AppendLines( + _code.Expression( + storeGeneratedValuesFactory, parameters.Namespaces, unsafeAccessors, + (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), + skipFinalNewline: true) + .AppendLine(");") + .DecrementIndent(); - var temporaryValuesFactory = TemporaryValuesFactoryFactory.Instance.CreateExpression(runtimeType); - mainBuilder - .Append(parameters.TargetName).AppendLine(".SetTemporaryValuesFactory(") - .IncrementIndent() - .AppendLines(_code.Expression(temporaryValuesFactory, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true) - .AppendLine(");") - .DecrementIndent(); + var temporaryValuesFactory = TemporaryValuesFactoryFactory.Instance.CreateExpression(runtimeType); + mainBuilder + .Append(parameters.TargetName).AppendLine(".SetTemporaryValuesFactory(") + .IncrementIndent() + .AppendLines( + _code.Expression( + temporaryValuesFactory, parameters.Namespaces, unsafeAccessors, + (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), + skipFinalNewline: true) + .AppendLine(");") + .DecrementIndent(); - var shadowValuesFactory = ShadowValuesFactoryFactory.Instance.CreateExpression(runtimeType); - mainBuilder - .Append(parameters.TargetName).AppendLine(".SetShadowValuesFactory(") - .IncrementIndent() - .AppendLines(_code.Expression(shadowValuesFactory, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true) - .AppendLine(");") - .DecrementIndent(); + var shadowValuesFactory = ShadowValuesFactoryFactory.Instance.CreateExpression(runtimeType); + mainBuilder + .Append(parameters.TargetName).AppendLine(".SetShadowValuesFactory(") + .IncrementIndent() + .AppendLines( + _code.Expression( + shadowValuesFactory, parameters.Namespaces, unsafeAccessors, + (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), + skipFinalNewline: true) + .AppendLine(");") + .DecrementIndent(); - var emptyShadowValuesFactory = EmptyShadowValuesFactoryFactory.Instance.CreateEmptyExpression(runtimeType); - mainBuilder - .Append(parameters.TargetName).AppendLine(".SetEmptyShadowValuesFactory(") - .IncrementIndent() - .AppendLines(_code.Expression(emptyShadowValuesFactory, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true) - .AppendLine(");") - .DecrementIndent(); + var emptyShadowValuesFactory = EmptyShadowValuesFactoryFactory.Instance.CreateEmptyExpression(runtimeType); + mainBuilder + .Append(parameters.TargetName).AppendLine(".SetEmptyShadowValuesFactory(") + .IncrementIndent() + .AppendLines( + _code.Expression( + emptyShadowValuesFactory, parameters.Namespaces, unsafeAccessors, + (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), + skipFinalNewline: true) + .AppendLine(");") + .DecrementIndent(); - var relationshipSnapshotFactory = RelationshipSnapshotFactoryFactory.Instance.CreateExpression(runtimeType); - mainBuilder - .Append(parameters.TargetName).AppendLine(".SetRelationshipSnapshotFactory(") - .IncrementIndent() - .AppendLines(_code.Expression(relationshipSnapshotFactory, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true) - .AppendLine(");") - .DecrementIndent(); + var relationshipSnapshotFactory = RelationshipSnapshotFactoryFactory.Instance.CreateExpression(runtimeType); + mainBuilder + .Append(parameters.TargetName).AppendLine(".SetRelationshipSnapshotFactory(") + .IncrementIndent() + .AppendLines( + _code.Expression( + relationshipSnapshotFactory, parameters.Namespaces, unsafeAccessors, + (IReadOnlyDictionary)parameters.ScopeVariables, memberAccessReplacements), + skipFinalNewline: true) + .AppendLine(");") + .DecrementIndent(); - AddNamespace(typeof(PropertyCounts), parameters.Namespaces); - var counts = runtimeType.Counts; - mainBuilder - .Append(parameters.TargetName).AppendLine(".Counts = new PropertyCounts(") - .IncrementIndent() - .Append("propertyCount: ").Append(_code.Literal(counts.PropertyCount)).AppendLine(",") - .Append("navigationCount: ").Append(_code.Literal(counts.NavigationCount)).AppendLine(",") - .Append("complexPropertyCount: ").Append(_code.Literal(counts.ComplexPropertyCount)).AppendLine(",") - .Append("originalValueCount: ").Append(_code.Literal(counts.OriginalValueCount)).AppendLine(",") - .Append("shadowCount: ").Append(_code.Literal(counts.ShadowCount)).AppendLine(",") - .Append("relationshipCount: ").Append(_code.Literal(counts.RelationshipCount)).AppendLine(",") - .Append("storeGeneratedCount: ").Append(_code.Literal(counts.StoreGeneratedCount)).AppendLine(");") - .DecrementIndent(); + AddNamespace(typeof(PropertyCounts), parameters.Namespaces); + var counts = runtimeType.Counts; + mainBuilder + .Append(parameters.TargetName).AppendLine(".Counts = new PropertyCounts(") + .IncrementIndent() + .Append("propertyCount: ").Append(_code.Literal(counts.PropertyCount)).AppendLine(",") + .Append("navigationCount: ").Append(_code.Literal(counts.NavigationCount)).AppendLine(",") + .Append("complexPropertyCount: ").Append(_code.Literal(counts.ComplexPropertyCount)).AppendLine(",") + .Append("originalValueCount: ").Append(_code.Literal(counts.OriginalValueCount)).AppendLine(",") + .Append("shadowCount: ").Append(_code.Literal(counts.ShadowCount)).AppendLine(",") + .Append("relationshipCount: ").Append(_code.Literal(counts.RelationshipCount)).AppendLine(",") + .Append("storeGeneratedCount: ").Append(_code.Literal(counts.StoreGeneratedCount)).AppendLine(");") + .DecrementIndent(); - CreateAnnotations(entityType, _annotationCodeGenerator.Generate, parameters); + Check.DebugAssert( + unsafeAccessors.Count == 0, + "Generated unsafe accessors not handled: " + string.Join(Environment.NewLine, unsafeAccessors)); + } - Check.DebugAssert(unsafeAccessors.Count == 0, "Generated unsafe accessors not handled: " + - string.Join(Environment.NewLine, unsafeAccessors)); + CreateAnnotations(entityType, _annotationCodeGenerator.Generate, parameters); mainBuilder .AppendLine() @@ -2599,7 +2770,13 @@ void GenerateMemberReferences( mainBuilder .Append($"var {variableName} = ") - .AppendLine($"{parameters.ScopeVariables[structuralType]}.FindProperty({_code.Literal(property.Name)})!;"); + .Append($"{parameters.ScopeVariables[structuralType]}.FindProperty({_code.Literal(property.Name)})"); + if (nullable) + { + mainBuilder.Append("!"); + } + + mainBuilder.AppendLine(";"); } foreach (var complexProperty in structuralType.GetComplexProperties()) @@ -2608,7 +2785,13 @@ void GenerateMemberReferences( mainBuilder .Append($"var {variableName} = ") - .AppendLine($"{parameters.ScopeVariables[structuralType]}.FindComplexProperty({_code.Literal(complexProperty.Name)})!;"); + .Append($"{parameters.ScopeVariables[structuralType]}.FindComplexProperty({_code.Literal(complexProperty.Name)})"); + if (nullable) + { + mainBuilder.Append("!"); + } + + mainBuilder.AppendLine(";"); var typeVariableName = _code.Identifier( complexProperty.ComplexType.ShortName(), complexProperty.ComplexType, parameters.ScopeObjects, capitalize: false); @@ -2636,8 +2819,7 @@ private static void CreateAnnotations( annotatable, parameters with { - Annotations = annotatable.GetRuntimeAnnotations().ToDictionary(a => a.Name, a => a.Value), - IsRuntime = true + Annotations = annotatable.GetRuntimeAnnotations().ToDictionary(a => a.Name, a => a.Value), IsRuntime = true }); } diff --git a/src/EFCore.Design/Scaffolding/Internal/CSharpUniqueNamer.cs b/src/EFCore.Design/Scaffolding/Internal/CSharpUniqueNamer.cs index ed328f091dd..e8b7904a64d 100644 --- a/src/EFCore.Design/Scaffolding/Internal/CSharpUniqueNamer.cs +++ b/src/EFCore.Design/Scaffolding/Internal/CSharpUniqueNamer.cs @@ -43,7 +43,7 @@ public CSharpUniqueNamer( bool caseSensitive) : base(nameGetter, cSharpUtilities, singularizePluralizer) { - _usedNames = new(caseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase); + _usedNames = new HashSet(caseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase); if (usedNames != null) { foreach (var name in usedNames) diff --git a/src/EFCore.Design/Scaffolding/Internal/CompiledModelScaffolder.cs b/src/EFCore.Design/Scaffolding/Internal/CompiledModelScaffolder.cs index aaf7d61d905..c28a848ae97 100644 --- a/src/EFCore.Design/Scaffolding/Internal/CompiledModelScaffolder.cs +++ b/src/EFCore.Design/Scaffolding/Internal/CompiledModelScaffolder.cs @@ -30,9 +30,7 @@ public class CompiledModelScaffolder : ICompiledModelScaffolder /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public CompiledModelScaffolder(ICompiledModelCodeGeneratorSelector modelCodeGeneratorSelector) - { - ModelCodeGeneratorSelector = modelCodeGeneratorSelector; - } + => ModelCodeGeneratorSelector = modelCodeGeneratorSelector; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Design/Scaffolding/Internal/ModelCodeGeneratorSelector.cs b/src/EFCore.Design/Scaffolding/Internal/ModelCodeGeneratorSelector.cs index 33cb619e2dc..69e0476b7e8 100644 --- a/src/EFCore.Design/Scaffolding/Internal/ModelCodeGeneratorSelector.cs +++ b/src/EFCore.Design/Scaffolding/Internal/ModelCodeGeneratorSelector.cs @@ -23,9 +23,7 @@ public class ModelCodeGeneratorSelector : LanguageBasedSelector public ModelCodeGeneratorSelector(IEnumerable services) : base(services.Except(services.OfType()).ToList()) - { - _templatedModelGenerators = services.OfType().ToList(); - } + => _templatedModelGenerators = services.OfType().ToList(); /// public virtual IModelCodeGenerator Select(ModelCodeGenerationOptions options) diff --git a/src/EFCore.Design/Scaffolding/Internal/ScaffoldingTypeMapper.cs b/src/EFCore.Design/Scaffolding/Internal/ScaffoldingTypeMapper.cs index 7f62b00e9c5..164780f8dd9 100644 --- a/src/EFCore.Design/Scaffolding/Internal/ScaffoldingTypeMapper.cs +++ b/src/EFCore.Design/Scaffolding/Internal/ScaffoldingTypeMapper.cs @@ -20,9 +20,7 @@ public class ScaffoldingTypeMapper : IScaffoldingTypeMapper /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public ScaffoldingTypeMapper(IRelationalTypeMappingSource typeMappingSource) - { - _typeMappingSource = typeMappingSource; - } + => _typeMappingSource = typeMappingSource; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Design/Scaffolding/Internal/TextTemplatingEngineHost.cs b/src/EFCore.Design/Scaffolding/Internal/TextTemplatingEngineHost.cs index aa014e1d281..8a78e882446 100644 --- a/src/EFCore.Design/Scaffolding/Internal/TextTemplatingEngineHost.cs +++ b/src/EFCore.Design/Scaffolding/Internal/TextTemplatingEngineHost.cs @@ -34,9 +34,7 @@ public class TextTemplatingEngineHost : ITextTemplatingSessionHost, ITextTemplat /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public TextTemplatingEngineHost(IServiceProvider? serviceProvider = null) - { - _serviceProvider = serviceProvider; - } + => _serviceProvider = serviceProvider; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Design/Scaffolding/Internal/TextTemplatingModelGenerator.cs b/src/EFCore.Design/Scaffolding/Internal/TextTemplatingModelGenerator.cs index bd42bfd9600..d6281f2f919 100644 --- a/src/EFCore.Design/Scaffolding/Internal/TextTemplatingModelGenerator.cs +++ b/src/EFCore.Design/Scaffolding/Internal/TextTemplatingModelGenerator.cs @@ -179,7 +179,7 @@ public override ScaffoldedModel GenerateModel(IModel model, ModelCodeGenerationO var entityTypeFileName = entityType.Name + entityTypeExtension; resultingFiles.AdditionalFiles.Add( - new ScaffoldedFile(entityTypeFileName, generatedCode)); + new ScaffoldedFile(entityTypeFileName, generatedCode)); } } finally diff --git a/src/EFCore.Design/Scaffolding/ModelCodeGenerator.cs b/src/EFCore.Design/Scaffolding/ModelCodeGenerator.cs index 9d1eb72129b..45cf5ae4083 100644 --- a/src/EFCore.Design/Scaffolding/ModelCodeGenerator.cs +++ b/src/EFCore.Design/Scaffolding/ModelCodeGenerator.cs @@ -16,9 +16,7 @@ public abstract class ModelCodeGenerator : IModelCodeGenerator /// /// The dependencies. protected ModelCodeGenerator(ModelCodeGeneratorDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Gets the programming language supported by this service. diff --git a/src/EFCore.InMemory/EFCore.InMemory.csproj b/src/EFCore.InMemory/EFCore.InMemory.csproj index 9da79937fa6..bf88275bc8f 100644 --- a/src/EFCore.InMemory/EFCore.InMemory.csproj +++ b/src/EFCore.InMemory/EFCore.InMemory.csproj @@ -40,7 +40,7 @@ - + diff --git a/src/EFCore.InMemory/Infrastructure/InMemoryDbContextOptionsBuilder.cs b/src/EFCore.InMemory/Infrastructure/InMemoryDbContextOptionsBuilder.cs index 0e8f71dd08d..b5b1e3d208b 100644 --- a/src/EFCore.InMemory/Infrastructure/InMemoryDbContextOptionsBuilder.cs +++ b/src/EFCore.InMemory/Infrastructure/InMemoryDbContextOptionsBuilder.cs @@ -28,9 +28,7 @@ public class InMemoryDbContextOptionsBuilder : IInMemoryDbContextOptionsBuilderI /// /// The options builder. public InMemoryDbContextOptionsBuilder(DbContextOptionsBuilder optionsBuilder) - { - OptionsBuilder = optionsBuilder; - } + => OptionsBuilder = optionsBuilder; /// /// Clones the configuration in this builder. diff --git a/src/EFCore.InMemory/Query/Internal/AnonymousObject.cs b/src/EFCore.InMemory/Query/Internal/AnonymousObject.cs index 329ea44bfad..9fa9bb9a325 100644 --- a/src/EFCore.InMemory/Query/Internal/AnonymousObject.cs +++ b/src/EFCore.InMemory/Query/Internal/AnonymousObject.cs @@ -34,9 +34,7 @@ public static readonly ConstructorInfo AnonymousObjectCtor /// [UsedImplicitly] public AnonymousObject(object[] values) - { - _values = values; - } + => _values = values; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.InMemory/Query/Internal/EntityProjectionExpression.cs b/src/EFCore.InMemory/Query/Internal/EntityProjectionExpression.cs index 36224942b99..bc0a514aa81 100644 --- a/src/EFCore.InMemory/Query/Internal/EntityProjectionExpression.cs +++ b/src/EFCore.InMemory/Query/Internal/EntityProjectionExpression.cs @@ -143,9 +143,7 @@ public virtual void AddNavigationBinding(INavigation navigation, StructuralTypeS InMemoryStrings.UnableToBindMemberToEntityProjection("navigation", navigation.Name, EntityType.DisplayName())); } - return _navigationExpressionsCache.TryGetValue(navigation, out var expression) - ? expression - : null; + return _navigationExpressionsCache.GetValueOrDefault(navigation); } /// diff --git a/src/EFCore.InMemory/Query/Internal/InMemoryQueryContext.cs b/src/EFCore.InMemory/Query/Internal/InMemoryQueryContext.cs index 9849d15cdf6..aad408a9f4c 100644 --- a/src/EFCore.InMemory/Query/Internal/InMemoryQueryContext.cs +++ b/src/EFCore.InMemory/Query/Internal/InMemoryQueryContext.cs @@ -47,9 +47,7 @@ public InMemoryQueryContext( QueryContextDependencies dependencies, IInMemoryStore store) : base(dependencies) - { - Store = store; - } + => Store = store; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.InMemory/Query/Internal/InMemoryQueryTranslationPreprocessorFactory.cs b/src/EFCore.InMemory/Query/Internal/InMemoryQueryTranslationPreprocessorFactory.cs index ae1f3c595cc..12b62bafc49 100644 --- a/src/EFCore.InMemory/Query/Internal/InMemoryQueryTranslationPreprocessorFactory.cs +++ b/src/EFCore.InMemory/Query/Internal/InMemoryQueryTranslationPreprocessorFactory.cs @@ -19,9 +19,7 @@ public class InMemoryQueryTranslationPreprocessorFactory : IQueryTranslationPrep /// public InMemoryQueryTranslationPreprocessorFactory( QueryTranslationPreprocessorDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore.InMemory/Query/Internal/InMemoryQueryableMethodTranslatingExpressionVisitorFactory.cs b/src/EFCore.InMemory/Query/Internal/InMemoryQueryableMethodTranslatingExpressionVisitorFactory.cs index 4593092b96b..17325d1bc91 100644 --- a/src/EFCore.InMemory/Query/Internal/InMemoryQueryableMethodTranslatingExpressionVisitorFactory.cs +++ b/src/EFCore.InMemory/Query/Internal/InMemoryQueryableMethodTranslatingExpressionVisitorFactory.cs @@ -19,9 +19,7 @@ public class InMemoryQueryableMethodTranslatingExpressionVisitorFactory : IQuery /// public InMemoryQueryableMethodTranslatingExpressionVisitorFactory( QueryableMethodTranslatingExpressionVisitorDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryExpressionVisitorFactory.cs b/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryExpressionVisitorFactory.cs index 95bf4f35a07..192cef1760d 100644 --- a/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryExpressionVisitorFactory.cs +++ b/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryExpressionVisitorFactory.cs @@ -19,9 +19,7 @@ public class InMemoryShapedQueryCompilingExpressionVisitorFactory : IShapedQuery /// public InMemoryShapedQueryCompilingExpressionVisitorFactory( ShapedQueryCompilingExpressionVisitorDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore.InMemory/Query/Internal/InMemoryTableExpression.cs b/src/EFCore.InMemory/Query/Internal/InMemoryTableExpression.cs index 2da22aa50ad..0b4b8cf13b6 100644 --- a/src/EFCore.InMemory/Query/Internal/InMemoryTableExpression.cs +++ b/src/EFCore.InMemory/Query/Internal/InMemoryTableExpression.cs @@ -18,9 +18,7 @@ public class InMemoryTableExpression : Expression, IPrintableExpression /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public InMemoryTableExpression(IEntityType entityType) - { - EntityType = entityType; - } + => EntityType = entityType; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.InMemory/Storage/Internal/InMemoryDatabaseCreator.cs b/src/EFCore.InMemory/Storage/Internal/InMemoryDatabaseCreator.cs index 654528b4a6c..69fc4d05515 100644 --- a/src/EFCore.InMemory/Storage/Internal/InMemoryDatabaseCreator.cs +++ b/src/EFCore.InMemory/Storage/Internal/InMemoryDatabaseCreator.cs @@ -12,6 +12,8 @@ namespace Microsoft.EntityFrameworkCore.InMemory.Storage.Internal; public class InMemoryDatabaseCreator : IDatabaseCreator { private readonly IDatabase _database; + private readonly ICurrentDbContext _currentContext; + private readonly IDbContextOptions _contextOptions; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -19,9 +21,14 @@ public class InMemoryDatabaseCreator : IDatabaseCreator /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public InMemoryDatabaseCreator(IDatabase database) + public InMemoryDatabaseCreator( + IDatabase database, + ICurrentDbContext currentContext, + IDbContextOptions contextOptions) { _database = database; + _currentContext = currentContext; + _contextOptions = contextOptions; } /// @@ -58,7 +65,25 @@ public virtual Task EnsureDeletedAsync(CancellationToken cancellationToken /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual bool EnsureCreated() - => Database.EnsureDatabaseCreated(); + { + var created = Database.EnsureDatabaseCreated(); + + var coreOptionsExtension = + _contextOptions.FindExtension() + ?? new CoreOptionsExtension(); + + var seed = coreOptionsExtension.Seeder; + if (seed != null) + { + seed(_currentContext.Context, created); + } + else if (coreOptionsExtension.AsyncSeeder != null) + { + throw new InvalidOperationException(CoreStrings.MissingSeeder); + } + + return created; + } /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -66,8 +91,26 @@ public virtual bool EnsureCreated() /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public virtual Task EnsureCreatedAsync(CancellationToken cancellationToken = default) - => Task.FromResult(Database.EnsureDatabaseCreated()); + public virtual async Task EnsureCreatedAsync(CancellationToken cancellationToken = default) + { + var created = Database.EnsureDatabaseCreated(); + + var coreOptionsExtension = + _contextOptions.FindExtension() + ?? new CoreOptionsExtension(); + + var seedAsync = coreOptionsExtension.AsyncSeeder; + if (seedAsync != null) + { + await seedAsync(_currentContext.Context, created, cancellationToken).ConfigureAwait(false); + } + else if (coreOptionsExtension.Seeder != null) + { + throw new InvalidOperationException(CoreStrings.MissingSeeder); + } + + return created; + } /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.InMemory/Storage/Internal/InMemoryStore.cs b/src/EFCore.InMemory/Storage/Internal/InMemoryStore.cs index 08ca15735f2..b05f0eb85d4 100644 --- a/src/EFCore.InMemory/Storage/Internal/InMemoryStore.cs +++ b/src/EFCore.InMemory/Storage/Internal/InMemoryStore.cs @@ -27,9 +27,7 @@ public class InMemoryStore : IInMemoryStore /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public InMemoryStore(IInMemoryTableFactory tableFactory) - { - _tableFactory = tableFactory; - } + => _tableFactory = tableFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.InMemory/Storage/Internal/InMemoryTransactionManager.cs b/src/EFCore.InMemory/Storage/Internal/InMemoryTransactionManager.cs index b09d8dd9499..d07bc94abbb 100644 --- a/src/EFCore.InMemory/Storage/Internal/InMemoryTransactionManager.cs +++ b/src/EFCore.InMemory/Storage/Internal/InMemoryTransactionManager.cs @@ -26,9 +26,7 @@ public class InMemoryTransactionManager : IDbContextTransactionManager, ITransac /// public InMemoryTransactionManager( IDiagnosticsLogger logger) - { - _logger = logger; - } + => _logger = logger; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.InMemory/ValueGeneration/Internal/InMemoryIntegerValueGenerator.cs b/src/EFCore.InMemory/ValueGeneration/Internal/InMemoryIntegerValueGenerator.cs index 46748f7270a..d5c5cbd9a0c 100644 --- a/src/EFCore.InMemory/ValueGeneration/Internal/InMemoryIntegerValueGenerator.cs +++ b/src/EFCore.InMemory/ValueGeneration/Internal/InMemoryIntegerValueGenerator.cs @@ -23,9 +23,7 @@ public class InMemoryIntegerValueGenerator : ValueGenerator, IIn /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public InMemoryIntegerValueGenerator(int propertyIndex) - { - _propertyIndex = propertyIndex; - } + => _propertyIndex = propertyIndex; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.InMemory/ValueGeneration/Internal/InMemoryValueGeneratorSelector.cs b/src/EFCore.InMemory/ValueGeneration/Internal/InMemoryValueGeneratorSelector.cs index 77483e1ba3b..75cc565b4cb 100644 --- a/src/EFCore.InMemory/ValueGeneration/Internal/InMemoryValueGeneratorSelector.cs +++ b/src/EFCore.InMemory/ValueGeneration/Internal/InMemoryValueGeneratorSelector.cs @@ -25,9 +25,7 @@ public InMemoryValueGeneratorSelector( ValueGeneratorSelectorDependencies dependencies, IInMemoryDatabase inMemoryDatabase) : base(dependencies) - { - _inMemoryStore = inMemoryDatabase.Store; - } + => _inMemoryStore = inMemoryDatabase.Store; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Proxies/EFCore.Proxies.csproj b/src/EFCore.Proxies/EFCore.Proxies.csproj index 212bda63217..2e52b366daf 100644 --- a/src/EFCore.Proxies/EFCore.Proxies.csproj +++ b/src/EFCore.Proxies/EFCore.Proxies.csproj @@ -39,11 +39,11 @@ - + - + diff --git a/src/EFCore.Proxies/LazyLoadingProxiesOptionsBuilder.cs b/src/EFCore.Proxies/LazyLoadingProxiesOptionsBuilder.cs index 4527b8e931b..4ad259e07f9 100644 --- a/src/EFCore.Proxies/LazyLoadingProxiesOptionsBuilder.cs +++ b/src/EFCore.Proxies/LazyLoadingProxiesOptionsBuilder.cs @@ -19,9 +19,7 @@ public class LazyLoadingProxiesOptionsBuilder /// /// The core options builder. public LazyLoadingProxiesOptionsBuilder(DbContextOptionsBuilder optionsBuilder) - { - OptionsBuilder = optionsBuilder; - } + => OptionsBuilder = optionsBuilder; /// /// Gets the core options builder. diff --git a/src/EFCore.Proxies/Proxies/Internal/PropertyChangeInterceptorBase.cs b/src/EFCore.Proxies/Proxies/Internal/PropertyChangeInterceptorBase.cs index 404c7c53d13..393439441f3 100644 --- a/src/EFCore.Proxies/Proxies/Internal/PropertyChangeInterceptorBase.cs +++ b/src/EFCore.Proxies/Proxies/Internal/PropertyChangeInterceptorBase.cs @@ -20,9 +20,7 @@ public abstract class PropertyChangeInterceptorBase /// doing so can result in application failures when updating to a new Entity Framework Core release. /// protected PropertyChangeInterceptorBase(IEntityType entityType) - { - EntityType = entityType; - } + => EntityType = entityType; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Proxies/Proxies/Internal/PropertyChangedInterceptor.cs b/src/EFCore.Proxies/Proxies/Internal/PropertyChangedInterceptor.cs index 2637f9e07c8..45308ec2753 100644 --- a/src/EFCore.Proxies/Proxies/Internal/PropertyChangedInterceptor.cs +++ b/src/EFCore.Proxies/Proxies/Internal/PropertyChangedInterceptor.cs @@ -31,9 +31,7 @@ public PropertyChangedInterceptor( IEntityType entityType, bool checkEquality) : base(entityType) - { - _checkEquality = checkEquality; - } + => _checkEquality = checkEquality; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Proxies/Proxies/Internal/PropertyChangingInterceptor.cs b/src/EFCore.Proxies/Proxies/Internal/PropertyChangingInterceptor.cs index ed1cfe38e51..26ba9d4b04c 100644 --- a/src/EFCore.Proxies/Proxies/Internal/PropertyChangingInterceptor.cs +++ b/src/EFCore.Proxies/Proxies/Internal/PropertyChangingInterceptor.cs @@ -31,9 +31,7 @@ public PropertyChangingInterceptor( IEntityType entityType, bool checkEquality) : base(entityType) - { - _checkEquality = checkEquality; - } + => _checkEquality = checkEquality; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Proxies/Proxies/Internal/ProxyBindingInterceptor.cs b/src/EFCore.Proxies/Proxies/Internal/ProxyBindingInterceptor.cs index ad8acaeceb4..82cbc08870d 100644 --- a/src/EFCore.Proxies/Proxies/Internal/ProxyBindingInterceptor.cs +++ b/src/EFCore.Proxies/Proxies/Internal/ProxyBindingInterceptor.cs @@ -26,9 +26,7 @@ private static readonly MethodInfo CreateProxyMethod /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public ProxyBindingInterceptor(IProxyFactory proxyFactory) - { - _proxyFactory = proxyFactory; - } + => _proxyFactory = proxyFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Proxies/Proxies/Internal/ProxyChangeTrackingConvention.cs b/src/EFCore.Proxies/Proxies/Internal/ProxyChangeTrackingConvention.cs index e7cef6fe611..7ba08c57925 100644 --- a/src/EFCore.Proxies/Proxies/Internal/ProxyChangeTrackingConvention.cs +++ b/src/EFCore.Proxies/Proxies/Internal/ProxyChangeTrackingConvention.cs @@ -23,9 +23,7 @@ public class ProxyChangeTrackingConvention : IModelInitializedConvention /// public ProxyChangeTrackingConvention( ProxiesOptionsExtension? options) - { - _options = options; - } + => _options = options; /// /// Called after a model is finalized. diff --git a/src/EFCore.Relational/Design/AnnotationCodeGenerator.cs b/src/EFCore.Relational/Design/AnnotationCodeGenerator.cs index 9f72d0b44c4..189b2ee6609 100644 --- a/src/EFCore.Relational/Design/AnnotationCodeGenerator.cs +++ b/src/EFCore.Relational/Design/AnnotationCodeGenerator.cs @@ -45,9 +45,7 @@ public class AnnotationCodeGenerator : IAnnotationCodeGenerator /// /// Parameter object containing dependencies for this service. public AnnotationCodeGenerator(AnnotationCodeGeneratorDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Relational provider-specific dependencies for this service. @@ -243,6 +241,18 @@ public virtual IReadOnlyList GenerateFluentApiCalls( #pragma warning restore CS0618 } + if (annotations.TryGetValue(RelationalAnnotationNames.ContainerColumnType, out var containerColumnTypeAnnotation) + && containerColumnTypeAnnotation is { Value: string containerColumnType } + && entityType.IsOwned()) + { + methodCallCodeFragments.Add( + new MethodCallCodeFragment( + nameof(RelationalOwnedNavigationBuilderExtensions.HasColumnType), + containerColumnType)); + + annotations.Remove(RelationalAnnotationNames.ContainerColumnType); + } + methodCallCodeFragments.AddRange(GenerateFluentApiCallsHelper(entityType, annotations, GenerateFluentApi)); return methodCallCodeFragments; diff --git a/src/EFCore.Relational/Design/AnnotationCodeGeneratorDependencies.cs b/src/EFCore.Relational/Design/AnnotationCodeGeneratorDependencies.cs index 1c07f78cfdc..d2bed64e354 100644 --- a/src/EFCore.Relational/Design/AnnotationCodeGeneratorDependencies.cs +++ b/src/EFCore.Relational/Design/AnnotationCodeGeneratorDependencies.cs @@ -39,9 +39,7 @@ public sealed record AnnotationCodeGeneratorDependencies [EntityFrameworkInternal] public AnnotationCodeGeneratorDependencies( IRelationalTypeMappingSource relationalTypeMappingSource) - { - RelationalTypeMappingSource = relationalTypeMappingSource; - } + => RelationalTypeMappingSource = relationalTypeMappingSource; /// /// The type mapper. diff --git a/src/EFCore.Relational/Design/Internal/RelationalCSharpRuntimeAnnotationCodeGenerator.cs b/src/EFCore.Relational/Design/Internal/RelationalCSharpRuntimeAnnotationCodeGenerator.cs index 6379a8b0099..485e89c3968 100644 --- a/src/EFCore.Relational/Design/Internal/RelationalCSharpRuntimeAnnotationCodeGenerator.cs +++ b/src/EFCore.Relational/Design/Internal/RelationalCSharpRuntimeAnnotationCodeGenerator.cs @@ -21,9 +21,7 @@ public RelationalCSharpRuntimeAnnotationCodeGenerator( CSharpRuntimeAnnotationCodeGeneratorDependencies dependencies, RelationalCSharpRuntimeAnnotationCodeGeneratorDependencies relationalDependencies) : base(dependencies) - { - RelationalDependencies = relationalDependencies; - } + => RelationalDependencies = relationalDependencies; /// /// Relational provider-specific dependencies for this service. @@ -40,23 +38,26 @@ public override void Generate(IModel model, CSharpRuntimeAnnotationCodeGenerator annotations.Remove(RelationalAnnotationNames.RelationalModel); annotations.Remove(RelationalAnnotationNames.RelationalModelFactory); - GenerateSimpleAnnotation(RelationalAnnotationNames.RelationalModelFactory, "() => CreateRelationalModel()", parameters); - - var methodBuilder = new IndentedStringBuilder(); - var newScope = new BidirectionalDictionary(); - Create( - model.GetRelationalModel(), parameters with - { - MainBuilder = parameters.MethodBuilder, - MethodBuilder = methodBuilder, - ScopeObjects = newScope, - ScopeVariables = newScope.Inverse - }); - - var methods = methodBuilder.ToString(); - if (!string.IsNullOrEmpty(methods)) + if (parameters.ForNativeAot) { - parameters.MethodBuilder.AppendLines(methods); + GenerateSimpleAnnotation(RelationalAnnotationNames.RelationalModelFactory, "() => CreateRelationalModel()", parameters); + + var methodBuilder = new IndentedStringBuilder(); + var newScope = new BidirectionalDictionary(); + Create( + model.GetRelationalModel(), parameters with + { + MainBuilder = parameters.MethodBuilder, + MethodBuilder = methodBuilder, + ScopeObjects = newScope, + ScopeVariables = newScope.Inverse + }); + + var methods = methodBuilder.ToString(); + if (!string.IsNullOrEmpty(methods)) + { + parameters.MethodBuilder.AppendLines(methods); + } } } else @@ -69,7 +70,8 @@ public override void Generate(IModel model, CSharpRuntimeAnnotationCodeGenerator { parameters.Namespaces.Add(typeof(Dictionary<,>).Namespace!); parameters.Namespaces.Add(typeof(BindingFlags).Namespace!); - var functionsVariable = Dependencies.CSharpHelper.Identifier("functions", functions, parameters.ScopeObjects, capitalize: false); + var functionsVariable = Dependencies.CSharpHelper.Identifier( + "functions", functions, parameters.ScopeObjects, capitalize: false); parameters.MainBuilder .Append("var ").Append(functionsVariable).AppendLine(" = new Dictionary();"); @@ -86,7 +88,8 @@ public override void Generate(IModel model, CSharpRuntimeAnnotationCodeGenerator out IReadOnlyDictionary<(string, string?), ISequence> sequences)) { parameters.Namespaces.Add(typeof(Dictionary<,>).Namespace!); - var sequencesVariable = Dependencies.CSharpHelper.Identifier("sequences", sequences, parameters.ScopeObjects, capitalize: false); + var sequencesVariable = Dependencies.CSharpHelper.Identifier( + "sequences", sequences, parameters.ScopeObjects, capitalize: false); var mainBuilder = parameters.MainBuilder; mainBuilder.Append("var ").Append(sequencesVariable).Append(" = new Dictionary<(string, string"); @@ -190,7 +193,8 @@ void CreateMappings( var defaultMappings = typeBase.GetDefaultMappings(); if (defaultMappings.Any()) { - var tableMappingsVariable = code.Identifier("defaultTableMappings", defaultMappings, parameters.ScopeObjects, capitalize: false); + var tableMappingsVariable = code.Identifier( + "defaultTableMappings", defaultMappings, parameters.ScopeObjects, capitalize: false); mainBuilder .AppendLine() .AppendLine($"var {tableMappingsVariable} = new List>();") @@ -235,7 +239,8 @@ void CreateMappings( var sqlQueryMappings = typeBase.GetSqlQueryMappings(); if (sqlQueryMappings.Any()) { - var sqlQueryMappingsVariable = code.Identifier("sqlQueryMappings", sqlQueryMappings, parameters.ScopeObjects, capitalize: false); + var sqlQueryMappingsVariable = code.Identifier( + "sqlQueryMappings", sqlQueryMappings, parameters.ScopeObjects, capitalize: false); mainBuilder .AppendLine() .AppendLine($"var {sqlQueryMappingsVariable} = new List();") @@ -250,7 +255,8 @@ void CreateMappings( var functionMappings = typeBase.GetFunctionMappings(); if (functionMappings.Any()) { - var functionMappingsVariable = code.Identifier("functionMappings", functionMappings, parameters.ScopeObjects, capitalize: false); + var functionMappingsVariable = code.Identifier( + "functionMappings", functionMappings, parameters.ScopeObjects, capitalize: false); mainBuilder .AppendLine() .AppendLine($"var {functionMappingsVariable} = new List();") @@ -258,14 +264,15 @@ void CreateMappings( .AppendLine($"{code.Literal(RelationalAnnotationNames.FunctionMappings)}, {functionMappingsVariable});"); foreach (var mapping in functionMappings) { - Create(mapping, functionMappingsVariable, parameters); + Create(mapping, functionMappingsVariable, parameters); } } var deleteStoredProcedureMappings = typeBase.GetDeleteStoredProcedureMappings(); if (deleteStoredProcedureMappings.Any()) { - var deleteSprocMappingsVariable = code.Identifier("deleteSprocMappings", deleteStoredProcedureMappings, parameters.ScopeObjects, capitalize: false); + var deleteSprocMappingsVariable = code.Identifier( + "deleteSprocMappings", deleteStoredProcedureMappings, parameters.ScopeObjects, capitalize: false); mainBuilder .AppendLine() .AppendLine($"var {deleteSprocMappingsVariable} = new List();") @@ -285,7 +292,8 @@ void CreateMappings( var insertStoredProcedureMappings = typeBase.GetInsertStoredProcedureMappings(); if (typeBase.GetInsertStoredProcedureMappings().Any()) { - var insertSprocMappingsVariable = code.Identifier("insertSprocMappings", insertStoredProcedureMappings, parameters.ScopeObjects, capitalize: false); + var insertSprocMappingsVariable = code.Identifier( + "insertSprocMappings", insertStoredProcedureMappings, parameters.ScopeObjects, capitalize: false); mainBuilder .AppendLine() .AppendLine($"var {insertSprocMappingsVariable} = new List();") @@ -305,7 +313,8 @@ void CreateMappings( var updateStoredProcedureMappings = typeBase.GetUpdateStoredProcedureMappings(); if (updateStoredProcedureMappings.Any()) { - var updateSprocMappingsVariable = code.Identifier("updateSprocMappings", updateStoredProcedureMappings, parameters.ScopeObjects, capitalize: false); + var updateSprocMappingsVariable = code.Identifier( + "updateSprocMappings", updateStoredProcedureMappings, parameters.ScopeObjects, capitalize: false); mainBuilder .AppendLine() .AppendLine($"var {updateSprocMappingsVariable} = new List();") @@ -532,7 +541,8 @@ private string GetOrCreate( foreach (var parameter in function.Parameters) { - var parameterVariable = code.Identifier(parameter.Name + "FunctionParameter", parameter, parameters.ScopeObjects, capitalize: false); + var parameterVariable = code.Identifier( + parameter.Name + "FunctionParameter", parameter, parameters.ScopeObjects, capitalize: false); mainBuilder.AppendLine($"var {parameterVariable} = {functionVariable}.FindParameter({code.Literal(parameter.Name)})!;"); CreateAnnotations( @@ -598,7 +608,8 @@ private string GetOrCreate( } var code = Dependencies.CSharpHelper; - storedProcedureVariable = code.Identifier(storeStoredProcedure.Name + "StoreSproc", storeStoredProcedure, parameters.ScopeObjects, capitalize: false); + storedProcedureVariable = code.Identifier( + storeStoredProcedure.Name + "StoreSproc", storeStoredProcedure, parameters.ScopeObjects, capitalize: false); var mainBuilder = parameters.MainBuilder; mainBuilder .Append($"var {storedProcedureVariable} = new StoreStoredProcedure(") @@ -943,6 +954,7 @@ private void Create( mainBuilder .Append($"new CompositeRowKeyValueFactory({uniqueConstraintVariable})"); } + mainBuilder.AppendLine(");"); CreateAnnotations( @@ -1009,6 +1021,7 @@ private void Create( mainBuilder .Append($"new CompositeRowIndexValueFactory({indexVariable})"); } + mainBuilder.AppendLine(");"); CreateAnnotations( @@ -1094,7 +1107,8 @@ private void Create( { if (!parameters.ScopeVariables.TryGetValue(mappedForeignKey, out var foreignKeyVariable)) { - foreignKeyVariable = code.Identifier(foreignKeyConstraintVariable + "Fk", mappedForeignKey, parameters.ScopeObjects, capitalize: false); + foreignKeyVariable = code.Identifier( + foreignKeyConstraintVariable + "Fk", mappedForeignKey, parameters.ScopeObjects, capitalize: false); mainBuilder .AppendLine($"var {foreignKeyVariable} = RelationalModel.GetForeignKey(this,").IncrementIndent() @@ -1303,7 +1317,8 @@ private void Create( var sqlQuery = sqlQueryMapping.SqlQuery; var sqlQueryVariable = GetOrCreate(sqlQuery, parameters); - var sqlQueryMappingVariable = code.Identifier(sqlQuery.Name + "SqlQueryMapping", sqlQueryMapping, parameters.ScopeObjects, capitalize: false); + var sqlQueryMappingVariable = code.Identifier( + sqlQuery.Name + "SqlQueryMapping", sqlQueryMapping, parameters.ScopeObjects, capitalize: false); GenerateAddMapping( sqlQueryMapping, @@ -1356,7 +1371,8 @@ private void Create( var storeFunction = functionMapping.StoreFunction; var functionVariable = GetOrCreate(storeFunction, parameters); var dbFunctionVariable = metadataVariables[functionMapping.DbFunction]; - var functionMappingVariable = code.Identifier(storeFunction.Name + "FunctionMapping", functionMapping, parameters.ScopeObjects, capitalize: false); + var functionMappingVariable = code.Identifier( + storeFunction.Name + "FunctionMapping", functionMapping, parameters.ScopeObjects, capitalize: false); GenerateAddMapping( functionMapping, @@ -1422,11 +1438,13 @@ private void Create( if (!metadataVariables.TryGetValue(sprocMapping.StoredProcedure, out var sprocVariable)) { var sprocSnippet = CreateFindSnippet(sprocMapping.StoredProcedure, metadataVariables); - sprocVariable = code.Identifier(storeSproc.Name + sprocMappingType[0] + "Sproc", sprocMapping.StoredProcedure, parameters.ScopeObjects, capitalize: false); + sprocVariable = code.Identifier( + storeSproc.Name + sprocMappingType[0] + "Sproc", sprocMapping.StoredProcedure, parameters.ScopeObjects, capitalize: false); mainBuilder.AppendLine($"var {sprocVariable} = {sprocSnippet};"); } - var sprocMappingVariable = code.Identifier(storeSproc.Name + "SprocMapping", sprocMapping, parameters.ScopeObjects, capitalize: false); + var sprocMappingVariable = code.Identifier( + storeSproc.Name + "SprocMapping", sprocMapping, parameters.ScopeObjects, capitalize: false); var tableMappingVariable = sprocMapping.TableMapping != null ? metadataVariables[sprocMapping.TableMapping] : null; GenerateAddMapping( @@ -1626,7 +1644,7 @@ private void Create( Create(parameter, parameters); } - if (function.TypeMapping != null) + if (function.TypeMapping != null && parameters.ForNativeAot) { mainBuilder.Append(functionVariable).Append(".TypeMapping = "); Create(function.TypeMapping, parameters with { TargetName = functionVariable }); @@ -1667,9 +1685,12 @@ private void Create(IDbFunctionParameter parameter, CSharpRuntimeAnnotationCodeG .Append(code.Literal(parameter.PropagatesNullability)).AppendLine(",") .Append(code.Literal(parameter.StoreType)).AppendLine(");").DecrementIndent(); - mainBuilder.Append(parameterVariable).Append(".TypeMapping = "); - Create(parameter.TypeMapping!, parameters with { TargetName = parameterVariable }); - mainBuilder.AppendLine(";"); + if (parameters.ForNativeAot) + { + mainBuilder.Append(parameterVariable).Append(".TypeMapping = "); + Create(parameter.TypeMapping!, parameters with { TargetName = parameterVariable }); + mainBuilder.AppendLine(";"); + } CreateAnnotations( parameter, @@ -1798,7 +1819,8 @@ public override void Generate(IEntityType entityType, CSharpRuntimeAnnotationCod { AddNamespace(typeof(StoreObjectDictionary), parameters.Namespaces); AddNamespace(typeof(StoreObjectIdentifier), parameters.Namespaces); - var fragmentsVariable = Dependencies.CSharpHelper.Identifier("fragments", fragments, parameters.ScopeObjects, capitalize: false); + var fragmentsVariable = Dependencies.CSharpHelper.Identifier( + "fragments", fragments, parameters.ScopeObjects, capitalize: false); parameters.MainBuilder .Append("var ").Append(fragmentsVariable) .AppendLine(" = new StoreObjectDictionary();"); @@ -1815,7 +1837,8 @@ public override void Generate(IEntityType entityType, CSharpRuntimeAnnotationCod RelationalAnnotationNames.InsertStoredProcedure, out StoredProcedure insertStoredProcedure)) { - var sprocVariable = Dependencies.CSharpHelper.Identifier("insertSproc", insertStoredProcedure, parameters.ScopeObjects, capitalize: false); + var sprocVariable = Dependencies.CSharpHelper.Identifier( + "insertSproc", insertStoredProcedure, parameters.ScopeObjects, capitalize: false); Create(insertStoredProcedure, sprocVariable, parameters); @@ -1827,7 +1850,8 @@ public override void Generate(IEntityType entityType, CSharpRuntimeAnnotationCod RelationalAnnotationNames.DeleteStoredProcedure, out StoredProcedure deleteStoredProcedure)) { - var sprocVariable = Dependencies.CSharpHelper.Identifier("deleteSproc", deleteStoredProcedure, parameters.ScopeObjects, capitalize: false); + var sprocVariable = Dependencies.CSharpHelper.Identifier( + "deleteSproc", deleteStoredProcedure, parameters.ScopeObjects, capitalize: false); Create(deleteStoredProcedure, sprocVariable, parameters); @@ -1839,7 +1863,8 @@ public override void Generate(IEntityType entityType, CSharpRuntimeAnnotationCod RelationalAnnotationNames.UpdateStoredProcedure, out StoredProcedure updateStoredProcedure)) { - var sprocVariable = Dependencies.CSharpHelper.Identifier("updateSproc", updateStoredProcedure, parameters.ScopeObjects, capitalize: false); + var sprocVariable = Dependencies.CSharpHelper.Identifier( + "updateSproc", updateStoredProcedure, parameters.ScopeObjects, capitalize: false); Create(updateStoredProcedure, sprocVariable, parameters); @@ -1964,7 +1989,8 @@ private void Create(IStoredProcedureParameter parameter, CSharpRuntimeAnnotation { var code = Dependencies.CSharpHelper; var mainBuilder = parameters.MainBuilder; - var parameterVariable = code.Identifier(parameter.PropertyName ?? parameter.Name, parameter, parameters.ScopeObjects, capitalize: false); + var parameterVariable = code.Identifier( + parameter.PropertyName ?? parameter.Name, parameter, parameters.ScopeObjects, capitalize: false); mainBuilder .Append("var ").Append(parameterVariable).Append(" = ") @@ -2055,7 +2081,8 @@ public override void Generate(IProperty property, CSharpRuntimeAnnotationCodeGen { AddNamespace(typeof(StoreObjectDictionary), parameters.Namespaces); AddNamespace(typeof(StoreObjectIdentifier), parameters.Namespaces); - var overridesVariable = Dependencies.CSharpHelper.Identifier("overrides", tableOverrides, parameters.ScopeObjects, capitalize: false); + var overridesVariable = Dependencies.CSharpHelper.Identifier( + "overrides", tableOverrides, parameters.ScopeObjects, capitalize: false); parameters.MainBuilder.AppendLine() .Append("var ").Append(overridesVariable) .AppendLine(" = new StoreObjectDictionary();"); diff --git a/src/EFCore.Relational/Diagnostics/CommandEndEventData.cs b/src/EFCore.Relational/Diagnostics/CommandEndEventData.cs index e28e57d0bf4..52ab9d5c36c 100644 --- a/src/EFCore.Relational/Diagnostics/CommandEndEventData.cs +++ b/src/EFCore.Relational/Diagnostics/CommandEndEventData.cs @@ -55,9 +55,7 @@ public CommandEndEventData( logParameterValues, startTime, commandSource) - { - Duration = duration; - } + => Duration = duration; /// /// The duration this event. diff --git a/src/EFCore.Relational/Diagnostics/CommandErrorEventData.cs b/src/EFCore.Relational/Diagnostics/CommandErrorEventData.cs index 09eda7aa5f5..9e9f6007b18 100644 --- a/src/EFCore.Relational/Diagnostics/CommandErrorEventData.cs +++ b/src/EFCore.Relational/Diagnostics/CommandErrorEventData.cs @@ -57,9 +57,7 @@ public CommandErrorEventData( startTime, duration, commandSource) - { - Exception = exception; - } + => Exception = exception; /// /// The exception that was thrown when execution failed. diff --git a/src/EFCore.Relational/Diagnostics/CommandExecutedEventData.cs b/src/EFCore.Relational/Diagnostics/CommandExecutedEventData.cs index 9be04d83a03..78fb02b4e5c 100644 --- a/src/EFCore.Relational/Diagnostics/CommandExecutedEventData.cs +++ b/src/EFCore.Relational/Diagnostics/CommandExecutedEventData.cs @@ -57,9 +57,7 @@ public CommandExecutedEventData( startTime, duration, commandSource) - { - Result = result; - } + => Result = result; /// /// The result of executing the command. diff --git a/src/EFCore.Relational/Diagnostics/ConnectionEndEventData.cs b/src/EFCore.Relational/Diagnostics/ConnectionEndEventData.cs index 28e59fb9e8f..12bb94caea6 100644 --- a/src/EFCore.Relational/Diagnostics/ConnectionEndEventData.cs +++ b/src/EFCore.Relational/Diagnostics/ConnectionEndEventData.cs @@ -33,9 +33,7 @@ public ConnectionEndEventData( DateTimeOffset startTime, TimeSpan duration) : base(eventDefinition, messageGenerator, connection, context, connectionId, async, startTime) - { - Duration = duration; - } + => Duration = duration; /// /// The duration this event. diff --git a/src/EFCore.Relational/Diagnostics/ConnectionErrorEventData.cs b/src/EFCore.Relational/Diagnostics/ConnectionErrorEventData.cs index ea2940ec594..af42f0a5c2d 100644 --- a/src/EFCore.Relational/Diagnostics/ConnectionErrorEventData.cs +++ b/src/EFCore.Relational/Diagnostics/ConnectionErrorEventData.cs @@ -34,9 +34,7 @@ public ConnectionErrorEventData( DateTimeOffset startTime, TimeSpan duration) : base(eventDefinition, messageGenerator, connection, context, connectionId, async, startTime, duration) - { - Exception = exception; - } + => Exception = exception; /// /// The exception that was thrown when the connection failed. diff --git a/src/EFCore.Relational/Diagnostics/DataReaderClosingEventData.cs b/src/EFCore.Relational/Diagnostics/DataReaderClosingEventData.cs index fee023e23bf..db4d6a1bec0 100644 --- a/src/EFCore.Relational/Diagnostics/DataReaderClosingEventData.cs +++ b/src/EFCore.Relational/Diagnostics/DataReaderClosingEventData.cs @@ -39,9 +39,7 @@ public DataReaderClosingEventData( DateTimeOffset startTime) : base( eventDefinition, messageGenerator, command, dataReader, context, commandId, connectionId, recordsAffected, readCount, startTime) - { - IsAsync = async; - } + => IsAsync = async; /// /// Indicates whether or not the operation is being executed asynchronously. diff --git a/src/EFCore.Relational/Diagnostics/DataReaderDisposingEventData.cs b/src/EFCore.Relational/Diagnostics/DataReaderDisposingEventData.cs index c61a67c3f95..1cf566d3b69 100644 --- a/src/EFCore.Relational/Diagnostics/DataReaderDisposingEventData.cs +++ b/src/EFCore.Relational/Diagnostics/DataReaderDisposingEventData.cs @@ -42,9 +42,7 @@ public DataReaderDisposingEventData( TimeSpan duration) : base( eventDefinition, messageGenerator, command, dataReader, context, commandId, connectionId, recordsAffected, readCount, startTime) - { - Duration = duration; - } + => Duration = duration; /// /// The duration from the time the data reader is created until it is disposed. This corresponds to the time reading diff --git a/src/EFCore.Relational/Diagnostics/MigrationAssemblyEventData.cs b/src/EFCore.Relational/Diagnostics/MigrationAssemblyEventData.cs index 8025edc237b..8b4ec39bb2e 100644 --- a/src/EFCore.Relational/Diagnostics/MigrationAssemblyEventData.cs +++ b/src/EFCore.Relational/Diagnostics/MigrationAssemblyEventData.cs @@ -25,9 +25,7 @@ public MigrationAssemblyEventData( IMigrator migrator, IMigrationsAssembly migrationsAssembly) : base(eventDefinition, messageGenerator, migrator) - { - MigrationsAssembly = migrationsAssembly; - } + => MigrationsAssembly = migrationsAssembly; /// /// The in use. diff --git a/src/EFCore.Relational/Diagnostics/MigrationColumnOperationEventData.cs b/src/EFCore.Relational/Diagnostics/MigrationColumnOperationEventData.cs index fd9fbde0d27..49ad7266901 100644 --- a/src/EFCore.Relational/Diagnostics/MigrationColumnOperationEventData.cs +++ b/src/EFCore.Relational/Diagnostics/MigrationColumnOperationEventData.cs @@ -19,9 +19,7 @@ public MigrationColumnOperationEventData( Func messageGenerator, ColumnOperation columnOperation) : base(eventDefinition, messageGenerator) - { - ColumnOperation = columnOperation; - } + => ColumnOperation = columnOperation; /// /// Gets the column operation. diff --git a/src/EFCore.Relational/Diagnostics/MigrationEventData.cs b/src/EFCore.Relational/Diagnostics/MigrationEventData.cs index f25799ae924..ffa6e4a71ed 100644 --- a/src/EFCore.Relational/Diagnostics/MigrationEventData.cs +++ b/src/EFCore.Relational/Diagnostics/MigrationEventData.cs @@ -29,9 +29,7 @@ public MigrationEventData( IMigrator migrator, Migration migration) : base(eventDefinition, messageGenerator, migrator) - { - Migration = migration; - } + => Migration = migration; /// /// The being processed. diff --git a/src/EFCore.Relational/Diagnostics/MigrationTypeEventData.cs b/src/EFCore.Relational/Diagnostics/MigrationTypeEventData.cs index 6466b0d4ca4..071e1084ea0 100644 --- a/src/EFCore.Relational/Diagnostics/MigrationTypeEventData.cs +++ b/src/EFCore.Relational/Diagnostics/MigrationTypeEventData.cs @@ -23,9 +23,7 @@ public MigrationTypeEventData( Func messageGenerator, TypeInfo migrationType) : base(eventDefinition, messageGenerator) - { - MigrationType = migrationType; - } + => MigrationType = migrationType; /// /// The migration type. diff --git a/src/EFCore.Relational/Diagnostics/MigratorEventData.cs b/src/EFCore.Relational/Diagnostics/MigratorEventData.cs index 02ca69e1906..cc0315bc28b 100644 --- a/src/EFCore.Relational/Diagnostics/MigratorEventData.cs +++ b/src/EFCore.Relational/Diagnostics/MigratorEventData.cs @@ -25,9 +25,7 @@ public MigratorEventData( Func messageGenerator, IMigrator migrator) : base(eventDefinition, messageGenerator) - { - Migrator = migrator; - } + => Migrator = migrator; /// /// The in use. diff --git a/src/EFCore.Relational/Diagnostics/MinBatchSizeEventData.cs b/src/EFCore.Relational/Diagnostics/MinBatchSizeEventData.cs index e14cb0891e6..4d10b7d816a 100644 --- a/src/EFCore.Relational/Diagnostics/MinBatchSizeEventData.cs +++ b/src/EFCore.Relational/Diagnostics/MinBatchSizeEventData.cs @@ -27,9 +27,7 @@ public MinBatchSizeEventData( int commandCount, int minBatchSize) : base(eventDefinition, messageGenerator, entries, commandCount) - { - MinBatchSize = minBatchSize; - } + => MinBatchSize = minBatchSize; /// /// The minimum batch size. diff --git a/src/EFCore.Relational/Diagnostics/RelationalEventId.cs b/src/EFCore.Relational/Diagnostics/RelationalEventId.cs index f487c54ff62..c05c73c46a3 100644 --- a/src/EFCore.Relational/Diagnostics/RelationalEventId.cs +++ b/src/EFCore.Relational/Diagnostics/RelationalEventId.cs @@ -79,6 +79,8 @@ private enum Id ColumnOrderIgnoredWarning, PendingModelChangesWarning, NonTransactionalMigrationOperationWarning, + AcquiringMigrationLock, + MigrationsUserTransactionWarning, // Query events QueryClientEvaluationWarning = CoreEventId.RelationalBaseId + 500, @@ -747,7 +749,34 @@ private static EventId MakeMigrationsId(Id id) /// This event uses the payload when used with a . /// /// - public static readonly EventId NonTransactionalMigrationOperationWarning = MakeMigrationsId(Id.NonTransactionalMigrationOperationWarning); + public static readonly EventId NonTransactionalMigrationOperationWarning = + MakeMigrationsId(Id.NonTransactionalMigrationOperationWarning); + + /// + /// A migration lock is being acquired. + /// + /// + /// + /// This event is in the category. + /// + /// + /// This event uses the payload when used with a . + /// + /// + public static readonly EventId AcquiringMigrationLock = MakeMigrationsId(Id.AcquiringMigrationLock); + + /// + /// A migration lock is being acquired. + /// + /// + /// + /// This event is in the category. + /// + /// + /// This event uses the payload when used with a . + /// + /// + public static readonly EventId MigrationsUserTransactionWarning = MakeMigrationsId(Id.MigrationsUserTransactionWarning); private static readonly string _queryPrefix = DbLoggerCategory.Query.Name + "."; diff --git a/src/EFCore.Relational/Diagnostics/RelationalLoggerExtensions.cs b/src/EFCore.Relational/Diagnostics/RelationalLoggerExtensions.cs index d704bcf1f1b..177b7e90bba 100644 --- a/src/EFCore.Relational/Diagnostics/RelationalLoggerExtensions.cs +++ b/src/EFCore.Relational/Diagnostics/RelationalLoggerExtensions.cs @@ -2365,6 +2365,7 @@ public static void NonTransactionalMigrationOperationWarning( { commandText = commandText.Substring(0, 100) + "..."; } + definition.Log(diagnostics, commandText, migration.GetType().ShortDisplayName()); } @@ -2390,9 +2391,70 @@ private static string NonTransactionalMigrationOperationWarning(EventDefinitionB { commandText = commandText.Substring(0, 100) + "..."; } + return d.GenerateMessage(commandText, p.Migration.GetType().ShortDisplayName()); } + /// + /// Logs for the event. + /// + /// The diagnostics logger to use. + public static void AcquiringMigrationLock( + this IDiagnosticsLogger diagnostics) + { + var definition = RelationalResources.LogAcquiringMigrationLock(diagnostics); + + if (diagnostics.ShouldLog(definition)) + { + definition.Log(diagnostics); + } + + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) + { + var eventData = new EventData( + definition, + AcquiringMigrationLock); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); + } + } + + private static string AcquiringMigrationLock(EventDefinitionBase definition, EventData payload) + { + var d = (EventDefinition)definition; + return d.GenerateMessage(); + } + + /// + /// Logs for the event. + /// + /// The diagnostics logger to use. + public static void MigrationsUserTransactionWarning( + this IDiagnosticsLogger diagnostics) + { + var definition = RelationalResources.LogMigrationsUserTransaction(diagnostics); + + if (diagnostics.ShouldLog(definition)) + { + definition.Log(diagnostics); + } + + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) + { + var eventData = new EventData( + definition, + MigrationsUserTransactionWarning); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); + } + } + + private static string MigrationsUserTransactionWarning(EventDefinitionBase definition, EventData payload) + { + var d = (EventDefinition)definition; + return d.GenerateMessage(); + } + /// /// Logs for the event. /// diff --git a/src/EFCore.Relational/Diagnostics/RelationalLoggingDefinitions.cs b/src/EFCore.Relational/Diagnostics/RelationalLoggingDefinitions.cs index 51e0e3b1aee..762172c8944 100644 --- a/src/EFCore.Relational/Diagnostics/RelationalLoggingDefinitions.cs +++ b/src/EFCore.Relational/Diagnostics/RelationalLoggingDefinitions.cs @@ -358,6 +358,24 @@ public abstract class RelationalLoggingDefinitions : LoggingDefinitions [EntityFrameworkInternal] public EventDefinitionBase? LogNoMigrationsFound; + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + [EntityFrameworkInternal] + public EventDefinitionBase? LogAcquiringMigrationLock; + + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + [EntityFrameworkInternal] + public EventDefinitionBase? LogMigrationsUserTransactionWarning; + /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in diff --git a/src/EFCore.Relational/Diagnostics/SequenceEventData.cs b/src/EFCore.Relational/Diagnostics/SequenceEventData.cs index b1b4a02bf96..8d7f263813c 100644 --- a/src/EFCore.Relational/Diagnostics/SequenceEventData.cs +++ b/src/EFCore.Relational/Diagnostics/SequenceEventData.cs @@ -23,9 +23,7 @@ public SequenceEventData( Func messageGenerator, IReadOnlySequence sequence) : base(eventDefinition, messageGenerator) - { - Sequence = sequence; - } + => Sequence = sequence; /// /// The sequence. diff --git a/src/EFCore.Relational/Diagnostics/TransactionEndEventData.cs b/src/EFCore.Relational/Diagnostics/TransactionEndEventData.cs index 8e60c400b52..9e2f3e5c4dc 100644 --- a/src/EFCore.Relational/Diagnostics/TransactionEndEventData.cs +++ b/src/EFCore.Relational/Diagnostics/TransactionEndEventData.cs @@ -35,9 +35,7 @@ public TransactionEndEventData( DateTimeOffset startTime, TimeSpan duration) : base(eventDefinition, messageGenerator, transaction, context, transactionId, connectionId, async, startTime) - { - Duration = duration; - } + => Duration = duration; /// /// The duration of this event. diff --git a/src/EFCore.Relational/EFCore.Relational.csproj b/src/EFCore.Relational/EFCore.Relational.csproj index bac04d23a8f..2f0010093e7 100644 --- a/src/EFCore.Relational/EFCore.Relational.csproj +++ b/src/EFCore.Relational/EFCore.Relational.csproj @@ -45,12 +45,12 @@ - + - + diff --git a/src/EFCore.Relational/Extensions/Internal/RelationalModelExtensions.cs b/src/EFCore.Relational/Extensions/Internal/RelationalModelExtensions.cs index 1c8d7ac540f..c43995b0023 100644 --- a/src/EFCore.Relational/Extensions/Internal/RelationalModelExtensions.cs +++ b/src/EFCore.Relational/Extensions/Internal/RelationalModelExtensions.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.Internal; /// @@ -18,5 +19,6 @@ public static class RelationalModelExtensions /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public static void EnsureRelationalModel(this IModel model) => model.GetRelationalModel(); + public static void EnsureRelationalModel(this IModel model) + => model.GetRelationalModel(); } diff --git a/src/EFCore.Relational/Extensions/RelationalDatabaseFacadeExtensions.cs b/src/EFCore.Relational/Extensions/RelationalDatabaseFacadeExtensions.cs index e355e7a7c23..5d8e3bd558f 100644 --- a/src/EFCore.Relational/Extensions/RelationalDatabaseFacadeExtensions.cs +++ b/src/EFCore.Relational/Extensions/RelationalDatabaseFacadeExtensions.cs @@ -123,13 +123,6 @@ public static void Migrate(this DatabaseFacade databaseFacade) /// /// The target migration to migrate the database to, or to migrate to the latest. /// - /// - /// The optional seed method to run after migrating the database. It will be invoked even if no migrations were applied. - /// - /// - /// The maximum amount of time that the migration lock should be held. Unless a catastrophic failure occurs, the - /// lock is released when the migration operation completes. - /// /// /// /// Note that this API is mutually exclusive with . EnsureCreated does not use migrations @@ -145,10 +138,8 @@ public static void Migrate(this DatabaseFacade databaseFacade) + " Use a migration bundle or an alternate way of executing migration operations.")] public static void Migrate( this DatabaseFacade databaseFacade, - Action? seed, - string? targetMigration = null, - TimeSpan? lockTimeout = null) - => databaseFacade.GetRelationalService().Migrate(seed, targetMigration, lockTimeout); + string? targetMigration) + => databaseFacade.GetRelationalService().Migrate(targetMigration); /// /// Asynchronously applies any pending migrations for the context to the database. Will create the database @@ -184,13 +175,6 @@ public static Task MigrateAsync( /// /// The target migration to migrate the database to, or to migrate to the latest. /// - /// - /// The optional seed method to run after migrating the database. It will be invoked even if no migrations were applied. - /// - /// - /// The maximum amount of time that the migration lock should be held. Unless a catastrophic failure occurs, the - /// lock is released when the migration operation completes. - /// /// A to observe while waiting for the task to complete. /// /// @@ -209,11 +193,9 @@ public static Task MigrateAsync( + " Use a migration bundle or an alternate way of executing migration operations.")] public static Task MigrateAsync( this DatabaseFacade databaseFacade, - Func? seed, - string? targetMigration = null, - TimeSpan? lockTimeout = null, + string? targetMigration, CancellationToken cancellationToken = default) - => databaseFacade.GetRelationalService().MigrateAsync(seed, targetMigration, lockTimeout, cancellationToken); + => databaseFacade.GetRelationalService().MigrateAsync(targetMigration, cancellationToken); /// /// Executes the given SQL against the database and returns the number of rows affected. diff --git a/src/EFCore.Relational/Extensions/RelationalEntityTypeExtensions.cs b/src/EFCore.Relational/Extensions/RelationalEntityTypeExtensions.cs index ff816843742..8cee65a5187 100644 --- a/src/EFCore.Relational/Extensions/RelationalEntityTypeExtensions.cs +++ b/src/EFCore.Relational/Extensions/RelationalEntityTypeExtensions.cs @@ -1606,9 +1606,50 @@ 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 is string columnName - ? columnName - : (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. + /// + /// The entity type. + /// The database column type. + public static void SetContainerColumnType(this IMutableEntityType entityType, string? columnType) + => entityType.SetOrRemoveAnnotation(RelationalAnnotationNames.ContainerColumnType, columnType); + + /// + /// Sets the column type to use for the container column to which the entity type is mapped. + /// + /// The entity type. + /// The database column type. + /// Indicates whether the configuration was specified using a data annotation. + /// The configured value. + public static string? SetContainerColumnType( + this IConventionEntityType entityType, + string? columnType, + bool fromDataAnnotation = false) + => (string?)entityType.SetAnnotation(RelationalAnnotationNames.ContainerColumnType, columnType, fromDataAnnotation)?.Value; + + /// + /// Gets the for the container column type. + /// + /// The entity type. + /// The . + public static ConfigurationSource? GetContainerColumnTypeConfigurationSource(this IConventionEntityType entityType) + => entityType.FindAnnotation(RelationalAnnotationNames.ContainerColumnType) + ?.GetConfigurationSource(); + + /// + /// Gets the column type to use for the container column to which the entity type is mapped. + /// + /// The entity type. + /// The database column type. + public static string? GetContainerColumnType(this IReadOnlyEntityType entityType) + => entityType.FindAnnotation(RelationalAnnotationNames.ContainerColumnType)?.Value as string; /// /// Sets the type mapping for the container column to which the entity type is mapped. @@ -1683,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/Extensions/RelationalForeignKeyExtensions.cs b/src/EFCore.Relational/Extensions/RelationalForeignKeyExtensions.cs index f4dec1f5808..f184bc57728 100644 --- a/src/EFCore.Relational/Extensions/RelationalForeignKeyExtensions.cs +++ b/src/EFCore.Relational/Extensions/RelationalForeignKeyExtensions.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Text; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata.Internal; @@ -139,8 +138,8 @@ public static IEnumerable GetMappedConstraints(this IFore { foreignKey.DeclaringEntityType.Model.EnsureRelationalModel(); return (IEnumerable?)foreignKey.FindRuntimeAnnotationValue( - RelationalAnnotationNames.ForeignKeyMappings) - ?? Enumerable.Empty(); + RelationalAnnotationNames.ForeignKeyMappings) + ?? Enumerable.Empty(); } /// diff --git a/src/EFCore.Relational/Extensions/RelationalIndexExtensions.cs b/src/EFCore.Relational/Extensions/RelationalIndexExtensions.cs index e7e318635d3..3ffcceb1ed4 100644 --- a/src/EFCore.Relational/Extensions/RelationalIndexExtensions.cs +++ b/src/EFCore.Relational/Extensions/RelationalIndexExtensions.cs @@ -3,7 +3,6 @@ using System.Text; using Microsoft.EntityFrameworkCore.Internal; -using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Internal; // ReSharper disable once CheckNamespace @@ -170,8 +169,8 @@ public static IEnumerable GetMappedTableIndexes(this IIndex index) { index.DeclaringEntityType.Model.EnsureRelationalModel(); return (IEnumerable?)index.FindRuntimeAnnotationValue( - RelationalAnnotationNames.TableIndexMappings) - ?? Enumerable.Empty(); + RelationalAnnotationNames.TableIndexMappings) + ?? Enumerable.Empty(); } /// diff --git a/src/EFCore.Relational/Extensions/RelationalKeyExtensions.cs b/src/EFCore.Relational/Extensions/RelationalKeyExtensions.cs index 406dfa63553..74a44e2738b 100644 --- a/src/EFCore.Relational/Extensions/RelationalKeyExtensions.cs +++ b/src/EFCore.Relational/Extensions/RelationalKeyExtensions.cs @@ -3,7 +3,6 @@ using System.Text; using Microsoft.EntityFrameworkCore.Internal; -using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Internal; // ReSharper disable once CheckNamespace @@ -111,8 +110,8 @@ public static IEnumerable GetMappedConstraints(this IKey key) { key.DeclaringEntityType.Model.EnsureRelationalModel(); return (IEnumerable?)key.FindRuntimeAnnotationValue( - RelationalAnnotationNames.UniqueConstraintMappings) - ?? Enumerable.Empty(); + RelationalAnnotationNames.UniqueConstraintMappings) + ?? Enumerable.Empty(); } /// diff --git a/src/EFCore.Relational/Extensions/RelationalModelExtensions.cs b/src/EFCore.Relational/Extensions/RelationalModelExtensions.cs index 0e106901ddb..d36f9b026d7 100644 --- a/src/EFCore.Relational/Extensions/RelationalModelExtensions.cs +++ b/src/EFCore.Relational/Extensions/RelationalModelExtensions.cs @@ -70,7 +70,7 @@ public static IRelationalModel GetRelationalModel(this IModel model) if (relationalModel == null) { var relationalModelFactory = (Func?)model.FindRuntimeAnnotationValue( - RelationalAnnotationNames.RelationalModelFactory) + RelationalAnnotationNames.RelationalModelFactory) ?? throw new InvalidOperationException(CoreStrings.ModelNotFinalized(nameof(GetRelationalModel))); lock (relationalModelFactory) { diff --git a/src/EFCore.Relational/Extensions/RelationalOwnedNavigationBuilderExtensions.cs b/src/EFCore.Relational/Extensions/RelationalOwnedNavigationBuilderExtensions.cs index 0f0329748a5..e40b561e023 100644 --- a/src/EFCore.Relational/Extensions/RelationalOwnedNavigationBuilderExtensions.cs +++ b/src/EFCore.Relational/Extensions/RelationalOwnedNavigationBuilderExtensions.cs @@ -23,12 +23,7 @@ public static class RelationalOwnedNavigationBuilderExtensions /// The builder for the owned navigation being configured. /// The same builder instance so that multiple calls can be chained. public static OwnedNavigationBuilder ToJson(this OwnedNavigationBuilder builder) - { - var navigationName = builder.Metadata.GetNavigation(pointsToPrincipal: false)!.Name; - builder.ToJson(navigationName); - - return builder; - } + => builder.ToJson(builder.Metadata.GetNavigation(pointsToPrincipal: false)!.Name); /// /// Configures a relationship where this entity type and the entities that it owns are mapped to a JSON column in the database. @@ -45,12 +40,7 @@ public static OwnedNavigationBuilder ToJson builder) where TOwnerEntity : class where TDependentEntity : class - { - var navigationName = builder.Metadata.GetNavigation(pointsToPrincipal: false)!.Name; - builder.ToJson(navigationName); - - return builder; - } + => (OwnedNavigationBuilder)((OwnedNavigationBuilder)builder).ToJson(); /// /// Configures a relationship where this entity type and the entities that it owns are mapped to a JSON column in the database. @@ -68,11 +58,7 @@ public static OwnedNavigationBuilder ToJson (OwnedNavigationBuilder)((OwnedNavigationBuilder)builder).ToJson(jsonColumnName); /// /// Configures a relationship where this entity type and the entities that it owns are mapped to a JSON column in the database. @@ -94,6 +80,40 @@ public static OwnedNavigationBuilder ToJson( return builder; } + /// + /// Set the relational database column type to be used to store the document represented by this owned entity. + /// + /// + /// This method should only be specified for the outer-most owned entity in the given ownership structure and + /// only when mapping the column to a database document type. + /// + /// The builder for the owned navigation being configured. + /// The database type for the column, or to use the database default. + /// The same builder instance so that multiple calls can be chained. + public static OwnedNavigationBuilder HasColumnType( + this OwnedNavigationBuilder builder, + string? columnType) + where TOwnerEntity : class + where TDependentEntity : class + => (OwnedNavigationBuilder)((OwnedNavigationBuilder)builder).HasColumnType(columnType); + + /// + /// Set the relational database column type to be used to store the document represented by this owned entity. + /// + /// + /// This method should only be specified for the outer-most owned entity in the given ownership structure and + /// only when mapping the column to a database document type. + /// + /// The builder for the owned navigation being configured. + /// The database type for the column, or to use the database default. + /// The same builder instance so that multiple calls can be chained. + public static OwnedNavigationBuilder HasColumnType(this OwnedNavigationBuilder builder, string? columnType) + { + builder.OwnedEntityType.SetContainerColumnType(columnType); + + return builder; + } + /// /// Configures the navigation of an entity mapped to a JSON column, mapping the navigation to a specific JSON property, /// rather than using the navigation name. diff --git a/src/EFCore.Relational/Extensions/RelationalPropertyExtensions.cs b/src/EFCore.Relational/Extensions/RelationalPropertyExtensions.cs index db1bbdd1f89..ac188c89e0a 100644 --- a/src/EFCore.Relational/Extensions/RelationalPropertyExtensions.cs +++ b/src/EFCore.Relational/Extensions/RelationalPropertyExtensions.cs @@ -521,8 +521,8 @@ public static IEnumerable GetDefaultColumnMappings(this IPro { property.DeclaringType.Model.EnsureRelationalModel(); return (IEnumerable?)property.FindRuntimeAnnotationValue( - RelationalAnnotationNames.DefaultColumnMappings) - ?? Enumerable.Empty(); + RelationalAnnotationNames.DefaultColumnMappings) + ?? Enumerable.Empty(); } /// @@ -534,8 +534,8 @@ public static IEnumerable GetTableColumnMappings(this IProperty { property.DeclaringType.Model.EnsureRelationalModel(); return (IEnumerable?)property.FindRuntimeAnnotationValue( - RelationalAnnotationNames.TableColumnMappings) - ?? Enumerable.Empty(); + RelationalAnnotationNames.TableColumnMappings) + ?? Enumerable.Empty(); } /// @@ -547,8 +547,8 @@ public static IEnumerable GetViewColumnMappings(this IProper { property.DeclaringType.Model.EnsureRelationalModel(); return (IEnumerable?)property.FindRuntimeAnnotationValue( - RelationalAnnotationNames.ViewColumnMappings) - ?? Enumerable.Empty(); + RelationalAnnotationNames.ViewColumnMappings) + ?? Enumerable.Empty(); } /// @@ -560,8 +560,8 @@ public static IEnumerable GetSqlQueryColumnMappings(this { property.DeclaringType.Model.EnsureRelationalModel(); return (IEnumerable?)property.FindRuntimeAnnotationValue( - RelationalAnnotationNames.SqlQueryColumnMappings) - ?? Enumerable.Empty(); + RelationalAnnotationNames.SqlQueryColumnMappings) + ?? Enumerable.Empty(); } /// @@ -573,8 +573,8 @@ public static IEnumerable GetFunctionColumnMappings(this { property.DeclaringType.Model.EnsureRelationalModel(); return (IEnumerable?)property.FindRuntimeAnnotationValue( - RelationalAnnotationNames.FunctionColumnMappings) - ?? Enumerable.Empty(); + RelationalAnnotationNames.FunctionColumnMappings) + ?? Enumerable.Empty(); } /// @@ -586,8 +586,8 @@ public static IEnumerable GetInsertStoredPr { property.DeclaringType.Model.EnsureRelationalModel(); return (IEnumerable?)property.FindRuntimeAnnotationValue( - RelationalAnnotationNames.InsertStoredProcedureResultColumnMappings) - ?? Enumerable.Empty(); + RelationalAnnotationNames.InsertStoredProcedureResultColumnMappings) + ?? Enumerable.Empty(); } /// @@ -599,8 +599,8 @@ public static IEnumerable GetInsertStoredProce { property.DeclaringType.Model.EnsureRelationalModel(); return (IEnumerable?)property.FindRuntimeAnnotationValue( - RelationalAnnotationNames.InsertStoredProcedureParameterMappings) - ?? Enumerable.Empty(); + RelationalAnnotationNames.InsertStoredProcedureParameterMappings) + ?? Enumerable.Empty(); } /// @@ -612,8 +612,8 @@ public static IEnumerable GetDeleteStoredProce { property.DeclaringType.Model.EnsureRelationalModel(); return (IEnumerable?)property.FindRuntimeAnnotationValue( - RelationalAnnotationNames.DeleteStoredProcedureParameterMappings) - ?? Enumerable.Empty(); + RelationalAnnotationNames.DeleteStoredProcedureParameterMappings) + ?? Enumerable.Empty(); } /// @@ -625,8 +625,8 @@ public static IEnumerable GetUpdateStoredPr { property.DeclaringType.Model.EnsureRelationalModel(); return (IEnumerable?)property.FindRuntimeAnnotationValue( - RelationalAnnotationNames.UpdateStoredProcedureResultColumnMappings) - ?? Enumerable.Empty(); + RelationalAnnotationNames.UpdateStoredProcedureResultColumnMappings) + ?? Enumerable.Empty(); } /// @@ -638,8 +638,8 @@ public static IEnumerable GetUpdateStoredProce { property.DeclaringType.Model.EnsureRelationalModel(); return (IEnumerable?)property.FindRuntimeAnnotationValue( - RelationalAnnotationNames.UpdateStoredProcedureParameterMappings) - ?? Enumerable.Empty(); + RelationalAnnotationNames.UpdateStoredProcedureParameterMappings) + ?? Enumerable.Empty(); } /// diff --git a/src/EFCore.Relational/Extensions/RelationalTypeBaseExtensions.cs b/src/EFCore.Relational/Extensions/RelationalTypeBaseExtensions.cs index 08e551a6ebc..930af7d1a75 100644 --- a/src/EFCore.Relational/Extensions/RelationalTypeBaseExtensions.cs +++ b/src/EFCore.Relational/Extensions/RelationalTypeBaseExtensions.cs @@ -43,8 +43,8 @@ public static IEnumerable GetDefaultMappings(this ITypeBase t { typeBase.Model.EnsureRelationalModel(); return (IEnumerable?)typeBase.FindRuntimeAnnotationValue( - RelationalAnnotationNames.DefaultMappings) - ?? Enumerable.Empty(); + RelationalAnnotationNames.DefaultMappings) + ?? Enumerable.Empty(); } /// @@ -56,8 +56,8 @@ public static IEnumerable GetTableMappings(this ITypeBase typeBas { typeBase.Model.EnsureRelationalModel(); return (IEnumerable?)typeBase.FindRuntimeAnnotationValue( - RelationalAnnotationNames.TableMappings) - ?? Enumerable.Empty(); + RelationalAnnotationNames.TableMappings) + ?? Enumerable.Empty(); } #endregion Table mapping @@ -89,8 +89,8 @@ public static IEnumerable GetViewMappings(this ITypeBase typeBase) { typeBase.Model.EnsureRelationalModel(); return (IEnumerable?)typeBase.FindRuntimeAnnotationValue( - RelationalAnnotationNames.ViewMappings) - ?? Enumerable.Empty(); + RelationalAnnotationNames.ViewMappings) + ?? Enumerable.Empty(); } #endregion View mapping @@ -114,8 +114,8 @@ public static IEnumerable GetSqlQueryMappings(this ITypeBase t { typeBase.Model.EnsureRelationalModel(); return (IEnumerable?)typeBase.FindRuntimeAnnotationValue( - RelationalAnnotationNames.SqlQueryMappings) - ?? Enumerable.Empty(); + RelationalAnnotationNames.SqlQueryMappings) + ?? Enumerable.Empty(); } #endregion SQL query mapping @@ -139,8 +139,8 @@ public static IEnumerable GetFunctionMappings(this ITypeBase t { typeBase.Model.EnsureRelationalModel(); return (IEnumerable?)typeBase.FindRuntimeAnnotationValue( - RelationalAnnotationNames.FunctionMappings) - ?? Enumerable.Empty(); + RelationalAnnotationNames.FunctionMappings) + ?? Enumerable.Empty(); } #endregion @@ -209,7 +209,9 @@ public static IEnumerable GetFunctionMappings(this ITypeBase t public static IEnumerable GetInsertStoredProcedureMappings(this ITypeBase typeBase) { typeBase.Model.EnsureRelationalModel(); - return (IEnumerable?)typeBase.FindRuntimeAnnotationValue(RelationalAnnotationNames.InsertStoredProcedureMappings) ?? Enumerable.Empty(); + return (IEnumerable?)typeBase.FindRuntimeAnnotationValue( + RelationalAnnotationNames.InsertStoredProcedureMappings) + ?? Enumerable.Empty(); } /// @@ -220,7 +222,9 @@ public static IEnumerable GetInsertStoredProcedureMappi public static IEnumerable GetDeleteStoredProcedureMappings(this ITypeBase typeBase) { typeBase.Model.EnsureRelationalModel(); - return (IEnumerable?)typeBase.FindRuntimeAnnotationValue(RelationalAnnotationNames.DeleteStoredProcedureMappings) ?? Enumerable.Empty(); + return (IEnumerable?)typeBase.FindRuntimeAnnotationValue( + RelationalAnnotationNames.DeleteStoredProcedureMappings) + ?? Enumerable.Empty(); } /// @@ -231,7 +235,9 @@ public static IEnumerable GetDeleteStoredProcedureMappi public static IEnumerable GetUpdateStoredProcedureMappings(this ITypeBase typeBase) { typeBase.Model.EnsureRelationalModel(); - return (IEnumerable?)typeBase.FindRuntimeAnnotationValue(RelationalAnnotationNames.UpdateStoredProcedureMappings) ?? Enumerable.Empty(); + return (IEnumerable?)typeBase.FindRuntimeAnnotationValue( + RelationalAnnotationNames.UpdateStoredProcedureMappings) + ?? Enumerable.Empty(); } #endregion @@ -368,6 +374,16 @@ public static bool IsMappedToJson(this IReadOnlyTypeBase typeBase) ? entityType.GetContainerColumnName() : ((IReadOnlyComplexType)typeBase).GetContainerColumnName(); + /// + /// Gets the column type to use for the container column to which the type is mapped. + /// + /// The type. + /// The database column type. + public static string? GetContainerColumnType(this IReadOnlyTypeBase typeBase) + => typeBase is IReadOnlyEntityType entityType + ? entityType.GetContainerColumnType() + : null; + /// /// Gets the value of JSON property name used for the given entity mapped to a JSON column. /// diff --git a/src/EFCore.Relational/Infrastructure/EntityFrameworkRelationalServicesBuilder.cs b/src/EFCore.Relational/Infrastructure/EntityFrameworkRelationalServicesBuilder.cs index 2a526d3dfc2..d0ee126a44c 100644 --- a/src/EFCore.Relational/Infrastructure/EntityFrameworkRelationalServicesBuilder.cs +++ b/src/EFCore.Relational/Infrastructure/EntityFrameworkRelationalServicesBuilder.cs @@ -96,8 +96,7 @@ public static readonly IDictionary RelationalServi typeof(IAggregateMethodCallTranslatorPlugin), new ServiceCharacteristics(ServiceLifetime.Scoped, multipleRegistrations: true) }, - { typeof(IMemberTranslatorPlugin), new ServiceCharacteristics(ServiceLifetime.Scoped, multipleRegistrations: true) }, - { typeof(IMigratorPlugin), new ServiceCharacteristics(ServiceLifetime.Singleton, multipleRegistrations: true) } + { typeof(IMemberTranslatorPlugin), new ServiceCharacteristics(ServiceLifetime.Scoped, multipleRegistrations: true) } }; /// diff --git a/src/EFCore.Relational/Infrastructure/RelationalDbContextOptionsBuilder.cs b/src/EFCore.Relational/Infrastructure/RelationalDbContextOptionsBuilder.cs index ee0e59414f7..6f8bd323463 100644 --- a/src/EFCore.Relational/Infrastructure/RelationalDbContextOptionsBuilder.cs +++ b/src/EFCore.Relational/Infrastructure/RelationalDbContextOptionsBuilder.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.ComponentModel; +using Microsoft.EntityFrameworkCore.Internal; namespace Microsoft.EntityFrameworkCore.Infrastructure; @@ -26,9 +27,7 @@ public abstract class RelationalDbContextOptionsBuilder : /// /// The core options builder. protected RelationalDbContextOptionsBuilder(DbContextOptionsBuilder optionsBuilder) - { - OptionsBuilder = optionsBuilder; - } + => OptionsBuilder = optionsBuilder; /// /// Gets the core options builder. @@ -102,7 +101,7 @@ public virtual TBuilder MigrationsAssembly(string? assemblyName) /// /// See Database migrations for more information and examples. /// - /// The where the migrations are located. + /// The where the migrations are located. /// The same builder instance so that multiple calls can be chained. public virtual TBuilder MigrationsAssembly(Assembly assembly) => WithOption(e => (TExtension)e.WithMigrationsAssembly(assembly)); @@ -159,6 +158,54 @@ public virtual TBuilder ExecutionStrategy( => WithOption( e => (TExtension)e.WithExecutionStrategyFactory(Check.NotNull(getExecutionStrategy, nameof(getExecutionStrategy)))); + /// + /// Configures the context to translate parameterized collections to inline constants. + /// + /// + /// + /// When a LINQ query contains a parameterized collection, by default EF Core parameterizes the entire collection as a single + /// SQL parameter, if possible. For example, on SQL Server, the LINQ query Where(b => ids.Contains(b.Id) is translated to + /// WHERE [b].[Id] IN (SELECT [i].[value] FROM OPENJSON(@__ids_0) ...). While this helps with query plan caching, it can + /// produce worse query plans for certain query types. + /// + /// + /// instructs EF to translate the collection to a set of constants: + /// WHERE [b].[Id] IN (1, 2, 3). This can produce better query plans for certain query types, but can also lead to query + /// plan bloat. + /// + /// + /// Note that it's possible to cause EF to translate a specific collection in a specific query to constants by wrapping the + /// parameterized collection in : Where(b => EF.Constant(ids).Contains(b.Id). This overrides + /// the default. + /// + /// + public virtual TBuilder TranslateParameterizedCollectionsToConstants() + => WithOption(e => (TExtension)e.WithParameterizedCollectionTranslationMode(ParameterizedCollectionTranslationMode.Constantize)); + + /// + /// Configures the context to translate parameterized collections to inline constants. + /// + /// + /// + /// When a LINQ query contains a parameterized collection, by default EF Core parameterizes the entire collection as a single + /// SQL parameter, if possible. For example, on SQL Server, the LINQ query Where(b => ids.Contains(b.Id) is translated to + /// WHERE [b].[Id] IN (SELECT [i].[value] FROM OPENJSON(@__ids_0) ...). While this helps with query plan caching, it can + /// produce worse query plans for certain query types. + /// + /// + /// instructs EF to translate the collection to a set of constants: + /// WHERE [b].[Id] IN (1, 2, 3). This can produce better query plans for certain query types, but can also lead to query + /// plan bloat. + /// + /// + /// Note that it's possible to cause EF to translate a specific collection in a specific query to constants by wrapping the + /// parameterized collection in : Where(b => EF.Constant(ids).Contains(b.Id). This overrides + /// the default. + /// + /// + public virtual TBuilder TranslateParameterizedCollectionsToParameters() + => WithOption(e => (TExtension)e.WithParameterizedCollectionTranslationMode(ParameterizedCollectionTranslationMode.Parameterize)); + /// /// Sets an option by cloning the extension used to store the settings. This ensures the builder /// does not modify options that are already in use elsewhere. diff --git a/src/EFCore.Relational/Infrastructure/RelationalModelRuntimeInitializer.cs b/src/EFCore.Relational/Infrastructure/RelationalModelRuntimeInitializer.cs index c60b4d3fa9a..26f333099b0 100644 --- a/src/EFCore.Relational/Infrastructure/RelationalModelRuntimeInitializer.cs +++ b/src/EFCore.Relational/Infrastructure/RelationalModelRuntimeInitializer.cs @@ -36,9 +36,7 @@ public RelationalModelRuntimeInitializer( ModelRuntimeInitializerDependencies dependencies, RelationalModelRuntimeInitializerDependencies relationalDependencies) : base(dependencies) - { - RelationalDependencies = relationalDependencies; - } + => RelationalDependencies = relationalDependencies; /// /// Relational provider-specific dependencies for this service. @@ -61,11 +59,12 @@ protected override void InitializeModel(IModel model, bool designTime, bool prev model.SetRuntimeAnnotation(RelationalAnnotationNames.ModelDependencies, RelationalDependencies.RelationalModelDependencies); } else if (model.FindRuntimeAnnotation(RelationalAnnotationNames.RelationalModel) == null - && model.FindRuntimeAnnotation(RelationalAnnotationNames.RelationalModelFactory) == null) + && model.FindRuntimeAnnotation(RelationalAnnotationNames.RelationalModelFactory) == null) { var annotationProvider = RelationalDependencies.RelationalAnnotationProvider; var typeMappingSource = (IRelationalTypeMappingSource)Dependencies.ModelDependencies.TypeMappingSource; - model.SetRuntimeAnnotation(RelationalAnnotationNames.RelationalModelFactory, + model.SetRuntimeAnnotation( + RelationalAnnotationNames.RelationalModelFactory, () => RelationalModel.Create( model, annotationProvider, diff --git a/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs b/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs index 4c5f8b5db56..69ed1618137 100644 --- a/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs +++ b/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs @@ -32,9 +32,7 @@ public RelationalModelValidator( ModelValidatorDependencies dependencies, RelationalModelValidatorDependencies relationalDependencies) : base(dependencies) - { - RelationalDependencies = relationalDependencies; - } + => RelationalDependencies = relationalDependencies; /// /// Relational provider-specific dependencies for this service. @@ -2017,9 +2015,10 @@ private static void ValidateNonTphMapping(IEntityType rootEntityType, StoreObjec var unmappedOwnedType = entityType.GetReferencingForeignKeys() .Where(fk => fk.IsOwnership) .Select(fk => fk.DeclaringEntityType) - .FirstOrDefault(owned => StoreObjectIdentifier.Create(owned, storeObjectType) == null - && ((IConventionEntityType)owned).GetStoreObjectConfigurationSource(storeObjectType) == null - && !owned.IsMappedToJson()); + .FirstOrDefault( + owned => StoreObjectIdentifier.Create(owned, storeObjectType) == null + && ((IConventionEntityType)owned).GetStoreObjectConfigurationSource(storeObjectType) == null + && !owned.IsMappedToJson()); if (unmappedOwnedType != null && entityType.GetDerivedTypes().Any(derived => StoreObjectIdentifier.Create(derived, storeObjectType) != null)) { @@ -2521,8 +2520,7 @@ protected virtual void ValidateIndexProperties( } } - - /// + /// protected override void ValidateData(IModel model, IDiagnosticsLogger logger) { foreach (var entityType in model.GetEntityTypes()) @@ -2532,11 +2530,13 @@ protected override void ValidateData(IModel model, IDiagnosticsLogger x.ForeignKey.IsOwnership && x.TargetEntityType.IsMappedToJson())) + foreach (var navigation in entityType.GetNavigations() + .Where(x => x.ForeignKey.IsOwnership && x.TargetEntityType.IsMappedToJson())) { if (entityType.GetSeedData().Any(x => x.TryGetValue(navigation.Name, out var _))) { - throw new InvalidOperationException(RelationalStrings.HasDataNotSupportedForEntitiesMappedToJson(entityType.DisplayName())); + throw new InvalidOperationException( + RelationalStrings.HasDataNotSupportedForEntitiesMappedToJson(entityType.DisplayName())); } } } @@ -2592,6 +2592,23 @@ protected virtual void ValidateJsonEntities( IModel model, IDiagnosticsLogger logger) { + foreach (var entityType in model.GetEntityTypes()) + { + if (entityType[RelationalAnnotationNames.ContainerColumnType] != null) + { + if (entityType.FindOwnership()?.PrincipalEntityType.IsOwned() == true) + { + throw new InvalidOperationException(RelationalStrings.ContainerTypeOnNestedOwnedEntityType(entityType.DisplayName())); + } + + if (!entityType.IsOwned() + || entityType.GetContainerColumnName() == null) + { + throw new InvalidOperationException(RelationalStrings.ContainerTypeOnNonContainer(entityType.DisplayName())); + } + } + } + var tables = BuildSharedTableEntityMap(model.GetEntityTypes()); foreach (var (table, mappedTypes) in tables) { @@ -2771,23 +2788,24 @@ protected virtual void ValidateJsonEntityKey( { if (primaryKeyProperty.GetJsonPropertyName() != null) { - // issue #28594 + // Issue #28594 throw new InvalidOperationException( RelationalStrings.JsonEntityWithExplicitlyConfiguredJsonPropertyNameOnKey( primaryKeyProperty.Name, jsonEntityType.DisplayName())); } - } - if (!ownership.IsUnique) - { - // for collection entities, make sure that ordinal key is not explicitly defined - var ordinalKeyProperty = primaryKeyProperties.Last(); - if (!ordinalKeyProperty.IsOrdinalKeyProperty()) + if (!ownership.IsUnique) { - // issue #28594 - throw new InvalidOperationException( - RelationalStrings.JsonEntityWithExplicitlyConfiguredOrdinalKey( - jsonEntityType.DisplayName())); + // For collection entities, no key properties other than the generated ones are allowed because they + // will not be persisted. + if (!primaryKeyProperty.IsOrdinalKeyProperty() + && !primaryKeyProperty.IsForeignKey()) + { + // issue #28594 + throw new InvalidOperationException( + RelationalStrings.JsonEntityWithExplicitlyConfiguredKey( + jsonEntityType.DisplayName(), primaryKeyProperty.Name)); + } } } @@ -2815,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( @@ -2839,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/Infrastructure/RelationalModelValidatorDependencies.cs b/src/EFCore.Relational/Infrastructure/RelationalModelValidatorDependencies.cs index a388cdb7c16..785c584acfd 100644 --- a/src/EFCore.Relational/Infrastructure/RelationalModelValidatorDependencies.cs +++ b/src/EFCore.Relational/Infrastructure/RelationalModelValidatorDependencies.cs @@ -47,9 +47,7 @@ public sealed record RelationalModelValidatorDependencies [EntityFrameworkInternal] public RelationalModelValidatorDependencies( IRelationalTypeMappingSource typeMappingSource) - { - TypeMappingSource = typeMappingSource; - } + => TypeMappingSource = typeMappingSource; /// /// The type mapper. diff --git a/src/EFCore.Relational/Infrastructure/RelationalOptionsExtension.cs b/src/EFCore.Relational/Infrastructure/RelationalOptionsExtension.cs index f8adafd96d9..ce2742e46a6 100644 --- a/src/EFCore.Relational/Infrastructure/RelationalOptionsExtension.cs +++ b/src/EFCore.Relational/Infrastructure/RelationalOptionsExtension.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Text; +using Microsoft.EntityFrameworkCore.Internal; namespace Microsoft.EntityFrameworkCore.Infrastructure; @@ -33,10 +34,10 @@ public abstract class RelationalOptionsExtension : IDbContextOptionsExtension private QuerySplittingBehavior? _querySplittingBehavior; private string? _migrationsAssembly; private Assembly? _migrationsAssemblyObject; - private string? _migrationsHistoryTableName; private string? _migrationsHistoryTableSchema; private Func? _executionStrategyFactory; + private ParameterizedCollectionTranslationMode? _parameterizedCollectionTranslationMode; /// /// Creates a new set of options with everything set to default values. @@ -63,6 +64,7 @@ protected RelationalOptionsExtension(RelationalOptionsExtension copyFrom) _migrationsHistoryTableName = copyFrom._migrationsHistoryTableName; _migrationsHistoryTableSchema = copyFrom._migrationsHistoryTableSchema; _executionStrategyFactory = copyFrom._executionStrategyFactory; + _parameterizedCollectionTranslationMode = copyFrom._parameterizedCollectionTranslationMode; } /// @@ -381,6 +383,27 @@ public virtual RelationalOptionsExtension WithExecutionStrategyFactory( return clone; } + /// + /// Configured translation mode for parameterized collections. + /// + public virtual ParameterizedCollectionTranslationMode? ParameterizedCollectionTranslationMode + => _parameterizedCollectionTranslationMode; + + /// + /// Creates a new instance with all options the same as for this instance, but with the given option changed. + /// It is unusual to call this method directly. Instead use . + /// + /// The option to change. + public virtual RelationalOptionsExtension WithParameterizedCollectionTranslationMode( + ParameterizedCollectionTranslationMode parameterizedCollectionTranslationMode) + { + var clone = Clone(); + + clone._parameterizedCollectionTranslationMode = parameterizedCollectionTranslationMode; + + return clone; + } + /// /// Finds an existing registered on the given options /// or throws if none has been registered. This is typically used to find some relational @@ -540,6 +563,12 @@ public override string LogFragment builder.Append(Extension._migrationsHistoryTableName ?? HistoryRepository.DefaultTableName).Append(' '); } + if (Extension._parameterizedCollectionTranslationMode != null) + { + builder.Append("ParameterizedCollectionTranslationMode=").Append(Extension._parameterizedCollectionTranslationMode) + .Append(' '); + } + _logFragment = builder.ToString(); } diff --git a/src/EFCore.Relational/Internal/ParameterizedCollectionTranslationMode.cs b/src/EFCore.Relational/Internal/ParameterizedCollectionTranslationMode.cs new file mode 100644 index 00000000000..cfb59de6f08 --- /dev/null +++ b/src/EFCore.Relational/Internal/ParameterizedCollectionTranslationMode.cs @@ -0,0 +1,29 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.Internal; + +/// +/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to +/// the same compatibility standards as public APIs. It may be changed or removed without notice in +/// any release. You should only use it directly in your code with extreme caution and knowing that +/// doing so can result in application failures when updating to a new Entity Framework Core release. +/// +public enum ParameterizedCollectionTranslationMode +{ + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + Constantize = 0, + + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + Parameterize, +} diff --git a/src/EFCore.Relational/Internal/SemanticVersionComparer.cs b/src/EFCore.Relational/Internal/SemanticVersionComparer.cs index f1f61e298c9..2f92a0fdd60 100644 --- a/src/EFCore.Relational/Internal/SemanticVersionComparer.cs +++ b/src/EFCore.Relational/Internal/SemanticVersionComparer.cs @@ -1,9 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Collections.Generic; - namespace Microsoft.EntityFrameworkCore.Internal; /// diff --git a/src/EFCore.Relational/Metadata/Builders/CheckConstraintBuilder.cs b/src/EFCore.Relational/Metadata/Builders/CheckConstraintBuilder.cs index fd9c2fccebc..62ef2431ff0 100644 --- a/src/EFCore.Relational/Metadata/Builders/CheckConstraintBuilder.cs +++ b/src/EFCore.Relational/Metadata/Builders/CheckConstraintBuilder.cs @@ -22,9 +22,7 @@ public class CheckConstraintBuilder : IInfrastructure [EntityFrameworkInternal] public CheckConstraintBuilder(IMutableCheckConstraint checkConstraint) - { - Builder = ((CheckConstraint)checkConstraint).Builder; - } + => Builder = ((CheckConstraint)checkConstraint).Builder; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Relational/Metadata/Builders/DbFunctionBuilderBase.cs b/src/EFCore.Relational/Metadata/Builders/DbFunctionBuilderBase.cs index ffaa6126514..6d947a239a4 100644 --- a/src/EFCore.Relational/Metadata/Builders/DbFunctionBuilderBase.cs +++ b/src/EFCore.Relational/Metadata/Builders/DbFunctionBuilderBase.cs @@ -22,9 +22,7 @@ public abstract class DbFunctionBuilderBase : IInfrastructure [EntityFrameworkInternal] protected DbFunctionBuilderBase(IMutableDbFunction function) - { - Builder = ((DbFunction)function).Builder; - } + => Builder = ((DbFunction)function).Builder; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Relational/Metadata/Builders/DbFunctionParameterBuilder.cs b/src/EFCore.Relational/Metadata/Builders/DbFunctionParameterBuilder.cs index cbe2eb2e24a..6383dedf8ac 100644 --- a/src/EFCore.Relational/Metadata/Builders/DbFunctionParameterBuilder.cs +++ b/src/EFCore.Relational/Metadata/Builders/DbFunctionParameterBuilder.cs @@ -23,9 +23,7 @@ public class DbFunctionParameterBuilder : IInfrastructure [EntityFrameworkInternal] public DbFunctionParameterBuilder(IMutableDbFunctionParameter parameter) - { - Builder = ((DbFunctionParameter)parameter).Builder; - } + => Builder = ((DbFunctionParameter)parameter).Builder; private InternalDbFunctionParameterBuilder Builder { [DebuggerStepThrough] get; } diff --git a/src/EFCore.Relational/Metadata/Builders/OwnedNavigationTableValuedFunctionBuilder.cs b/src/EFCore.Relational/Metadata/Builders/OwnedNavigationTableValuedFunctionBuilder.cs index d4b1d1ca368..6f31fbca6e5 100644 --- a/src/EFCore.Relational/Metadata/Builders/OwnedNavigationTableValuedFunctionBuilder.cs +++ b/src/EFCore.Relational/Metadata/Builders/OwnedNavigationTableValuedFunctionBuilder.cs @@ -19,9 +19,7 @@ public OwnedNavigationTableValuedFunctionBuilder( IMutableDbFunction function, OwnedNavigationBuilder ownedNavigationBuilder) : base(function) - { - OwnedNavigationBuilder = ownedNavigationBuilder; - } + => OwnedNavigationBuilder = ownedNavigationBuilder; private OwnedNavigationBuilder OwnedNavigationBuilder { get; } diff --git a/src/EFCore.Relational/Metadata/Builders/SequenceBuilder.cs b/src/EFCore.Relational/Metadata/Builders/SequenceBuilder.cs index 2a0d2e0646c..7fc797f03c3 100644 --- a/src/EFCore.Relational/Metadata/Builders/SequenceBuilder.cs +++ b/src/EFCore.Relational/Metadata/Builders/SequenceBuilder.cs @@ -19,9 +19,7 @@ public class SequenceBuilder : IInfrastructure /// /// The to configure. public SequenceBuilder(IMutableSequence sequence) - { - Builder = ((Sequence)sequence).Builder; - } + => Builder = ((Sequence)sequence).Builder; private InternalSequenceBuilder Builder { [DebuggerStepThrough] get; } diff --git a/src/EFCore.Relational/Metadata/Builders/TableValuedFunctionBuilder.cs b/src/EFCore.Relational/Metadata/Builders/TableValuedFunctionBuilder.cs index 6f7533d4e18..f5f9cc3d4f6 100644 --- a/src/EFCore.Relational/Metadata/Builders/TableValuedFunctionBuilder.cs +++ b/src/EFCore.Relational/Metadata/Builders/TableValuedFunctionBuilder.cs @@ -17,9 +17,7 @@ public class TableValuedFunctionBuilder : DbFunctionBuilderBase, IInfrastructure [EntityFrameworkInternal] public TableValuedFunctionBuilder(IMutableDbFunction function, EntityTypeBuilder entityTypeBuilder) : base(function) - { - EntityTypeBuilder = entityTypeBuilder; - } + => EntityTypeBuilder = entityTypeBuilder; private EntityTypeBuilder EntityTypeBuilder { get; } diff --git a/src/EFCore.Relational/Metadata/Conventions/Infrastructure/RelationalConventionSetBuilder.cs b/src/EFCore.Relational/Metadata/Conventions/Infrastructure/RelationalConventionSetBuilder.cs index a25f84861ec..b8e49bb22c2 100644 --- a/src/EFCore.Relational/Metadata/Conventions/Infrastructure/RelationalConventionSetBuilder.cs +++ b/src/EFCore.Relational/Metadata/Conventions/Infrastructure/RelationalConventionSetBuilder.cs @@ -41,9 +41,7 @@ protected RelationalConventionSetBuilder( ProviderConventionSetBuilderDependencies dependencies, RelationalConventionSetBuilderDependencies relationalDependencies) : base(dependencies) - { - RelationalDependencies = relationalDependencies; - } + => RelationalDependencies = relationalDependencies; /// /// Relational provider-specific dependencies for this service. @@ -81,9 +79,15 @@ public override ConventionSet CreateConventionSet() conventionSet.Replace( new RelationalValueGenerationConvention(Dependencies, RelationalDependencies)); + + conventionSet.Replace( + new RelationalKeyDiscoveryConvention(Dependencies, RelationalDependencies)); + conventionSet.Replace( new RelationalQueryFilterRewritingConvention(Dependencies, RelationalDependencies)); - conventionSet.Replace(new RelationalRuntimeModelConvention(Dependencies, RelationalDependencies)); + + conventionSet.Replace( + new RelationalRuntimeModelConvention(Dependencies, RelationalDependencies)); return conventionSet; } diff --git a/src/EFCore.Relational/Metadata/Conventions/RelationalColumnAttributeConvention.cs b/src/EFCore.Relational/Metadata/Conventions/RelationalColumnAttributeConvention.cs index 8669ae16b76..186a701cd2b 100644 --- a/src/EFCore.Relational/Metadata/Conventions/RelationalColumnAttributeConvention.cs +++ b/src/EFCore.Relational/Metadata/Conventions/RelationalColumnAttributeConvention.cs @@ -22,9 +22,7 @@ public RelationalColumnAttributeConvention( ProviderConventionSetBuilderDependencies dependencies, RelationalConventionSetBuilderDependencies relationalDependencies) : base(dependencies) - { - RelationalDependencies = relationalDependencies; - } + => RelationalDependencies = relationalDependencies; /// /// Relational provider-specific dependencies for this service. diff --git a/src/EFCore.Relational/Metadata/Conventions/RelationalColumnCommentAttributeConvention.cs b/src/EFCore.Relational/Metadata/Conventions/RelationalColumnCommentAttributeConvention.cs index 4b4277cdc19..e24c122e8f6 100644 --- a/src/EFCore.Relational/Metadata/Conventions/RelationalColumnCommentAttributeConvention.cs +++ b/src/EFCore.Relational/Metadata/Conventions/RelationalColumnCommentAttributeConvention.cs @@ -20,9 +20,7 @@ public RelationalColumnCommentAttributeConvention( ProviderConventionSetBuilderDependencies dependencies, RelationalConventionSetBuilderDependencies relationalDependencies) : base(dependencies) - { - RelationalDependencies = relationalDependencies; - } + => RelationalDependencies = relationalDependencies; /// /// Relational provider-specific dependencies for this service. diff --git a/src/EFCore.Relational/Metadata/Conventions/RelationalKeyDiscoveryConvention.cs b/src/EFCore.Relational/Metadata/Conventions/RelationalKeyDiscoveryConvention.cs new file mode 100644 index 00000000000..1d2a1e2d96c --- /dev/null +++ b/src/EFCore.Relational/Metadata/Conventions/RelationalKeyDiscoveryConvention.cs @@ -0,0 +1,158 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions; + +/// +/// A relational-specific convention inheriting from . +/// +/// +/// +/// See Model building conventions for more information and examples. +/// +/// +public class RelationalKeyDiscoveryConvention : KeyDiscoveryConvention, IEntityTypeAnnotationChangedConvention +{ + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + [EntityFrameworkInternal] + public const string SynthesizedOrdinalPropertyName = "__synthesizedOrdinal"; + + /// + /// Creates a new instance of . + /// + /// Parameter object containing dependencies for this convention. + /// Parameter object containing relational dependencies for this convention. + public RelationalKeyDiscoveryConvention( + ProviderConventionSetBuilderDependencies dependencies, + RelationalConventionSetBuilderDependencies relationalDependencies) + : base(dependencies) + { + RelationalDependencies = relationalDependencies; + } + + /// + /// Relational provider-specific dependencies for this service. + /// + protected virtual RelationalConventionSetBuilderDependencies RelationalDependencies { get; } + + /// + protected override List? DiscoverKeyProperties(IConventionEntityType entityType) + { + var ownership = entityType.FindOwnership(); + if (ownership?.DeclaringEntityType != entityType) + { + ownership = null; + } + + // Don't discover key properties for owned collection types mapped to JSON so that we can persist properties + // called `Id` without attempting to persist key values. + if (ownership?.IsUnique == false + && entityType.GetContainerColumnName() is not null) + { + return []; + } + + return base.DiscoverKeyProperties(entityType); + } + + /// + protected override void ProcessKeyProperties( + IList keyProperties, + IConventionEntityType entityType) + { + var isMappedToJson = entityType.GetContainerColumnName() is not null; + var synthesizedProperty = keyProperties.FirstOrDefault(p => p.Name == SynthesizedOrdinalPropertyName); + var ownershipForeignKey = entityType.FindOwnership(); + if (ownershipForeignKey?.IsUnique == false + && isMappedToJson) + { + // This is an owned collection, so it has a composite key consisting of FK properties pointing to the owner PK, + // any additional key properties defined by the application, and then the synthesized property. + // Add these in the correct order--this is somewhat inefficient, but we are limited because we have to manipulate the + // existing collection. + var existingKeyProperties = keyProperties.ToList(); + keyProperties.Clear(); + + // Add the FK properties to form the first part of the composite key. + foreach (var conventionProperty in ownershipForeignKey.Properties) + { + keyProperties.Add(conventionProperty); + } + + // Generate the synthesized key property if it doesn't exist. + if (synthesizedProperty == null) + { + var builder = entityType.Builder.CreateUniqueProperty(typeof(int), SynthesizedOrdinalPropertyName, required: true); + builder = builder?.ValueGenerated(ValueGenerated.OnAdd) ?? builder; + synthesizedProperty = builder!.Metadata; + } + + // Add non-duplicate, non-ownership, non-synthesized properties. + foreach (var keyProperty in existingKeyProperties) + { + if (keyProperty != synthesizedProperty + && !keyProperties.Contains(keyProperty)) + { + keyProperties.Add(keyProperty); + } + } + + // Finally, the synthesized property always goes at the end. + keyProperties.Add(synthesizedProperty); + } + else + { + // Not an owned collection or not mapped to JSON. + if (synthesizedProperty is not null) + { + // This was an owned collection, but now is not, so remove the synthesized property. + keyProperties.Remove(synthesizedProperty); + } + + base.ProcessKeyProperties(keyProperties, entityType); + } + } + + /// + public override void ProcessPropertyAdded( + IConventionPropertyBuilder propertyBuilder, + IConventionContext context) + { + if (propertyBuilder.Metadata.Name != SynthesizedOrdinalPropertyName) + { + base.ProcessPropertyAdded(propertyBuilder, context); + } + } + + /// + public virtual void ProcessEntityTypeAnnotationChanged( + IConventionEntityTypeBuilder entityTypeBuilder, + string name, + IConventionAnnotation? annotation, + IConventionAnnotation? oldAnnotation, + IConventionContext context) + { + if (name == RelationalAnnotationNames.ContainerColumnName) + { + Configure(this, entityTypeBuilder); + } + + static void Configure(RelationalKeyDiscoveryConvention me, IConventionEntityTypeBuilder builder) + { + me.TryConfigurePrimaryKey(builder); + + foreach (var ownershipFk in builder.Metadata.GetReferencingForeignKeys()) + { + if (ownershipFk.IsOwnership) + { + Configure(me, ownershipFk.DeclaringEntityType.Builder); + } + } + } + } +} diff --git a/src/EFCore.Relational/Metadata/Conventions/RelationalNavigationJsonPropertyNameAttributeConvention.cs b/src/EFCore.Relational/Metadata/Conventions/RelationalNavigationJsonPropertyNameAttributeConvention.cs index 17f55836472..71de2ea23fe 100644 --- a/src/EFCore.Relational/Metadata/Conventions/RelationalNavigationJsonPropertyNameAttributeConvention.cs +++ b/src/EFCore.Relational/Metadata/Conventions/RelationalNavigationJsonPropertyNameAttributeConvention.cs @@ -25,9 +25,7 @@ public RelationalNavigationJsonPropertyNameAttributeConvention( ProviderConventionSetBuilderDependencies dependencies, RelationalConventionSetBuilderDependencies relationalDependencies) : base(dependencies) - { - RelationalDependencies = relationalDependencies; - } + => RelationalDependencies = relationalDependencies; /// /// Relational provider-specific dependencies for this service. diff --git a/src/EFCore.Relational/Metadata/Conventions/RelationalPropertyJsonPropertyNameAttributeConvention.cs b/src/EFCore.Relational/Metadata/Conventions/RelationalPropertyJsonPropertyNameAttributeConvention.cs index 33f2b1ab240..3c5150113bb 100644 --- a/src/EFCore.Relational/Metadata/Conventions/RelationalPropertyJsonPropertyNameAttributeConvention.cs +++ b/src/EFCore.Relational/Metadata/Conventions/RelationalPropertyJsonPropertyNameAttributeConvention.cs @@ -22,9 +22,7 @@ public RelationalPropertyJsonPropertyNameAttributeConvention( ProviderConventionSetBuilderDependencies dependencies, RelationalConventionSetBuilderDependencies relationalDependencies) : base(dependencies) - { - RelationalDependencies = relationalDependencies; - } + => RelationalDependencies = relationalDependencies; /// /// Relational provider-specific dependencies for this service. diff --git a/src/EFCore.Relational/Metadata/Conventions/RelationalRuntimeModelConvention.cs b/src/EFCore.Relational/Metadata/Conventions/RelationalRuntimeModelConvention.cs index e61eb9cf64f..20aeb33cd38 100644 --- a/src/EFCore.Relational/Metadata/Conventions/RelationalRuntimeModelConvention.cs +++ b/src/EFCore.Relational/Metadata/Conventions/RelationalRuntimeModelConvention.cs @@ -23,9 +23,7 @@ public RelationalRuntimeModelConvention( ProviderConventionSetBuilderDependencies dependencies, RelationalConventionSetBuilderDependencies relationalDependencies) : base(dependencies) - { - RelationalDependencies = relationalDependencies; - } + => RelationalDependencies = relationalDependencies; /// /// Relational provider-specific dependencies for this service. diff --git a/src/EFCore.Relational/Metadata/Conventions/RelationalTableAttributeConvention.cs b/src/EFCore.Relational/Metadata/Conventions/RelationalTableAttributeConvention.cs index 3226db5a8dd..6dd75c621ad 100644 --- a/src/EFCore.Relational/Metadata/Conventions/RelationalTableAttributeConvention.cs +++ b/src/EFCore.Relational/Metadata/Conventions/RelationalTableAttributeConvention.cs @@ -22,9 +22,7 @@ public RelationalTableAttributeConvention( ProviderConventionSetBuilderDependencies dependencies, RelationalConventionSetBuilderDependencies relationalDependencies) : base(dependencies) - { - RelationalDependencies = relationalDependencies; - } + => RelationalDependencies = relationalDependencies; /// /// Relational provider-specific dependencies for this service. diff --git a/src/EFCore.Relational/Metadata/Conventions/RelationalTableCommentAttributeConvention.cs b/src/EFCore.Relational/Metadata/Conventions/RelationalTableCommentAttributeConvention.cs index ba202eb015e..e6ac6c4237d 100644 --- a/src/EFCore.Relational/Metadata/Conventions/RelationalTableCommentAttributeConvention.cs +++ b/src/EFCore.Relational/Metadata/Conventions/RelationalTableCommentAttributeConvention.cs @@ -20,9 +20,7 @@ public RelationalTableCommentAttributeConvention( ProviderConventionSetBuilderDependencies dependencies, RelationalConventionSetBuilderDependencies relationalDependencies) : base(dependencies) - { - RelationalDependencies = relationalDependencies; - } + => RelationalDependencies = relationalDependencies; /// /// Relational provider-specific dependencies for this service. diff --git a/src/EFCore.Relational/Metadata/Conventions/RelationalValueGenerationConvention.cs b/src/EFCore.Relational/Metadata/Conventions/RelationalValueGenerationConvention.cs index 20029a66117..087d1feec47 100644 --- a/src/EFCore.Relational/Metadata/Conventions/RelationalValueGenerationConvention.cs +++ b/src/EFCore.Relational/Metadata/Conventions/RelationalValueGenerationConvention.cs @@ -28,9 +28,7 @@ public RelationalValueGenerationConvention( ProviderConventionSetBuilderDependencies dependencies, RelationalConventionSetBuilderDependencies relationalDependencies) : base(dependencies) - { - RelationalDependencies = relationalDependencies; - } + => RelationalDependencies = relationalDependencies; /// /// Relational provider-specific dependencies for this service. diff --git a/src/EFCore.Relational/Metadata/Conventions/SequenceUniquificationConvention.cs b/src/EFCore.Relational/Metadata/Conventions/SequenceUniquificationConvention.cs index d901df57937..9afdd36ab39 100644 --- a/src/EFCore.Relational/Metadata/Conventions/SequenceUniquificationConvention.cs +++ b/src/EFCore.Relational/Metadata/Conventions/SequenceUniquificationConvention.cs @@ -44,7 +44,7 @@ public virtual void ProcessModelFinalizing( IConventionContext context) { var model = modelBuilder.Metadata; - var modelSequences = + var modelSequences = (IReadOnlyDictionary<(string Name, string? Schema), ISequence>?)model[RelationalAnnotationNames.Sequences]; if (modelSequences != null) { diff --git a/src/EFCore.Relational/Metadata/ITable.cs b/src/EFCore.Relational/Metadata/ITable.cs index bfcaa5b0c51..6b933ec9691 100644 --- a/src/EFCore.Relational/Metadata/ITable.cs +++ b/src/EFCore.Relational/Metadata/ITable.cs @@ -134,8 +134,8 @@ string ITableBase.ToDebugString(MetadataDebugStringOptions options, int indent) } if ((options & MetadataDebugStringOptions.SingleLine) == 0 - && designTime - && Comment != null) + && designTime + && Comment != null) { builder .AppendLine() diff --git a/src/EFCore.Relational/Metadata/Internal/CheckConstraint.cs b/src/EFCore.Relational/Metadata/Internal/CheckConstraint.cs index e40951abb20..08ade8a541b 100644 --- a/src/EFCore.Relational/Metadata/Internal/CheckConstraint.cs +++ b/src/EFCore.Relational/Metadata/Internal/CheckConstraint.cs @@ -122,11 +122,7 @@ public static IEnumerable GetCheckConstraints(IReadOnl public static IReadOnlyCheckConstraint? FindDeclaredCheckConstraint(IReadOnlyEntityType entityType, string name) { var dataDictionary = GetConstraintsDictionary(entityType); - return dataDictionary == null - ? null - : dataDictionary.TryGetValue(name, out var checkConstraint) - ? checkConstraint - : null; + return dataDictionary?.GetValueOrDefault(name); } /// diff --git a/src/EFCore.Relational/Metadata/Internal/ColumnNameComparer.cs b/src/EFCore.Relational/Metadata/Internal/ColumnNameComparer.cs index 28ce0569a97..3880cfcf8b2 100644 --- a/src/EFCore.Relational/Metadata/Internal/ColumnNameComparer.cs +++ b/src/EFCore.Relational/Metadata/Internal/ColumnNameComparer.cs @@ -20,9 +20,7 @@ public sealed class ColumnNameComparer : IComparer /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public ColumnNameComparer(Table table) - { - _table = table; - } + => _table = table; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Relational/Metadata/Internal/DbFunction.cs b/src/EFCore.Relational/Metadata/Internal/DbFunction.cs index 4096165f137..f93df12aea9 100644 --- a/src/EFCore.Relational/Metadata/Internal/DbFunction.cs +++ b/src/EFCore.Relational/Metadata/Internal/DbFunction.cs @@ -656,7 +656,8 @@ public virtual IReadOnlyList Parameters /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public virtual IStoreFunction? StoreFunction => _storeFunction; + public virtual IStoreFunction? StoreFunction + => _storeFunction; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Relational/Metadata/Internal/EntityTypeMappingFragment.cs b/src/EFCore.Relational/Metadata/Internal/EntityTypeMappingFragment.cs index d37388ba95c..eed19d44965 100644 --- a/src/EFCore.Relational/Metadata/Internal/EntityTypeMappingFragment.cs +++ b/src/EFCore.Relational/Metadata/Internal/EntityTypeMappingFragment.cs @@ -47,8 +47,10 @@ public EntityTypeMappingFragment( public virtual InternalEntityTypeMappingFragmentBuilder Builder { [DebuggerStepThrough] - get => _builder ?? throw new InvalidOperationException(CoreStrings.ObjectRemovedFromModel( - StoreObject.DisplayName())); + get => _builder + ?? throw new InvalidOperationException( + CoreStrings.ObjectRemovedFromModel( + StoreObject.DisplayName())); } /// diff --git a/src/EFCore.Relational/Metadata/Internal/FunctionMapping.cs b/src/EFCore.Relational/Metadata/Internal/FunctionMapping.cs index 2bf82c263f2..d6282e8f9c5 100644 --- a/src/EFCore.Relational/Metadata/Internal/FunctionMapping.cs +++ b/src/EFCore.Relational/Metadata/Internal/FunctionMapping.cs @@ -19,9 +19,7 @@ public class FunctionMapping : TableMappingBase, IFunctio /// public FunctionMapping(IEntityType entityType, StoreFunction storeFunction, IDbFunction dbFunction, bool? includesDerivedTypes) : base(entityType, storeFunction, includesDerivedTypes) - { - DbFunction = dbFunction; - } + => DbFunction = dbFunction; /// public virtual bool IsDefaultFunctionMapping { get; set; } diff --git a/src/EFCore.Relational/Metadata/Internal/RelationalModel.cs b/src/EFCore.Relational/Metadata/Internal/RelationalModel.cs index 637be020b0e..ae7dd11e42c 100644 --- a/src/EFCore.Relational/Metadata/Internal/RelationalModel.cs +++ b/src/EFCore.Relational/Metadata/Internal/RelationalModel.cs @@ -23,9 +23,7 @@ public class RelationalModel : Annotatable, IRelationalModel /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public RelationalModel(IModel model) - { - Model = model; - } + => Model = model; /// public virtual IModel Model { get; } @@ -286,12 +284,14 @@ private static void AddDefaultMappings( includesDerivedTypes: entityType.GetDirectlyDerivedTypes().Any() ? !isTpc && mappedType == entityType : null); + var containerColumnName = mappedType.GetContainerColumnName(); + var containerColumnType = mappedType.GetContainerColumnType(); if (!string.IsNullOrEmpty(containerColumnName)) { CreateContainerColumn( - defaultTable, containerColumnName, mappedType, relationalTypeMappingSource, - static (c, t, m) => new JsonColumnBase(c, m.StoreType, t, m)); + defaultTable, containerColumnName, containerColumnType, mappedType, relationalTypeMappingSource, + static (colName, colType, table, mapping) => new JsonColumnBase(colName, colType ?? mapping.StoreType, table, mapping)); } else { @@ -366,6 +366,7 @@ private static void CreateDefaultColumnMapping( tableMappings = new List>(); complexType.AddRuntimeAnnotation(RelationalAnnotationNames.DefaultMappings, tableMappings); } + tableMappings.Add(tableMapping); defaultTable.ComplexTypeMappings.Add(tableMapping); @@ -395,8 +396,8 @@ static string GetColumnName(IProperty property) private static IEnumerable GetTableMappings(ITypeBase typeBase) => (IEnumerable?)typeBase.FindRuntimeAnnotationValue( - RelationalAnnotationNames.TableMappings) - ?? Enumerable.Empty(); + RelationalAnnotationNames.TableMappings) + ?? Enumerable.Empty(); private static void AddTables( RelationalModel databaseModel, @@ -417,8 +418,8 @@ private static void AddTables( var mappingStrategy = entityType.GetMappingStrategy(); var isTpc = mappingStrategy == RelationalAnnotationNames.TpcMappingStrategy; var includesDerivedTypes = entityType.GetDirectlyDerivedTypes().Any() - ? !isTpc && mappedType == entityType - : (bool?)null; + ? !isTpc && mappedType == entityType + : (bool?)null; while (mappedType != null) { var mappedTableName = mappedType.GetTableName(); @@ -492,11 +493,12 @@ private static void CreateTableMapping( }; var containerColumnName = mappedType.GetContainerColumnName(); + var containerColumnType = mappedType.GetContainerColumnType(); if (!string.IsNullOrEmpty(containerColumnName)) { CreateContainerColumn( - table, containerColumnName, (IEntityType)mappedType, relationalTypeMappingSource, - static (c, t, m) => new JsonColumn(c, m.StoreType, (Table)t, m)); + table, containerColumnName, containerColumnType, (IEntityType)mappedType, relationalTypeMappingSource, + static (colName, colType, table, mapping) => new JsonColumn(colName, colType ?? mapping.StoreType, (Table)table, mapping)); } else { @@ -530,7 +532,8 @@ private static void CreateTableMapping( { var complexType = complexProperty.ComplexType; - var complexTableMappings = (List?)complexType.FindRuntimeAnnotationValue(RelationalAnnotationNames.TableMappings); + var complexTableMappings = + (List?)complexType.FindRuntimeAnnotationValue(RelationalAnnotationNames.TableMappings); if (complexTableMappings == null) { complexTableMappings = []; @@ -567,9 +570,10 @@ private static void CreateTableMapping( private static void CreateContainerColumn( TableBase tableBase, string containerColumnName, + string? containerColumnType, IEntityType mappedType, IRelationalTypeMappingSource relationalTypeMappingSource, - Func> createColumn) + Func> createColumn) where TColumnMappingBase : class, IColumnMappingBase { var ownership = mappedType.GetForeignKeys().Single(fk => fk.IsOwnership); @@ -577,8 +581,8 @@ private static void CreateContainerColumn( { Check.DebugAssert(tableBase.FindColumn(containerColumnName) == null, $"Table does not have column '{containerColumnName}'."); - var jsonColumnTypeMapping = relationalTypeMappingSource.FindMapping(typeof(JsonElement), mappedType.Model)!; - var jsonColumn = createColumn(containerColumnName, tableBase, jsonColumnTypeMapping); + var jsonColumnTypeMapping = relationalTypeMappingSource.FindMapping(typeof(JsonElement), storeTypeName: containerColumnType)!; + var jsonColumn = createColumn(containerColumnName, containerColumnType, tableBase, jsonColumnTypeMapping); tableBase.Columns.Add(containerColumnName, jsonColumn); jsonColumn.IsNullable = !ownership.IsRequiredDependent || !ownership.IsUnique; @@ -625,8 +629,8 @@ private static void AddViews( } var includesDerivedTypes = entityType.GetDirectlyDerivedTypes().Any() - ? !isTpc && mappedType == entityType - : (bool?)null; + ? !isTpc && mappedType == entityType + : (bool?)null; foreach (var fragment in mappedType.GetMappingFragments(StoreObjectType.View)) { CreateViewMapping( @@ -684,11 +688,13 @@ private static void CreateViewMapping( }; var containerColumnName = mappedType.GetContainerColumnName(); + var containerColumnType = mappedType.GetContainerColumnType(); if (!string.IsNullOrEmpty(containerColumnName)) { CreateContainerColumn( - view, containerColumnName, mappedType, relationalTypeMappingSource, - static (c, t, m) => new JsonViewColumn(c, m.StoreType, (View)t, m)); + view, containerColumnName, containerColumnType, mappedType, relationalTypeMappingSource, + static (colName, colType, table, mapping) => new JsonViewColumn( + colName, colType ?? mapping.StoreType, (View)table, mapping)); } else { @@ -770,11 +776,9 @@ private static void AddSqlQueries(RelationalModel databaseModel, IEntityType ent databaseModel.Queries.Add(mappedQuery.Name, sqlQuery); } - var queryMapping = new SqlQueryMapping(entityType, sqlQuery, - includesDerivedTypes: entityType.GetDirectlyDerivedTypes().Any() ? true : null) - { - IsDefaultSqlQueryMapping = true - }; + var queryMapping = new SqlQueryMapping( + entityType, sqlQuery, + includesDerivedTypes: entityType.GetDirectlyDerivedTypes().Any() ? true : null) { IsDefaultSqlQueryMapping = true }; foreach (var property in mappedType.GetProperties()) { @@ -909,11 +913,9 @@ private static FunctionMapping CreateFunctionMapping( var storeFunction = GetOrCreateStoreFunction(dbFunction, model); var mappedFunction = StoreObjectIdentifier.DbFunction(dbFunction.Name); - var functionMapping = new FunctionMapping(entityType, storeFunction, dbFunction, - includesDerivedTypes: entityType.GetDirectlyDerivedTypes().Any() ? true : null) - { - IsDefaultFunctionMapping = @default - }; + var functionMapping = new FunctionMapping( + entityType, storeFunction, dbFunction, + includesDerivedTypes: entityType.GetDirectlyDerivedTypes().Any() ? true : null) { IsDefaultFunctionMapping = @default }; foreach (var property in mappedType.GetProperties()) { @@ -997,8 +999,8 @@ private static void AddStoredProcedures( while (mappedType != null) { var includesDerivedTypes = entityType.GetDirectlyDerivedTypes().Any() - ? !isTpc && mappedType == entityType - : (bool?)null; + ? !isTpc && mappedType == entityType + : (bool?)null; var tableMappings = GetTableMappings(entityType).Where( m => m.Table.Name == mappedType.GetTableName() @@ -1245,7 +1247,8 @@ static StoreStoredProcedure GetOrCreateStoreStoredProcedure( var storeStoredProcedure = (StoreStoredProcedure?)storedProcedure.StoreStoredProcedure; if (storeStoredProcedure == null) { - storeStoredProcedure = (StoreStoredProcedure?)databaseModel.FindStoredProcedure(storedProcedure.Name, storedProcedure.Schema); + storeStoredProcedure = + (StoreStoredProcedure?)databaseModel.FindStoredProcedure(storedProcedure.Name, storedProcedure.Schema); if (storeStoredProcedure == null) { storeStoredProcedure = new StoreStoredProcedure(storedProcedure.Name, storedProcedure.Schema, databaseModel); @@ -1359,8 +1362,8 @@ static StoreStoredProcedureResultColumn GetOrCreateStoreStoredProcedureResultCol private static IEnumerable GetTableColumnMappings(IProperty property) => (IEnumerable?)property.FindRuntimeAnnotationValue( - RelationalAnnotationNames.TableColumnMappings) - ?? Enumerable.Empty(); + RelationalAnnotationNames.TableColumnMappings) + ?? Enumerable.Empty(); private static IColumn? FindColumn(Table table, IProperty property) => GetTableColumnMappings(property) @@ -1457,7 +1460,9 @@ private static void PopulateTableConfiguration(Table table, bool designTime) if (designTime) { - foreach (var checkConstraint in includeInherited ? entityType.GetCheckConstraints() : entityType.GetDeclaredCheckConstraints()) + foreach (var checkConstraint in includeInherited + ? entityType.GetCheckConstraints() + : entityType.GetDeclaredCheckConstraints()) { var name = checkConstraint.GetName(storeObject); if (name == null) @@ -2063,7 +2068,7 @@ IEnumerable IRelationalModel.Views IEnumerable IRelationalModel.Functions { [DebuggerStepThrough] - get => Functions.OrderBy(f => f.Key).Select(t => t.Value); + get => Functions.OrderBy(f => f.Key, NamedListComparer.Instance).Select(t => t.Value); } IEnumerable IRelationalModel.StoredProcedures diff --git a/src/EFCore.Relational/Metadata/Internal/RelationalPropertyExtensions.cs b/src/EFCore.Relational/Metadata/Internal/RelationalPropertyExtensions.cs index bc86bdd78c2..836b55f07d2 100644 --- a/src/EFCore.Relational/Metadata/Internal/RelationalPropertyExtensions.cs +++ b/src/EFCore.Relational/Metadata/Internal/RelationalPropertyExtensions.cs @@ -28,8 +28,5 @@ public static class RelationalPropertyExtensions /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public static bool IsOrdinalKeyProperty(this IReadOnlyProperty property) - => property.FindContainingPrimaryKey() is { Properties.Count: > 1 } - && !property.IsForeignKey() - && property.ClrType == typeof(int) - && property.GetJsonPropertyName() == null; + => property.Name == RelationalKeyDiscoveryConvention.SynthesizedOrdinalPropertyName; } diff --git a/src/EFCore.Relational/Metadata/Internal/RelationalPropertyOverrides.cs b/src/EFCore.Relational/Metadata/Internal/RelationalPropertyOverrides.cs index fea560ea1c9..3b0f0c41cc0 100644 --- a/src/EFCore.Relational/Metadata/Internal/RelationalPropertyOverrides.cs +++ b/src/EFCore.Relational/Metadata/Internal/RelationalPropertyOverrides.cs @@ -73,8 +73,10 @@ public override bool IsReadOnly public virtual InternalRelationalPropertyOverridesBuilder Builder { [DebuggerStepThrough] - get => _builder ?? throw new InvalidOperationException(CoreStrings.ObjectRemovedFromModel( - $"{Property.Name} - {StoreObject.DisplayName()}")); + get => _builder + ?? throw new InvalidOperationException( + CoreStrings.ObjectRemovedFromModel( + $"{Property.Name} - {StoreObject.DisplayName()}")); } /// diff --git a/src/EFCore.Relational/Metadata/Internal/RelationalTypeBaseExtensions.cs b/src/EFCore.Relational/Metadata/Internal/RelationalTypeBaseExtensions.cs index 037cb568f89..d84babc6554 100644 --- a/src/EFCore.Relational/Metadata/Internal/RelationalTypeBaseExtensions.cs +++ b/src/EFCore.Relational/Metadata/Internal/RelationalTypeBaseExtensions.cs @@ -23,8 +23,8 @@ public static IEnumerable GetViewOrTableMappings(this ITypeBa { typeBase.Model.EnsureRelationalModel(); return (IEnumerable?)(typeBase.FindRuntimeAnnotationValue( - RelationalAnnotationNames.ViewMappings) - ?? typeBase.FindRuntimeAnnotationValue(RelationalAnnotationNames.TableMappings)) - ?? Enumerable.Empty(); + RelationalAnnotationNames.ViewMappings) + ?? typeBase.FindRuntimeAnnotationValue(RelationalAnnotationNames.TableMappings)) + ?? Enumerable.Empty(); } } diff --git a/src/EFCore.Relational/Metadata/Internal/SqlQuery.cs b/src/EFCore.Relational/Metadata/Internal/SqlQuery.cs index 685655ca267..21346767cba 100644 --- a/src/EFCore.Relational/Metadata/Internal/SqlQuery.cs +++ b/src/EFCore.Relational/Metadata/Internal/SqlQuery.cs @@ -19,9 +19,7 @@ public class SqlQuery : TableBase, ISqlQuery /// public SqlQuery(string name, RelationalModel model, string sql) : base(name, null, model) - { - Sql = sql; - } + => Sql = sql; /// public virtual string Sql { get; set; } diff --git a/src/EFCore.Relational/Metadata/Internal/StoreStoredProcedure.cs b/src/EFCore.Relational/Metadata/Internal/StoreStoredProcedure.cs index 4db631dcaa5..6abb728ddba 100644 --- a/src/EFCore.Relational/Metadata/Internal/StoreStoredProcedure.cs +++ b/src/EFCore.Relational/Metadata/Internal/StoreStoredProcedure.cs @@ -103,9 +103,7 @@ public virtual void AddParameter(IStoreStoredProcedureParameter parameter) /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual IStoreStoredProcedureParameter? FindParameter(string name) - => _parametersSet.TryGetValue(name, out var parameter) - ? parameter - : null; + => _parametersSet.GetValueOrDefault(name); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Relational/Metadata/Internal/StoreStoredProcedureResultColumn.cs b/src/EFCore.Relational/Metadata/Internal/StoreStoredProcedureResultColumn.cs index 29f1f4913c0..16624668886 100644 --- a/src/EFCore.Relational/Metadata/Internal/StoreStoredProcedureResultColumn.cs +++ b/src/EFCore.Relational/Metadata/Internal/StoreStoredProcedureResultColumn.cs @@ -25,9 +25,7 @@ public StoreStoredProcedureResultColumn( StoreStoredProcedure storedProcedure, RelationalTypeMapping? storeTypeMapping = null) : base(name, type, storedProcedure, storeTypeMapping) - { - Position = position; - } + => Position = position; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Relational/Metadata/Internal/StoredProcedure.cs b/src/EFCore.Relational/Metadata/Internal/StoredProcedure.cs index de01c98664b..06f6fc25fe1 100644 --- a/src/EFCore.Relational/Metadata/Internal/StoredProcedure.cs +++ b/src/EFCore.Relational/Metadata/Internal/StoredProcedure.cs @@ -505,9 +505,7 @@ public virtual IReadOnlyList Parameters /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual StoredProcedureParameter? FindParameter(string propertyName) - => _currentValueParameters.TryGetValue(propertyName, out var parameter) - ? parameter - : null; + => _currentValueParameters.GetValueOrDefault(propertyName); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -538,9 +536,7 @@ public virtual StoredProcedureParameter AddParameter(string propertyName) /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual StoredProcedureParameter? FindOriginalValueParameter(string propertyName) - => _originalValueParameters.TryGetValue(propertyName, out var parameter) - ? parameter - : null; + => _originalValueParameters.GetValueOrDefault(propertyName); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -616,9 +612,7 @@ public virtual IReadOnlyList ResultColumns /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual StoredProcedureResultColumn? FindResultColumn(string propertyName) - => _propertyResultColumns.TryGetValue(propertyName, out var resultColumn) - ? resultColumn - : null; + => _propertyResultColumns.GetValueOrDefault(propertyName); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Relational/Metadata/Internal/StoredProcedureComparer.cs b/src/EFCore.Relational/Metadata/Internal/StoredProcedureComparer.cs index edb4e5d6be6..07d03daa7f6 100644 --- a/src/EFCore.Relational/Metadata/Internal/StoredProcedureComparer.cs +++ b/src/EFCore.Relational/Metadata/Internal/StoredProcedureComparer.cs @@ -47,11 +47,11 @@ public int Compare(IStoredProcedure? x, IStoredProcedure? y) return 1; } - var xId = x.GetStoreIdentifier(); - var yId = y.GetStoreIdentifier(); + var xStoreId = x.GetStoreIdentifier(); + var yStoreId = y.GetStoreIdentifier(); var result = 0; - result = xId.StoreObjectType.CompareTo(yId.StoreObjectType); + result = xStoreId.StoreObjectType.CompareTo(yStoreId.StoreObjectType); if (result != 0) { return result; @@ -63,13 +63,13 @@ public int Compare(IStoredProcedure? x, IStoredProcedure? y) return result; } - result = StringComparer.Ordinal.Compare(xId.Name, yId.Name); + result = StringComparer.Ordinal.Compare(xStoreId.Name, yStoreId.Name); if (result != 0) { return result; } - result = StringComparer.Ordinal.Compare(xId.Schema, yId.Schema); + result = StringComparer.Ordinal.Compare(xStoreId.Schema, yStoreId.Schema); if (result != 0) { return result; diff --git a/src/EFCore.Relational/Metadata/Internal/StoredProcedureParameterMapping.cs b/src/EFCore.Relational/Metadata/Internal/StoredProcedureParameterMapping.cs index 3a07090020e..cb17a986501 100644 --- a/src/EFCore.Relational/Metadata/Internal/StoredProcedureParameterMapping.cs +++ b/src/EFCore.Relational/Metadata/Internal/StoredProcedureParameterMapping.cs @@ -23,9 +23,7 @@ public StoredProcedureParameterMapping( StoreStoredProcedureParameter storeParameter, StoredProcedureMapping storedProcedureMapping) : base(property, storeParameter, storedProcedureMapping) - { - Parameter = parameter; - } + => Parameter = parameter; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Relational/Metadata/Internal/StoredProcedureResultColumnMapping.cs b/src/EFCore.Relational/Metadata/Internal/StoredProcedureResultColumnMapping.cs index 51b40790312..367586abc02 100644 --- a/src/EFCore.Relational/Metadata/Internal/StoredProcedureResultColumnMapping.cs +++ b/src/EFCore.Relational/Metadata/Internal/StoredProcedureResultColumnMapping.cs @@ -23,9 +23,7 @@ public StoredProcedureResultColumnMapping( StoreStoredProcedureResultColumn storeResultColumn, StoredProcedureMapping storedProcedureMapping) : base(property, storeResultColumn, storedProcedureMapping) - { - ResultColumn = resultColumn; - } + => ResultColumn = resultColumn; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Relational/Metadata/Internal/Table.cs b/src/EFCore.Relational/Metadata/Internal/Table.cs index 10d70265c92..9ba15edbe8b 100644 --- a/src/EFCore.Relational/Metadata/Internal/Table.cs +++ b/src/EFCore.Relational/Metadata/Internal/Table.cs @@ -21,9 +21,7 @@ public class Table : TableBase, ITable /// public Table(string name, string? schema, RelationalModel model) : base(name, schema, model) - { - Columns = new SortedDictionary(new ColumnNameComparer(this)); - } + => Columns = new SortedDictionary(new ColumnNameComparer(this)); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -109,9 +107,7 @@ public virtual UniqueConstraint? PrimaryKey public virtual UniqueConstraint? FindUniqueConstraint(string name) => PrimaryKey != null && PrimaryKey.Name == name ? PrimaryKey - : UniqueConstraints.TryGetValue(name, out var constraint) - ? constraint - : null; + : UniqueConstraints.GetValueOrDefault(name); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Relational/Metadata/Internal/TableBase.cs b/src/EFCore.Relational/Metadata/Internal/TableBase.cs index 43d36758ed2..d2accdc373d 100644 --- a/src/EFCore.Relational/Metadata/Internal/TableBase.cs +++ b/src/EFCore.Relational/Metadata/Internal/TableBase.cs @@ -86,9 +86,7 @@ public override bool IsReadOnly /// public virtual IColumnBase? FindColumn(string name) - => Columns.TryGetValue(name, out var column) - ? column - : null; + => Columns.GetValueOrDefault(name); /// public virtual IColumnBase? FindColumn(IProperty property) diff --git a/src/EFCore.Relational/Metadata/RelationalAdHocMapper.cs b/src/EFCore.Relational/Metadata/RelationalAdHocMapper.cs index e59550c82b0..ade20fc2738 100644 --- a/src/EFCore.Relational/Metadata/RelationalAdHocMapper.cs +++ b/src/EFCore.Relational/Metadata/RelationalAdHocMapper.cs @@ -30,9 +30,7 @@ public class RelationalAdHocMapper : AdHocMapper /// public RelationalAdHocMapper(AdHocMapperDependencies dependencies, RelationalAdHocMapperDependencies relationalDependencies) : base(dependencies) - { - RelationalDependencies = relationalDependencies; - } + => RelationalDependencies = relationalDependencies; /// /// Relational-specific dependencies for this service. diff --git a/src/EFCore.Relational/Metadata/RelationalAnnotationNames.cs b/src/EFCore.Relational/Metadata/RelationalAnnotationNames.cs index 6041736eca8..efbf0a4e205 100644 --- a/src/EFCore.Relational/Metadata/RelationalAnnotationNames.cs +++ b/src/EFCore.Relational/Metadata/RelationalAnnotationNames.cs @@ -324,6 +324,11 @@ public static class RelationalAnnotationNames /// public const string ContainerColumnName = Prefix + "ContainerColumnName"; + /// + /// The column type for the container column to which the object is mapped. + /// + public const string ContainerColumnType = Prefix + nameof(ContainerColumnType); + /// /// The name for the annotation specifying container column type mapping. /// @@ -368,9 +373,9 @@ public static class RelationalAnnotationNames Collation, DefaultSchema, Name, - #pragma warning disable CS0618 // Type or member is obsolete +#pragma warning disable CS0618 // Type or member is obsolete SequencePrefix, - #pragma warning restore CS0618 // Type or member is obsolete +#pragma warning restore CS0618 // Type or member is obsolete Sequences, CheckConstraints, Filter, @@ -408,9 +413,10 @@ public static class RelationalAnnotationNames ModelDependencies, FieldValueGetter, ContainerColumnName, - #pragma warning disable CS0618 // Type or member is obsolete + ContainerColumnType, +#pragma warning disable CS0618 // Type or member is obsolete ContainerColumnTypeMapping, - #pragma warning restore CS0618 // Type or member is obsolete +#pragma warning restore CS0618 // Type or member is obsolete JsonPropertyName, StoreType }; diff --git a/src/EFCore.Relational/Metadata/RelationalAnnotationProvider.cs b/src/EFCore.Relational/Metadata/RelationalAnnotationProvider.cs index 05bd8fa3605..b7e0bea889f 100644 --- a/src/EFCore.Relational/Metadata/RelationalAnnotationProvider.cs +++ b/src/EFCore.Relational/Metadata/RelationalAnnotationProvider.cs @@ -25,9 +25,7 @@ public class RelationalAnnotationProvider : IRelationalAnnotationProvider /// /// Parameter object containing dependencies for this service. public RelationalAnnotationProvider(RelationalAnnotationProviderDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Relational provider-specific dependencies for this service. diff --git a/src/EFCore.Relational/Metadata/RuntimeDbFunction.cs b/src/EFCore.Relational/Metadata/RuntimeDbFunction.cs index b2e62b25929..0f638a228d3 100644 --- a/src/EFCore.Relational/Metadata/RuntimeDbFunction.cs +++ b/src/EFCore.Relational/Metadata/RuntimeDbFunction.cs @@ -145,7 +145,8 @@ public virtual RuntimeDbFunctionParameter AddParameter( /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public virtual IStoreFunction? StoreFunction => _storeFunction; + public virtual IStoreFunction? StoreFunction + => _storeFunction; /// /// Returns a string that represents the current object. diff --git a/src/EFCore.Relational/Metadata/StoreObjectDictionary.cs b/src/EFCore.Relational/Metadata/StoreObjectDictionary.cs index 84ede007aae..864b596eb55 100644 --- a/src/EFCore.Relational/Metadata/StoreObjectDictionary.cs +++ b/src/EFCore.Relational/Metadata/StoreObjectDictionary.cs @@ -14,9 +14,7 @@ public class StoreObjectDictionary : IReadOnlyStoreObjectDictionary /// public virtual T? Find(in StoreObjectIdentifier storeObject) - => _dictionary.TryGetValue(storeObject, out var value) - ? value - : null; + => _dictionary.GetValueOrDefault(storeObject); /// public virtual IEnumerable GetValues() diff --git a/src/EFCore.Relational/Migrations/HistoryRepository.cs b/src/EFCore.Relational/Migrations/HistoryRepository.cs index e3d1a03e75f..bfb565786c0 100644 --- a/src/EFCore.Relational/Migrations/HistoryRepository.cs +++ b/src/EFCore.Relational/Migrations/HistoryRepository.cs @@ -47,6 +47,14 @@ protected HistoryRepository(HistoryRepositoryDependencies dependencies) TableSchema = relationalOptions.MigrationsHistoryTableSchema; } + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + public abstract LockReleaseBehavior LockReleaseBehavior { get; } + /// /// Relational provider-specific dependencies for this service. /// @@ -120,14 +128,15 @@ protected virtual string ProductVersionColumnName /// /// if the table already exists, otherwise. public virtual bool Exists() - => InterpretExistsResult( - Dependencies.RawSqlCommandBuilder.Build(ExistsSql).ExecuteScalar( - new RelationalCommandParameterObject( - Dependencies.Connection, - null, - null, - Dependencies.CurrentContext.Context, - Dependencies.CommandLogger, CommandSource.Migrations))); + => Dependencies.DatabaseCreator.Exists() + && InterpretExistsResult( + Dependencies.RawSqlCommandBuilder.Build(ExistsSql).ExecuteScalar( + new RelationalCommandParameterObject( + Dependencies.Connection, + null, + null, + Dependencies.CurrentContext.Context, + Dependencies.CommandLogger, CommandSource.Migrations))); /// /// Checks whether or not the history table exists. @@ -139,15 +148,16 @@ public virtual bool Exists() /// /// If the is canceled. public virtual async Task ExistsAsync(CancellationToken cancellationToken = default) - => InterpretExistsResult( - await Dependencies.RawSqlCommandBuilder.Build(ExistsSql).ExecuteScalarAsync( - new RelationalCommandParameterObject( - Dependencies.Connection, - null, - null, - Dependencies.CurrentContext.Context, - Dependencies.CommandLogger, CommandSource.Migrations), - cancellationToken).ConfigureAwait(false)); + => await Dependencies.DatabaseCreator.ExistsAsync(cancellationToken).ConfigureAwait(false) + && InterpretExistsResult( + await Dependencies.RawSqlCommandBuilder.Build(ExistsSql).ExecuteScalarAsync( + new RelationalCommandParameterObject( + Dependencies.Connection, + null, + null, + Dependencies.CurrentContext.Context, + Dependencies.CommandLogger, CommandSource.Migrations), + cancellationToken).ConfigureAwait(false)); /// /// Interprets the result of executing . @@ -173,13 +183,15 @@ public virtual string GetCreateScript() /// Creates the history table. /// public virtual void Create() - => Dependencies.MigrationCommandExecutor.ExecuteNonQuery(GetCreateCommands(), Dependencies.Connection); + => Dependencies.MigrationCommandExecutor.ExecuteNonQuery( + GetCreateCommands(), Dependencies.Connection, new MigrationExecutionState(), commitTransaction: true); /// /// Creates the history table. /// public virtual Task CreateAsync(CancellationToken cancellationToken = default) - => Dependencies.MigrationCommandExecutor.ExecuteNonQueryAsync(GetCreateCommands(), Dependencies.Connection, cancellationToken); + => Dependencies.MigrationCommandExecutor.ExecuteNonQueryAsync( + GetCreateCommands(), Dependencies.Connection, new MigrationExecutionState(), commitTransaction: true, cancellationToken: cancellationToken); /// /// Returns the migration commands that will create the history table. @@ -194,21 +206,37 @@ protected virtual IReadOnlyList GetCreateCommands() return commandList; } + bool IHistoryRepository.CreateIfNotExists() + => Dependencies.MigrationCommandExecutor.ExecuteNonQuery( + GetCreateIfNotExistsCommands(), Dependencies.Connection, new MigrationExecutionState(), commitTransaction: true) + != 0; + + async Task IHistoryRepository.CreateIfNotExistsAsync(CancellationToken cancellationToken) + => (await Dependencies.MigrationCommandExecutor.ExecuteNonQueryAsync( + GetCreateIfNotExistsCommands(), Dependencies.Connection, new MigrationExecutionState(), commitTransaction: true, cancellationToken: cancellationToken).ConfigureAwait(false)) + != 0; + + private IReadOnlyList GetCreateIfNotExistsCommands() + => Dependencies.MigrationsSqlGenerator.Generate([new SqlOperation + { + Sql = GetCreateIfNotExistsScript(), + SuppressTransaction = true + }]); + /// /// Gets an exclusive lock on the database. /// - /// The time to wait for the lock before an exception is thrown. /// An object that can be disposed to release the lock. - public abstract IDisposable GetDatabaseLock(TimeSpan timeout); + public abstract IMigrationsDatabaseLock AcquireDatabaseLock(); /// /// Gets an exclusive lock on the database. /// - /// The time to wait for the lock before an exception is thrown. /// A to observe while waiting for the task to complete. + /// /// An object that can be disposed to release the lock. /// If the is canceled. - public abstract Task GetDatabaseLockAsync(TimeSpan timeout, CancellationToken cancellationToken = default); + public abstract Task AcquireDatabaseLockAsync(CancellationToken cancellationToken = default); /// /// Configures the entity type mapped to the history table. diff --git a/src/EFCore.Relational/Migrations/HistoryRepositoryDependencies.cs b/src/EFCore.Relational/Migrations/HistoryRepositoryDependencies.cs index b5f40bd8ba2..a8bf28d3f22 100644 --- a/src/EFCore.Relational/Migrations/HistoryRepositoryDependencies.cs +++ b/src/EFCore.Relational/Migrations/HistoryRepositoryDependencies.cs @@ -59,7 +59,8 @@ public HistoryRepositoryDependencies( IRelationalTypeMappingSource typeMappingSource, ICurrentDbContext currentContext, IModelRuntimeInitializer modelRuntimeInitializer, - IRelationalCommandDiagnosticsLogger commandLogger) + IRelationalCommandDiagnosticsLogger commandLogger, + IDiagnosticsLogger migrationsLogger) { DatabaseCreator = databaseCreator; RawSqlCommandBuilder = rawSqlCommandBuilder; @@ -75,6 +76,7 @@ public HistoryRepositoryDependencies( CurrentContext = currentContext; ModelRuntimeInitializer = modelRuntimeInitializer; CommandLogger = commandLogger; + MigrationsLogger = migrationsLogger; } /// @@ -146,4 +148,9 @@ public HistoryRepositoryDependencies( /// The command logger /// public IRelationalCommandDiagnosticsLogger CommandLogger { get; init; } + + /// + /// The migrations logger + /// + public IDiagnosticsLogger MigrationsLogger { get; init; } } diff --git a/src/EFCore.Relational/Migrations/IHistoryRepository.cs b/src/EFCore.Relational/Migrations/IHistoryRepository.cs index 4d52db38043..2189e6cea87 100644 --- a/src/EFCore.Relational/Migrations/IHistoryRepository.cs +++ b/src/EFCore.Relational/Migrations/IHistoryRepository.cs @@ -50,12 +50,44 @@ public interface IHistoryRepository /// /// A to observe while waiting for the task to complete. /// - /// A task that represents the asynchronous operation. The task result contains - /// if the table already exists, otherwise. + /// A task that represents the asynchronous operation. /// /// If the is canceled. Task CreateAsync(CancellationToken cancellationToken = default); + /// + /// Creates the history table if it doesn't exist. + /// + /// if the table was created, otherwise. + bool CreateIfNotExists() + { + if (!Exists()) + { + Create(); + return true; + } + return false; + } + + /// + /// Creates the history table. + /// + /// A to observe while waiting for the task to complete. + /// + /// A task that represents the asynchronous operation. The task result contains + /// if the table was created, otherwise. + /// + /// If the is canceled. + async Task CreateIfNotExistsAsync(CancellationToken cancellationToken = default) + { + if (!await ExistsAsync(cancellationToken).ConfigureAwait(false)) + { + await CreateAsync(cancellationToken).ConfigureAwait(false); + return true; + } + return false; + } + /// /// Queries the history table for all migrations that have been applied. /// @@ -75,20 +107,23 @@ Task> GetAppliedMigrationsAsync( CancellationToken cancellationToken = default); /// - /// Gets an exclusive lock on the database. + /// The condition under witch the lock is released implicitly. + /// + LockReleaseBehavior LockReleaseBehavior { get; } + + /// + /// Acquires an exclusive lock on the database. /// - /// The time to wait for the lock before an exception is thrown. /// An object that can be disposed to release the lock. - IDisposable GetDatabaseLock(TimeSpan timeout); + IMigrationsDatabaseLock AcquireDatabaseLock(); /// - /// Gets an exclusive lock on the database. + /// Acquires an exclusive lock on the database asynchronously. /// - /// The time to wait for the lock before an exception is thrown. /// A to observe while waiting for the task to complete. /// An object that can be disposed to release the lock. /// If the is canceled. - Task GetDatabaseLockAsync(TimeSpan timeout, CancellationToken cancellationToken = default); + Task AcquireDatabaseLockAsync(CancellationToken cancellationToken = default); /// /// Generates a SQL script that will create the history table. diff --git a/src/EFCore.Relational/Migrations/IMigrationCommandExecutor.cs b/src/EFCore.Relational/Migrations/IMigrationCommandExecutor.cs index 7069ba9c045..039bbaa4f15 100644 --- a/src/EFCore.Relational/Migrations/IMigrationCommandExecutor.cs +++ b/src/EFCore.Relational/Migrations/IMigrationCommandExecutor.cs @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Data; + namespace Microsoft.EntityFrameworkCore.Migrations; /// @@ -28,6 +30,24 @@ void ExecuteNonQuery( IEnumerable migrationCommands, IRelationalConnection connection); + /// + /// Executes the given commands using the given database connection. + /// + /// The commands to execute. + /// The connection to use. + /// The state of the current migration execution. + /// + /// Indicates whether the transaction started by this call should be commited. + /// If , the transaction will be made available in . + /// + /// The isolation level for the transaction. + int ExecuteNonQuery( + IReadOnlyList migrationCommands, + IRelationalConnection connection, + MigrationExecutionState executionState, + bool commitTransaction, + IsolationLevel? isolationLevel = null); + /// /// Executes the given commands using the given database connection. /// @@ -40,4 +60,26 @@ Task ExecuteNonQueryAsync( IEnumerable migrationCommands, IRelationalConnection connection, CancellationToken cancellationToken = default); + + /// + /// Executes the given commands using the given database connection. + /// + /// The commands to execute. + /// The connection to use. + /// The state of the current migration execution. + /// + /// Indicates whether the transaction started by this call should be commited. + /// If , the transaction will be made available in . + /// + /// The isolation level for the transaction. + /// A to observe while waiting for the task to complete. + /// A task that represents the asynchronous operation. + /// If the is canceled. + Task ExecuteNonQueryAsync( + IReadOnlyList migrationCommands, + IRelationalConnection connection, + MigrationExecutionState executionState, + bool commitTransaction, + IsolationLevel? isolationLevel = null, + CancellationToken cancellationToken = default); } diff --git a/src/EFCore.Relational/Migrations/IMigrationsDatabaseLock.cs b/src/EFCore.Relational/Migrations/IMigrationsDatabaseLock.cs new file mode 100644 index 00000000000..b08ea1b9faa --- /dev/null +++ b/src/EFCore.Relational/Migrations/IMigrationsDatabaseLock.cs @@ -0,0 +1,62 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.Migrations; + +/// +/// Represents an exclusive lock on the database that is used to ensure that only one migration application can be run at a time. +/// +/// +/// Typically only database providers implement this. +/// +public interface IMigrationsDatabaseLock : IDisposable, IAsyncDisposable +{ + /// + /// The history repository. + /// + protected IHistoryRepository HistoryRepository { get; } + + /// + /// Acquires an exclusive lock on the database again if the current one was already released. + /// + /// Indicates whether the connection was reopened. + /// + /// Indicates whether the transaction was restarted. + /// if there's no current transaction. + /// + /// An object that can be disposed to release the lock. + IMigrationsDatabaseLock ReacquireIfNeeded(bool connectionReopened, bool? transactionRestarted) + { + if ((connectionReopened && HistoryRepository.LockReleaseBehavior == LockReleaseBehavior.Connection) + || (transactionRestarted is true && HistoryRepository.LockReleaseBehavior == LockReleaseBehavior.Transaction)) + { + Dispose(); + return HistoryRepository.AcquireDatabaseLock(); + } + + return this; + } + + /// + /// Acquires an exclusive lock on the database again, if the current one was already released. + /// + /// Indicates whether the connection was reopened. + /// + /// Indicates whether the transaction was restarted. + /// if there's no current transaction. + /// + /// A to observe while waiting for the task to complete. + /// An object that can be disposed to release the lock. + async Task ReacquireIfNeededAsync( + bool connectionReopened, bool? transactionRestarted, CancellationToken cancellationToken = default) + { + if ((connectionReopened && HistoryRepository.LockReleaseBehavior == LockReleaseBehavior.Connection) + || (transactionRestarted is true && HistoryRepository.LockReleaseBehavior == LockReleaseBehavior.Transaction)) + { + await DisposeAsync().ConfigureAwait(false); + return await HistoryRepository.AcquireDatabaseLockAsync(cancellationToken).ConfigureAwait(false); + } + + return this; + } +} diff --git a/src/EFCore.Relational/Migrations/IMigrator.cs b/src/EFCore.Relational/Migrations/IMigrator.cs index 0b02cbe7df3..b7735b4f0f7 100644 --- a/src/EFCore.Relational/Migrations/IMigrator.cs +++ b/src/EFCore.Relational/Migrations/IMigrator.cs @@ -26,37 +26,23 @@ public interface IMigrator /// Migrates the database to either a specified target migration or up to the latest /// migration that exists in the . /// - /// - /// The optional seed method to run after migrating the database. It will be invoked even if no migrations were applied. - /// /// /// The target migration to migrate the database to, or to migrate to the latest. /// - /// - /// The maximum amount of time that the migration lock should be held. Unless a catastrophic failure occurs, the - /// lock is released when the migration operation completes. - /// /// /// See Database migrations for more information and examples. /// [RequiresUnreferencedCode("Migration generation currently isn't compatible with trimming")] [RequiresDynamicCode("Migrations operations are not supported with NativeAOT")] - void Migrate(Action? seed = null, string? targetMigration = null, TimeSpan? lockTimeout = null); + void Migrate(string? targetMigration = null); /// /// Migrates the database to either a specified target migration or up to the latest /// migration that exists in the . /// - /// - /// The optional seed method to run after migrating the database. It will be invoked even if no migrations were applied. - /// /// /// The target migration to migrate the database to, or to migrate to the latest. /// - /// - /// The maximum amount of time that the migration lock should be held. Unless a catastrophic failure occurs, the - /// lock is released when the migration operation completes. - /// /// A to observe while waiting for the task to complete. /// A task that represents the asynchronous operation /// @@ -66,9 +52,7 @@ public interface IMigrator [RequiresUnreferencedCode("Migration generation currently isn't compatible with trimming")] [RequiresDynamicCode("Migrations operations are not supported with NativeAOT")] Task MigrateAsync( - Func? seed = null, string? targetMigration = null, - TimeSpan? lockTimeout = null, CancellationToken cancellationToken = default); /// diff --git a/src/EFCore.Relational/Migrations/IMigratorData.cs b/src/EFCore.Relational/Migrations/IMigratorData.cs deleted file mode 100644 index 60531a1c699..00000000000 --- a/src/EFCore.Relational/Migrations/IMigratorData.cs +++ /dev/null @@ -1,29 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.EntityFrameworkCore.Migrations; - -/// -/// A class that holds the results from the last migrations application. -/// -/// -/// See Database migrations for more information and examples. -/// -public interface IMigratorData -{ - /// - /// The migrations that were applied to the database. - /// - public IReadOnlyList AppliedMigrations { get; } - - /// - /// The migrations that were reverted from the database. - /// - public IReadOnlyList RevertedMigrations { get; } - - /// - /// The target migration. - /// if all migrations were reverted or no target migration was specified. - /// - public Migration? TargetMigration { get; } -} diff --git a/src/EFCore.Relational/Migrations/IMigratorPlugin.cs b/src/EFCore.Relational/Migrations/IMigratorPlugin.cs deleted file mode 100644 index ae06c4d968e..00000000000 --- a/src/EFCore.Relational/Migrations/IMigratorPlugin.cs +++ /dev/null @@ -1,73 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.EntityFrameworkCore.Migrations; - -/// -/// -/// A service on the EF internal service provider that allows providers or extensions to execute logic -/// after is called. -/// -/// -/// This type is typically used by providers or extensions. It is generally not used in application code. -/// -/// -/// -/// The service lifetime is . This means a single instance -/// is used by many instances. The implementation must be thread-safe. -/// This service cannot depend on services registered as . -/// -public interface IMigratorPlugin -{ - /// - /// Called by before applying the migrations. - /// - /// The that is being migrated. - /// The that contains the result of the migrations application. - /// - /// See Database migrations for more information and examples. - /// - void Migrating(DbContext context, IMigratorData data); - - /// - /// Called by before applying the migrations. - /// - /// The that is being migrated. - /// The that contains the result of the migrations application. - /// - /// See Database migrations for more information and examples. - /// - /// A to observe while waiting for the task to complete. - /// A task that represents the asynchronous operation - /// If the is canceled. - Task MigratingAsync( - DbContext context, - IMigratorData data, - CancellationToken cancellationToken = default); - - /// - /// Called by after applying the migrations, but before the seeding action. - /// - /// The that is being migrated. - /// The that contains the result of the migrations application. - /// - /// See Database migrations for more information and examples. - /// - void Migrated(DbContext context, IMigratorData data); - - /// - /// Called by after applying the migrations, but before the seeding action. - /// - /// The that is being migrated. - /// The that contains the result of the migrations application. - /// - /// See Database migrations for more information and examples. - /// - /// A to observe while waiting for the task to complete. - /// A task that represents the asynchronous operation - /// If the is canceled. - Task MigratedAsync( - DbContext context, - IMigratorData data, - CancellationToken cancellationToken = default); -} diff --git a/src/EFCore.Relational/Migrations/Internal/MigrationCommandExecutor.cs b/src/EFCore.Relational/Migrations/Internal/MigrationCommandExecutor.cs index e545d4c13b5..68c6ba4a886 100644 --- a/src/EFCore.Relational/Migrations/Internal/MigrationCommandExecutor.cs +++ b/src/EFCore.Relational/Migrations/Internal/MigrationCommandExecutor.cs @@ -11,20 +11,25 @@ namespace Microsoft.EntityFrameworkCore.Migrations.Internal; /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// -public class MigrationCommandExecutor : IMigrationCommandExecutor +/// +/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to +/// the same compatibility standards as public APIs. It may be changed or removed without notice in +/// any release. You should only use it directly in your code with extreme caution and knowing that +/// doing so can result in application failures when updating to a new Entity Framework Core release. +/// +public class MigrationCommandExecutor(IExecutionStrategy executionStrategy) : IMigrationCommandExecutor { - private readonly IExecutionStrategy _executionStrategy; - /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public MigrationCommandExecutor(IExecutionStrategy executionStrategy) - { - _executionStrategy = executionStrategy; - } + public virtual void ExecuteNonQuery( + IEnumerable migrationCommands, + IRelationalConnection connection) + => ExecuteNonQuery( + migrationCommands.ToList(), connection, new MigrationExecutionState(), commitTransaction: true); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -32,75 +37,111 @@ public MigrationCommandExecutor(IExecutionStrategy executionStrategy) /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public virtual void ExecuteNonQuery( - IEnumerable migrationCommands, - IRelationalConnection connection) + public virtual int ExecuteNonQuery( + IReadOnlyList migrationCommands, + IRelationalConnection connection, + MigrationExecutionState executionState, + bool commitTransaction, + System.Data.IsolationLevel? isolationLevel = null) { - var userTransaction = connection.CurrentTransaction; - if (userTransaction is not null - && (migrationCommands.Any(x => x.TransactionSuppressed) || _executionStrategy.RetriesOnFailure)) + var inUserTransaction = connection.CurrentTransaction is not null && executionState.Transaction == null; + if (inUserTransaction + && (migrationCommands.Any(x => x.TransactionSuppressed) || executionStrategy.RetriesOnFailure)) { throw new NotSupportedException(RelationalStrings.TransactionSuppressedMigrationInUserTransaction); } - using (new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled)) - { - var parameters = new ExecuteParameters(migrationCommands.ToList(), connection); - if (userTransaction is null) - { - _executionStrategy.Execute(parameters, static (_, p) => Execute(p, beginTransaction: true), verifySucceeded: null); - } - else - { - Execute(parameters, beginTransaction: false); - } - } + using var transactionScope = new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled); + + return executionStrategy.Execute( + (migrationCommands, connection, inUserTransaction, executionState, commitTransaction, isolationLevel), + static (_, s) => Execute( + s.migrationCommands, + s.connection, + s.executionState, + beginTransaction: !s.inUserTransaction, + commitTransaction: !s.inUserTransaction && s.commitTransaction, + s.isolationLevel), + verifySucceeded: null); } - private static bool Execute(ExecuteParameters parameters, bool beginTransaction) + private static int Execute( + IReadOnlyList migrationCommands, + IRelationalConnection connection, + MigrationExecutionState executionState, + bool beginTransaction, + bool commitTransaction, + System.Data.IsolationLevel? isolationLevel) { - var migrationCommands = parameters.MigrationCommands; - var connection = parameters.Connection; - IDbContextTransaction? transaction = null; - connection.Open(); + var result = 0; + var connectionOpened = connection.Open(); + Check.DebugAssert(!connectionOpened || executionState.Transaction == null, + "executionState.Transaction should be null"); + try { - for (var i = parameters.CurrentCommandIndex; i < migrationCommands.Count; i++) + for (var i = executionState.LastCommittedCommandIndex; i < migrationCommands.Count; i++) { var command = migrationCommands[i]; - if (transaction == null + if (executionState.Transaction == null && !command.TransactionSuppressed && beginTransaction) { - transaction = connection.BeginTransaction(); + executionState.Transaction = isolationLevel == null + ? connection.BeginTransaction() + : connection.BeginTransaction(isolationLevel.Value); + if (executionState.DatabaseLock != null) + { + executionState.DatabaseLock = executionState.DatabaseLock.ReacquireIfNeeded( + connectionOpened, transactionRestarted: true); + connectionOpened = false; + } } - if (transaction != null + if (executionState.Transaction != null && command.TransactionSuppressed) { - transaction.Commit(); - transaction.Dispose(); - transaction = null; - parameters.CurrentCommandIndex = i; + executionState.Transaction.Commit(); + executionState.Transaction.Dispose(); + executionState.Transaction = null; + executionState.LastCommittedCommandIndex = i; + executionState.AnyOperationPerformed = true; + + if (executionState.DatabaseLock != null) + { + executionState.DatabaseLock = executionState.DatabaseLock.ReacquireIfNeeded( + connectionOpened, transactionRestarted: null); + connectionOpened = false; + } } - command.ExecuteNonQuery(connection); + result = command.ExecuteNonQuery(connection); - if (transaction == null) + if (executionState.Transaction == null) { - parameters.CurrentCommandIndex = i + 1; + executionState.LastCommittedCommandIndex = i + 1; + executionState.AnyOperationPerformed = true; } } - transaction?.Commit(); + if (commitTransaction + && executionState.Transaction != null) + { + executionState.Transaction.Commit(); + executionState.Transaction.Dispose(); + executionState.Transaction = null; + } } - finally + catch { - transaction?.Dispose(); + executionState.Transaction?.Dispose(); + executionState.Transaction = null; connection.Close(); + throw; } - return true; + connection.Close(); + return result; } /// @@ -109,101 +150,136 @@ private static bool Execute(ExecuteParameters parameters, bool beginTransaction) /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public virtual async Task ExecuteNonQueryAsync( + public virtual Task ExecuteNonQueryAsync( IEnumerable migrationCommands, IRelationalConnection connection, CancellationToken cancellationToken = default) + => ExecuteNonQueryAsync( + migrationCommands.ToList(), connection, new MigrationExecutionState(), commitTransaction: true, System.Data.IsolationLevel.Unspecified, cancellationToken); + + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + public virtual async Task ExecuteNonQueryAsync( + IReadOnlyList migrationCommands, + IRelationalConnection connection, + MigrationExecutionState executionState, + bool commitTransaction, + System.Data.IsolationLevel? isolationLevel = null, + CancellationToken cancellationToken = default) { - var userTransaction = connection.CurrentTransaction; - if (userTransaction is not null - && (migrationCommands.Any(x => x.TransactionSuppressed) || _executionStrategy.RetriesOnFailure)) + var inUserTransaction = connection.CurrentTransaction is not null && executionState.Transaction == null; + if (inUserTransaction + && (migrationCommands.Any(x => x.TransactionSuppressed) || executionStrategy.RetriesOnFailure)) { throw new NotSupportedException(RelationalStrings.TransactionSuppressedMigrationInUserTransaction); } - var transactionScope = new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled); - try - { - var parameters = new ExecuteParameters(migrationCommands.ToList(), connection); - if (userTransaction is null) - { - await _executionStrategy.ExecuteAsync( - parameters, - static (_, p, ct) => ExecuteAsync(p, beginTransaction: true, ct), - verifySucceeded: null, - cancellationToken).ConfigureAwait(false); - } - else - { - await ExecuteAsync(parameters, beginTransaction: false, cancellationToken).ConfigureAwait(false); - } + using var transactionScope = new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled); - } - finally - { - await transactionScope.DisposeAsyncIfAvailable().ConfigureAwait(false); - } + return await executionStrategy.ExecuteAsync( + (migrationCommands, connection, inUserTransaction, executionState, commitTransaction, isolationLevel), + static (_, s, ct) => ExecuteAsync( + s.migrationCommands, + s.connection, + s.executionState, + beginTransaction: !s.inUserTransaction, + commitTransaction: !s.inUserTransaction && s.commitTransaction, + s.isolationLevel, + ct), + verifySucceeded: null, + cancellationToken).ConfigureAwait(false); } - private static async Task ExecuteAsync(ExecuteParameters parameters, bool beginTransaction, CancellationToken cancellationToken) + private static async Task ExecuteAsync( + IReadOnlyList migrationCommands, + IRelationalConnection connection, + MigrationExecutionState executionState, + bool beginTransaction, + bool commitTransaction, + System.Data.IsolationLevel? isolationLevel, + CancellationToken cancellationToken) { - var migrationCommands = parameters.MigrationCommands; - var connection = parameters.Connection; - IDbContextTransaction? transaction = null; - await connection.OpenAsync(cancellationToken).ConfigureAwait(false); + var result = 0; + var connectionOpened = await connection.OpenAsync(cancellationToken).ConfigureAwait(false); + Check.DebugAssert(!connectionOpened || executionState.Transaction == null, + "executionState.Transaction should be null"); + try { - for (var i = parameters.CurrentCommandIndex; i < migrationCommands.Count; i++) + for (var i = executionState.LastCommittedCommandIndex; i < migrationCommands.Count; i++) { + var lockReacquired = false; var command = migrationCommands[i]; - if (transaction == null + if (executionState.Transaction == null && !command.TransactionSuppressed && beginTransaction) { - transaction = await connection.BeginTransactionAsync(cancellationToken) + executionState.Transaction = await (isolationLevel == null + ? connection.BeginTransactionAsync(cancellationToken) + : connection.BeginTransactionAsync(isolationLevel.Value, cancellationToken)) .ConfigureAwait(false); + + if (executionState.DatabaseLock != null) + { + executionState.DatabaseLock = await executionState.DatabaseLock.ReacquireIfNeededAsync( + connectionOpened, transactionRestarted: true, cancellationToken) + .ConfigureAwait(false); + lockReacquired = true; + } } - if (transaction != null + if (executionState.Transaction != null && command.TransactionSuppressed) { - await transaction.CommitAsync(cancellationToken).ConfigureAwait(false); - await transaction.DisposeAsync().ConfigureAwait(false); - transaction = null; - parameters.CurrentCommandIndex = i; + await executionState.Transaction.CommitAsync(cancellationToken).ConfigureAwait(false); + await executionState.Transaction.DisposeAsync().ConfigureAwait(false); + executionState.Transaction = null; + executionState.LastCommittedCommandIndex = i; + executionState.AnyOperationPerformed = true; + + if (executionState.DatabaseLock != null + && !lockReacquired) + { + executionState.DatabaseLock = await executionState.DatabaseLock.ReacquireIfNeededAsync( + connectionOpened, transactionRestarted: null, cancellationToken) + .ConfigureAwait(false); + } } - await command.ExecuteNonQueryAsync(connection, cancellationToken: cancellationToken) + result = await command.ExecuteNonQueryAsync(connection, cancellationToken: cancellationToken) .ConfigureAwait(false); - if (transaction == null) + if (executionState.Transaction == null) { - parameters.CurrentCommandIndex = i + 1; + executionState.LastCommittedCommandIndex = i + 1; + executionState.AnyOperationPerformed = true; } } - if (transaction != null) + if (commitTransaction + && executionState.Transaction != null) { - await transaction.CommitAsync(cancellationToken).ConfigureAwait(false); + await executionState.Transaction.CommitAsync(cancellationToken).ConfigureAwait(false); + await executionState.Transaction.DisposeAsync().ConfigureAwait(false); + executionState.Transaction = null; } } - finally + catch { - if (transaction != null) + if (executionState.Transaction != null) { - await transaction.DisposeAsync().ConfigureAwait(false); + await executionState.Transaction.DisposeAsync().ConfigureAwait(false); + executionState.Transaction = null; } - await connection.CloseAsync().ConfigureAwait(false); + throw; } - return true; - } - - private sealed class ExecuteParameters(List migrationCommands, IRelationalConnection connection) - { - public int CurrentCommandIndex; - public List MigrationCommands { get; } = migrationCommands; - public IRelationalConnection Connection { get; } = connection; + await connection.CloseAsync().ConfigureAwait(false); + return result; } } diff --git a/src/EFCore.Relational/Migrations/Internal/MigrationsAssembly.cs b/src/EFCore.Relational/Migrations/Internal/MigrationsAssembly.cs index d323288303d..bfbfa0af56e 100644 --- a/src/EFCore.Relational/Migrations/Internal/MigrationsAssembly.cs +++ b/src/EFCore.Relational/Migrations/Internal/MigrationsAssembly.cs @@ -35,8 +35,8 @@ public MigrationsAssembly( var assemblyObject = RelationalOptionsExtension.Extract(options).MigrationsAssemblyObject; Assembly = assemblyName == null - ? assemblyObject ?? _contextType.Assembly - : Assembly.Load(new AssemblyName(assemblyName)); + ? assemblyObject ?? _contextType.Assembly + : Assembly.Load(new AssemblyName(assemblyName)); _idGenerator = idGenerator; _logger = logger; diff --git a/src/EFCore.Relational/Migrations/Internal/MigrationsModelDiffer.cs b/src/EFCore.Relational/Migrations/Internal/MigrationsModelDiffer.cs index 474881f8c28..91a409a72f1 100644 --- a/src/EFCore.Relational/Migrations/Internal/MigrationsModelDiffer.cs +++ b/src/EFCore.Relational/Migrations/Internal/MigrationsModelDiffer.cs @@ -1245,11 +1245,14 @@ private void Initialize( { // for non-nullable collections of primitives that are mapped to JSON we set a default value corresponding to empty JSON collection defaultValue = !inline - && column is { IsNullable: false, StoreTypeMapping: { ElementTypeMapping: not null, Converter: ValueConverter columnValueConverter } } + && column is + { + IsNullable: false, StoreTypeMapping: { ElementTypeMapping: not null, Converter: ValueConverter columnValueConverter } + } && columnValueConverter.GetType() is Type { IsGenericType: true } columnValueConverterType && columnValueConverterType.GetGenericTypeDefinition() == typeof(CollectionToJsonStringConverter<>) - ? "[]" - : null; + ? "[]" + : null; } columnOperation.DefaultValue = defaultValue diff --git a/src/EFCore.Relational/Migrations/Internal/Migrator.cs b/src/EFCore.Relational/Migrations/Internal/Migrator.cs index 4012a1a7a53..a6644ef6fc1 100644 --- a/src/EFCore.Relational/Migrations/Internal/Migrator.cs +++ b/src/EFCore.Relational/Migrations/Internal/Migrator.cs @@ -1,8 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Transactions; using Microsoft.EntityFrameworkCore.Diagnostics.Internal; -using Microsoft.EntityFrameworkCore.Storage; namespace Microsoft.EntityFrameworkCore.Migrations.Internal; @@ -26,11 +26,11 @@ public class Migrator : IMigrator private readonly IModelRuntimeInitializer _modelRuntimeInitializer; private readonly IDiagnosticsLogger _logger; private readonly IRelationalCommandDiagnosticsLogger _commandLogger; - private readonly IEnumerable _plugins; private readonly IMigrationsModelDiffer _migrationsModelDiffer; private readonly IDesignTimeModel _designTimeModel; private readonly string _activeProvider; - private static readonly TimeSpan _defaultLockTimeout = TimeSpan.FromHours(1); + private readonly IDbContextOptions _contextOptions; + private readonly IExecutionStrategy _executionStrategy; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -52,9 +52,10 @@ public Migrator( IDiagnosticsLogger logger, IRelationalCommandDiagnosticsLogger commandLogger, IDatabaseProvider databaseProvider, - IEnumerable plugins, IMigrationsModelDiffer migrationsModelDiffer, - IDesignTimeModel designTimeModel) + IDesignTimeModel designTimeModel, + IDbContextOptions contextOptions, + IExecutionStrategy executionStrategy) { _migrationsAssembly = migrationsAssembly; _historyRepository = historyRepository; @@ -68,10 +69,11 @@ public Migrator( _modelRuntimeInitializer = modelRuntimeInitializer; _logger = logger; _commandLogger = commandLogger; - _plugins = plugins; _migrationsModelDiffer = migrationsModelDiffer; _designTimeModel = designTimeModel; _activeProvider = databaseProvider.Name; + _contextOptions = contextOptions; + _executionStrategy = executionStrategy; } /// @@ -80,30 +82,100 @@ public Migrator( /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public virtual void Migrate(Action? seed, string? targetMigration, TimeSpan? lockTimeout) + protected virtual System.Data.IsolationLevel? MigrationTransactionIsolationLevel => null; + + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + public virtual void Migrate(string? targetMigration) { + var useTransaction = _connection.CurrentTransaction is null; + if (!useTransaction + && _executionStrategy.RetriesOnFailure) + { + throw new NotSupportedException(RelationalStrings.TransactionSuppressedMigrationInUserTransaction); + } + if (RelationalResources.LogPendingModelChanges(_logger).WarningBehavior != WarningBehavior.Ignore && HasPendingModelChanges()) { _logger.PendingModelChangesWarning(_currentContext.Context.GetType()); } + if (!useTransaction) + { + _logger.MigrationsUserTransactionWarning(); + } + _logger.MigrateUsingConnection(this, _connection); + using var transactionScope = new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled); + if (!_databaseCreator.Exists()) { _databaseCreator.Create(); } + _connection.Open(); try { - _connection.Open(); + var state = new MigrationExecutionState(); + if (_historyRepository.LockReleaseBehavior != LockReleaseBehavior.Transaction + && useTransaction) + { + state.DatabaseLock = _historyRepository.AcquireDatabaseLock(); + } - using var _ = _historyRepository.GetDatabaseLock(lockTimeout ?? _defaultLockTimeout); + _executionStrategy.Execute( + this, + static (_, migrator) => + { + migrator._connection.Open(); + try + { + return migrator._historyRepository.CreateIfNotExists(); + } + finally + { + migrator._connection.Close(); + } + }, + verifySucceeded: null); + + _executionStrategy.Execute( + (Migrator: this, + TargetMigration: targetMigration, + State: state, + UseTransaction: useTransaction), + static (c, s) => s.Migrator.MigrateImplementation(c, s.TargetMigration, s.State, s.UseTransaction), + static (_, s) => new ExecutionResult( + successful: s.Migrator.VerifyMigrationSucceeded(s.TargetMigration, s.State), + result: true)); + } + finally + { + _connection.Close(); + } + } - if (!_historyRepository.Exists()) + private bool MigrateImplementation( + DbContext context, string? targetMigration, MigrationExecutionState state, bool useTransaction) + { + var connectionOpened = _connection.Open(); + try + { + if (useTransaction) { - _historyRepository.Create(); + state.Transaction = MigrationTransactionIsolationLevel == null + ? _connection.BeginTransaction() + : _connection.BeginTransaction(MigrationTransactionIsolationLevel.Value); + + state.DatabaseLock = state.DatabaseLock == null + ? _historyRepository.AcquireDatabaseLock() + : state.DatabaseLock.ReacquireIfNeeded(connectionOpened, useTransaction); } PopulateMigrations( @@ -111,31 +183,43 @@ public virtual void Migrate(Action? seed, string? targ targetMigration, out var migratorData); - foreach (var plugin in _plugins) - { - plugin.Migrating(_currentContext.Context, migratorData); - } - var commandLists = GetMigrationCommandLists(migratorData); foreach (var commandList in commandLists) { - _migrationCommandExecutor.ExecuteNonQuery(commandList(), _connection); - } + var (id, getCommands) = commandList; + if (id != state.CurrentMigrationId) + { + state.CurrentMigrationId = id; + state.LastCommittedCommandIndex = 0; + } - foreach (var plugin in _plugins) - { - plugin.Migrated(_currentContext.Context, migratorData); + _migrationCommandExecutor.ExecuteNonQuery( + getCommands(), _connection, state, commitTransaction: false, MigrationTransactionIsolationLevel); } + var coreOptionsExtension = + _contextOptions.FindExtension() + ?? new CoreOptionsExtension(); + + var seed = coreOptionsExtension.Seeder; if (seed != null) { - using var transaction = _connection.BeginTransaction(); - seed(_currentContext.Context, migratorData); - transaction.Commit(); + seed(context, state.AnyOperationPerformed); + } + else if (coreOptionsExtension.AsyncSeeder != null) + { + throw new InvalidOperationException(CoreStrings.MissingSeeder); } + + state.Transaction?.Commit(); + return state.AnyOperationPerformed; } finally { + state.DatabaseLock?.Dispose(); + state.DatabaseLock = null; + state.Transaction?.Dispose(); + state.Transaction = null; _connection.Close(); } } @@ -147,34 +231,99 @@ public virtual void Migrate(Action? seed, string? targ /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual async Task MigrateAsync( - Func? seed, string? targetMigration, - TimeSpan? lockTimeout = null, CancellationToken cancellationToken = default) { + var useTransaction = _connection.CurrentTransaction is null; + if (!useTransaction + && _executionStrategy.RetriesOnFailure) + { + throw new NotSupportedException(RelationalStrings.TransactionSuppressedMigrationInUserTransaction); + } + if (RelationalResources.LogPendingModelChanges(_logger).WarningBehavior != WarningBehavior.Ignore && HasPendingModelChanges()) { _logger.PendingModelChangesWarning(_currentContext.Context.GetType()); } + if (!useTransaction) + { + _logger.MigrationsUserTransactionWarning(); + } + _logger.MigrateUsingConnection(this, _connection); + using var transactionScope = new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled); + if (!await _databaseCreator.ExistsAsync(cancellationToken).ConfigureAwait(false)) { await _databaseCreator.CreateAsync(cancellationToken).ConfigureAwait(false); } + await _connection.OpenAsync(cancellationToken).ConfigureAwait(false); try { - await _connection.OpenAsync(cancellationToken).ConfigureAwait(false); + var state = new MigrationExecutionState(); + if (_historyRepository.LockReleaseBehavior != LockReleaseBehavior.Transaction + && useTransaction) + { + state.DatabaseLock = await _historyRepository.AcquireDatabaseLockAsync(cancellationToken).ConfigureAwait(false); + } - var dbLock = await _historyRepository.GetDatabaseLockAsync(lockTimeout ?? _defaultLockTimeout, cancellationToken).ConfigureAwait(false); - await using var _ = dbLock.ConfigureAwait(false); + await _executionStrategy.ExecuteAsync( + this, + static async (_, migrator, ct) => + { + await migrator._connection.OpenAsync(ct).ConfigureAwait(false); + try + { + return await migrator._historyRepository.CreateIfNotExistsAsync(ct).ConfigureAwait(false); + } + finally + { + await migrator._connection.CloseAsync().ConfigureAwait(false); + } + }, + verifySucceeded: null, + cancellationToken).ConfigureAwait(false); + + await _executionStrategy.ExecuteAsync( + (Migrator: this, + TargetMigration: targetMigration, + State: state, + UseTransaction: useTransaction), + async static (c, s, ct) => await s.Migrator.MigrateImplementationAsync( + c, s.TargetMigration, s.State, s.UseTransaction, ct).ConfigureAwait(false), + async static (_, s, ct) => new ExecutionResult( + successful: await s.Migrator.VerifyMigrationSucceededAsync(s.TargetMigration, s.State, ct).ConfigureAwait(false), + result: true), + cancellationToken) + .ConfigureAwait(false); + } + finally + { + await _connection.CloseAsync().ConfigureAwait(false); + } + } - if (!await _historyRepository.ExistsAsync(cancellationToken).ConfigureAwait(false)) + private async Task MigrateImplementationAsync( + DbContext context, string? targetMigration, MigrationExecutionState state, bool useTransaction, CancellationToken cancellationToken = default) + { + var connectionOpened = await _connection.OpenAsync(cancellationToken).ConfigureAwait(false); + try + { + if (useTransaction) { - await _historyRepository.CreateAsync(cancellationToken).ConfigureAwait(false); + state.Transaction = await (MigrationTransactionIsolationLevel == null + ? context.Database.BeginTransactionAsync(cancellationToken) + : context.Database.BeginTransactionAsync(MigrationTransactionIsolationLevel.Value, cancellationToken)) + .ConfigureAwait(false); + + state.DatabaseLock = state.DatabaseLock == null + ? await _historyRepository.AcquireDatabaseLockAsync(cancellationToken).ConfigureAwait(false) + : await state.DatabaseLock.ReacquireIfNeededAsync(connectionOpened, useTransaction, cancellationToken) + .ConfigureAwait(false); } PopulateMigrations( @@ -182,38 +331,58 @@ public virtual async Task MigrateAsync( targetMigration, out var migratorData); - foreach (var plugin in _plugins) - { - await plugin.MigratingAsync(_currentContext.Context, migratorData, cancellationToken).ConfigureAwait(false); - } - var commandLists = GetMigrationCommandLists(migratorData); foreach (var commandList in commandLists) { - await _migrationCommandExecutor.ExecuteNonQueryAsync(commandList(), _connection, cancellationToken) + var (id, getCommands) = commandList; + if (id != state.CurrentMigrationId) + { + state.CurrentMigrationId = id; + state.LastCommittedCommandIndex = 0; + } + + await _migrationCommandExecutor.ExecuteNonQueryAsync( + getCommands(), _connection, state, commitTransaction: false, MigrationTransactionIsolationLevel, cancellationToken) .ConfigureAwait(false); } - foreach (var plugin in _plugins) + var coreOptionsExtension = + _contextOptions.FindExtension() + ?? new CoreOptionsExtension(); + + var seedAsync = coreOptionsExtension.AsyncSeeder; + if (seedAsync != null) { - await plugin.MigratedAsync(_currentContext.Context, migratorData, cancellationToken).ConfigureAwait(false); + await seedAsync(context, state.AnyOperationPerformed, cancellationToken).ConfigureAwait(false); + } + else if (coreOptionsExtension.Seeder != null) + { + throw new InvalidOperationException(CoreStrings.MissingSeeder); } - if (seed != null) + if (state.Transaction != null) { - var transaction = await _connection.BeginTransactionAsync(cancellationToken).ConfigureAwait(false); - await using var __ = transaction.ConfigureAwait(false); - await seed(_currentContext.Context, migratorData, cancellationToken).ConfigureAwait(false); - await transaction.CommitAsync(cancellationToken).ConfigureAwait(false); + await state.Transaction.CommitAsync(cancellationToken).ConfigureAwait(false); } + return state.AnyOperationPerformed; } finally { - _connection.Close(); + if (state.DatabaseLock != null) + { + state.DatabaseLock.Dispose(); + state.DatabaseLock = null; + } + if (state.Transaction != null) + { + await state.Transaction.DisposeAsync().ConfigureAwait(false); + state.Transaction = null; + } + await _connection.CloseAsync().ConfigureAwait(false); } } - private IEnumerable>> GetMigrationCommandLists(IMigratorData parameters) + private IEnumerable<(string, Func>)> GetMigrationCommandLists(MigratorData parameters) { var migrationsToApply = parameters.AppliedMigrations; var migrationsToRevert = parameters.RevertedMigrations; @@ -224,7 +393,7 @@ private IEnumerable>> GetMigrationCommandLi var migration = migrationsToRevert[i]; var index = i; - yield return () => + yield return (migration.GetId(), () => { _logger.MigrationReverting(this, migration); @@ -238,13 +407,14 @@ private IEnumerable>> GetMigrationCommandLi { _logger.NonTransactionalMigrationOperationWarning(this, migration, nonTransactionalCommand); } + return commands; - }; + }); } foreach (var migration in migrationsToApply) { - yield return () => + yield return (migration.GetId(), () => { _logger.MigrationApplying(this, migration); @@ -254,8 +424,9 @@ private IEnumerable>> GetMigrationCommandLi { _logger.NonTransactionalMigrationOperationWarning(this, migration, nonTransactionalCommand); } + return commands; - }; + }); } if (migrationsToRevert.Count + migrationsToApply.Count == 0) @@ -273,7 +444,7 @@ private IEnumerable>> GetMigrationCommandLi protected virtual void PopulateMigrations( IEnumerable appliedMigrationEntries, string? targetMigration, - out IMigratorData parameters) + out MigratorData parameters) { var appliedMigrations = new Dictionary(); var unappliedMigrations = new Dictionary(); @@ -336,6 +507,26 @@ protected virtual void PopulateMigrations( parameters = new MigratorData(migrationsToApply, migrationsToRevert, actualTargetMigration); } + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + protected virtual bool VerifyMigrationSucceeded( + string? targetMigration, MigrationExecutionState state) + => false; + + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + protected virtual Task VerifyMigrationSucceededAsync( + string? targetMigration, MigrationExecutionState state, CancellationToken cancellationToken) + => Task.FromResult(false); + /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in @@ -518,8 +709,8 @@ protected virtual IReadOnlyList GenerateDownSql( private IModel? FinalizeModel(IModel? model) => model == null - ? null - : _modelRuntimeInitializer.Initialize(model); + ? null + : _modelRuntimeInitializer.Initialize(model); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Relational/Migrations/Internal/MigratorData.cs b/src/EFCore.Relational/Migrations/Internal/MigratorData.cs index 97c47555d2f..6a4f0706460 100644 --- a/src/EFCore.Relational/Migrations/Internal/MigratorData.cs +++ b/src/EFCore.Relational/Migrations/Internal/MigratorData.cs @@ -13,7 +13,6 @@ public class MigratorData( IReadOnlyList appliedMigrations, IReadOnlyList revertedMigrations, Migration? targetMigration) - : IMigratorData { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -21,7 +20,7 @@ public class MigratorData( /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public IReadOnlyList AppliedMigrations { get; } = appliedMigrations; + public virtual IReadOnlyList AppliedMigrations { get; } = appliedMigrations; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -29,7 +28,7 @@ public class MigratorData( /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public IReadOnlyList RevertedMigrations { get; } = revertedMigrations; + public virtual IReadOnlyList RevertedMigrations { get; } = revertedMigrations; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -37,5 +36,5 @@ public class MigratorData( /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public Migration? TargetMigration { get; } = targetMigration; + public virtual Migration? TargetMigration { get; } = targetMigration; } diff --git a/src/EFCore.Relational/Migrations/LockReleaseBehavior.cs b/src/EFCore.Relational/Migrations/LockReleaseBehavior.cs new file mode 100644 index 00000000000..bd1f96e995c --- /dev/null +++ b/src/EFCore.Relational/Migrations/LockReleaseBehavior.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.Migrations; + +/// +/// Represents the conditions under which a lock is released implicitly. +/// +public enum LockReleaseBehavior +{ + /// + /// The lock is released when the transaction is committed or rolled back. + /// + Transaction, + + /// + /// The lock is released when the connection is closed. + /// + Connection, + + /// + /// The lock can only be released explicitly. + /// + Explicit +} diff --git a/src/EFCore.Relational/Migrations/MigrationBuilder.cs b/src/EFCore.Relational/Migrations/MigrationBuilder.cs index 04ede42da18..0cde7484d7d 100644 --- a/src/EFCore.Relational/Migrations/MigrationBuilder.cs +++ b/src/EFCore.Relational/Migrations/MigrationBuilder.cs @@ -19,9 +19,7 @@ public class MigrationBuilder /// /// The name of the database provider being used. public MigrationBuilder(string? activeProvider) - { - ActiveProvider = activeProvider; - } + => ActiveProvider = activeProvider; /// /// The name of the database provider being used. diff --git a/src/EFCore.Relational/Migrations/MigrationExecutionState.cs b/src/EFCore.Relational/Migrations/MigrationExecutionState.cs new file mode 100644 index 00000000000..accd83e0cfc --- /dev/null +++ b/src/EFCore.Relational/Migrations/MigrationExecutionState.cs @@ -0,0 +1,35 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.Migrations; + +/// +/// Contains the state of the current migration execution. +/// +public sealed class MigrationExecutionState +{ + /// + /// The index of the last command that was committed to the database. + /// + public int LastCommittedCommandIndex { get; set; } + + /// + /// The id the migration that is currently being applied. + /// + public string? CurrentMigrationId { get; set; } + + /// + /// Indicates whether any migration operation was performed. + /// + public bool AnyOperationPerformed { get; set; } + + /// + /// The database lock that is in use. + /// + public IMigrationsDatabaseLock? DatabaseLock { get; set; } + + /// + /// The transaction that is in use. + /// + public IDbContextTransaction? Transaction { get; set; } +} diff --git a/src/EFCore.Relational/Migrations/MigrationsAnnotationProvider.cs b/src/EFCore.Relational/Migrations/MigrationsAnnotationProvider.cs index 3aeb3993814..8813f778429 100644 --- a/src/EFCore.Relational/Migrations/MigrationsAnnotationProvider.cs +++ b/src/EFCore.Relational/Migrations/MigrationsAnnotationProvider.cs @@ -24,9 +24,7 @@ public class MigrationsAnnotationProvider : IMigrationsAnnotationProvider /// /// Parameter object containing dependencies for this service. public MigrationsAnnotationProvider(MigrationsAnnotationProviderDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Relational provider-specific dependencies for this service. diff --git a/src/EFCore.Relational/Migrations/MigrationsSqlGenerator.cs b/src/EFCore.Relational/Migrations/MigrationsSqlGenerator.cs index 28de816666e..9db17d862fe 100644 --- a/src/EFCore.Relational/Migrations/MigrationsSqlGenerator.cs +++ b/src/EFCore.Relational/Migrations/MigrationsSqlGenerator.cs @@ -1249,7 +1249,7 @@ protected virtual void SequenceOptions( /// The sequence options. /// The target model which may be if the operations exist without a model. /// The command builder to use to add the SQL fragment. - /// If , then all options are included, even if default. + /// If , then all options are included, even if default. protected virtual void SequenceOptions( string? schema, string name, diff --git a/src/EFCore.Relational/Migrations/Operations/DropColumnOperation.cs b/src/EFCore.Relational/Migrations/Operations/DropColumnOperation.cs index 842bf281700..110e0aee581 100644 --- a/src/EFCore.Relational/Migrations/Operations/DropColumnOperation.cs +++ b/src/EFCore.Relational/Migrations/Operations/DropColumnOperation.cs @@ -17,9 +17,7 @@ public class DropColumnOperation : MigrationOperation, ITableMigrationOperation /// // ReSharper disable once VirtualMemberCallInConstructor public DropColumnOperation() - { - IsDestructiveChange = true; - } + => IsDestructiveChange = true; /// /// The name of the column. diff --git a/src/EFCore.Relational/Migrations/Operations/DropTableOperation.cs b/src/EFCore.Relational/Migrations/Operations/DropTableOperation.cs index 25ef798eb15..ca14b66c22c 100644 --- a/src/EFCore.Relational/Migrations/Operations/DropTableOperation.cs +++ b/src/EFCore.Relational/Migrations/Operations/DropTableOperation.cs @@ -17,9 +17,7 @@ public class DropTableOperation : MigrationOperation, ITableMigrationOperation /// // ReSharper disable once VirtualMemberCallInConstructor public DropTableOperation() - { - IsDestructiveChange = true; - } + => IsDestructiveChange = true; /// /// The name of the table. diff --git a/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs b/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs index 3b7b9c4c49e..63c19e40d40 100644 --- a/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs +++ b/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs @@ -195,6 +195,22 @@ public static string ConflictingTypeMappingsInferredForColumn(object? column) GetString("ConflictingTypeMappingsInferredForColumn", nameof(column)), column); + /// + /// The entity type '{entityType}' has a container column type configured, but is nested in another owned type. The container column type can only be specified on a top-level owned type mapped to a container. + /// + public static string ContainerTypeOnNestedOwnedEntityType(object? entityType) + => string.Format( + GetString("ContainerTypeOnNestedOwnedEntityType", nameof(entityType)), + entityType); + + /// + /// The entity type '{entityType}' has a container column type configured, but is not mapped to a container column, such as for JSON. The container column type can only be specified on a top-level owned type mapped to a container. + /// + public static string ContainerTypeOnNonContainer(object? entityType) + => string.Format( + GetString("ContainerTypeOnNonContainer", nameof(entityType)), + entityType); + /// /// {numSortOrderProperties} values were provided in CreateIndexOperations.IsDescending, but the operation has {numColumns} columns. /// @@ -795,6 +811,14 @@ public static string ExecuteOperationWithUnsupportedOperatorInSqlGeneration(obje GetString("ExecuteOperationWithUnsupportedOperatorInSqlGeneration", nameof(operation)), operation); + /// + /// ExecuteUpdate or ExecuteDelete was called on entity type '{entityType}', but that entity type is not mapped to a table. + /// + public static string ExecuteUpdateDeleteOnEntityNotMappedToTable(object? entityType) + => string.Format( + GetString("ExecuteUpdateDeleteOnEntityNotMappedToTable", nameof(entityType)), + entityType); + /// /// ExecuteUpdate is being used over a LINQ operator which isn't natively supported by the database; this cannot be translated because complex type '{complexType}' is projected out. Rewrite your query to project out the containing entity type instead. /// @@ -1053,6 +1077,12 @@ public static string JsonCantNavigateToParentEntity(object? jsonEntity, object? GetString("JsonCantNavigateToParentEntity", nameof(jsonEntity), nameof(parentEntity), nameof(navigation)), jsonEntity, parentEntity, navigation); + /// + /// The database returned the empty string when a JSON object was expected. + /// + public static string JsonEmptyString + => GetString("JsonEmptyString"); + /// /// Entity '{jsonType}' is mapped to JSON and also to a table or view '{tableOrViewName}', but its owner '{ownerType}' is mapped to a different table or view '{ownerTableOrViewName}'. Every entity mapped to JSON must also map to the same table or view as its owner. /// @@ -1118,12 +1148,12 @@ public static string JsonEntityWithExplicitlyConfiguredJsonPropertyNameOnKey(obj keyProperty, jsonEntity); /// - /// Entity type '{jsonEntity}' is part of a collection mapped to JSON and has its ordinal key defined explicitly. Only implicitly defined ordinal keys are supported. + /// The property '{entityType}.{property}' is configured as part of the primary key. Explicitly configured primary keys are not supported on entities stored in JSON collections, and any key configuration should be removed. /// - public static string JsonEntityWithExplicitlyConfiguredOrdinalKey(object? jsonEntity) + public static string JsonEntityWithExplicitlyConfiguredKey(object? entityType, object? property) => string.Format( - GetString("JsonEntityWithExplicitlyConfiguredOrdinalKey", nameof(jsonEntity)), - jsonEntity); + GetString("JsonEntityWithExplicitlyConfiguredKey", nameof(entityType), nameof(property)), + entityType, property); /// /// Entity type '{jsonEntity}' has an incorrect number of primary key properties. Expected number is: {expectedCount}, actual number is: {actualCount}. @@ -2233,6 +2263,31 @@ public static class RelationalResources private static readonly ResourceManager _resourceManager = new ResourceManager("Microsoft.EntityFrameworkCore.Properties.RelationalStrings", typeof(RelationalResources).Assembly); + /// + /// Acquiring an exclusive lock for migration application. See https://aka.ms/efcore-docs-migrations-lock for more information if this takes too long. + /// + public static EventDefinition LogAcquiringMigrationLock(IDiagnosticsLogger logger) + { + var definition = ((RelationalLoggingDefinitions)logger.Definitions).LogAcquiringMigrationLock; + if (definition == null) + { + definition = NonCapturingLazyInitializer.EnsureInitialized( + ref ((RelationalLoggingDefinitions)logger.Definitions).LogAcquiringMigrationLock, + logger, + static logger => new EventDefinition( + logger.Options, + RelationalEventId.AcquiringMigrationLock, + LogLevel.Information, + "RelationalEventId.AcquiringMigrationLock", + level => LoggerMessage.Define( + level, + RelationalEventId.AcquiringMigrationLock, + _resourceManager.GetString("LogAcquiringMigrationLock")!))); + } + + return (EventDefinition)definition; + } + /// /// An ambient transaction has been detected, but the current provider does not support ambient transactions. See https://go.microsoft.com/fwlink/?LinkId=800142 /// @@ -3377,6 +3432,31 @@ public static EventDefinition LogMigrationAttributeMissingWarning(IDiagn return (EventDefinition)definition; } + /// + /// A transaction was started before applying migrations. This prevents a database lock to be acquired and hence the database will not be protected from concurrent migration applications. The transactions and execution strategy are already managed by EF as needed. Remove the external transaction. + /// + public static EventDefinition LogMigrationsUserTransaction(IDiagnosticsLogger logger) + { + var definition = ((RelationalLoggingDefinitions)logger.Definitions).LogMigrationsUserTransactionWarning; + if (definition == null) + { + definition = NonCapturingLazyInitializer.EnsureInitialized( + ref ((RelationalLoggingDefinitions)logger.Definitions).LogMigrationsUserTransactionWarning, + logger, + static logger => new EventDefinition( + logger.Options, + RelationalEventId.MigrationsUserTransactionWarning, + LogLevel.Warning, + "RelationalEventId.MigrationsUserTransactionWarning", + level => LoggerMessage.Define( + level, + RelationalEventId.MigrationsUserTransactionWarning, + _resourceManager.GetString("LogMigrationsUserTransaction")!))); + } + + return (EventDefinition)definition; + } + /// /// Compiling a query which loads related collections for more than one collection navigation, either via 'Include' or through projection, but no 'QuerySplittingBehavior' has been configured. By default, Entity Framework will use 'QuerySplittingBehavior.SingleQuery', which can potentially result in slow query performance. See https://go.microsoft.com/fwlink/?linkid=2134277 for more information. To identify the query that's triggering this warning call 'ConfigureWarnings(w => w.Throw(RelationalEventId.MultipleCollectionIncludeWarning))'. /// diff --git a/src/EFCore.Relational/Properties/RelationalStrings.resx b/src/EFCore.Relational/Properties/RelationalStrings.resx index 7099418d2e3..19d3cc3c5c5 100644 --- a/src/EFCore.Relational/Properties/RelationalStrings.resx +++ b/src/EFCore.Relational/Properties/RelationalStrings.resx @@ -187,6 +187,12 @@ Conflicting type mappings were inferred for column '{column}'. + + The entity type '{entityType}' has a container column type configured, but is nested in another owned type. The container column type can only be specified on a top-level owned type mapped to a container. + + + The entity type '{entityType}' has a container column type configured, but is not mapped to a container column, such as for JSON. The container column type can only be specified on a top-level owned type mapped to a container. + {numSortOrderProperties} values were provided in CreateIndexOperations.IsDescending, but the operation has {numColumns} columns. @@ -412,6 +418,9 @@ The operation '{operation}' is being applied on entity type '{entityType}', which is using the TPT mapping strategy. 'ExecuteDelete'/'ExecuteUpdate' operations on hierarchies mapped as TPT is not supported. + + ExecuteUpdate or ExecuteDelete was called on entity type '{entityType}', but that entity type is not mapped to a table. + The operation '{operation}' contains a select expression feature that isn't supported in the query SQL generator, but has been declared as supported by provider during translation phase. This is a bug in your EF Core provider, please file an issue. @@ -514,6 +523,9 @@ Can't navigate from JSON-mapped entity '{jsonEntity}' to its parent entity '{parentEntity}' using navigation '{navigation}'. Entities mapped to JSON can only navigate to their children. + + The database returned the empty string when a JSON object was expected. + Entity '{jsonType}' is mapped to JSON and also to a table or view '{tableOrViewName}', but its owner '{ownerType}' is mapped to a different table or view '{ownerTableOrViewName}'. Every entity mapped to JSON must also map to the same table or view as its owner. @@ -538,8 +550,8 @@ Key property '{keyProperty}' on JSON-mapped entity '{jsonEntity}' should not have its JSON property name configured explicitly. - - Entity type '{jsonEntity}' is part of a collection mapped to JSON and has its ordinal key defined explicitly. Only implicitly defined ordinal keys are supported. + + The property '{entityType}.{property}' is configured as part of the primary key. Explicitly configured primary keys are not supported on entities stored in JSON collections, and any key configuration should be removed. Entity type '{jsonEntity}' has an incorrect number of primary key properties. Expected number is: {expectedCount}, actual number is: {actualCount}. @@ -589,6 +601,10 @@ Queries performing '{method}' operation must have a deterministic sort order. Rewrite the query to apply an 'OrderBy' operation on the sequence before calling '{method}'. + + Acquiring an exclusive lock for migration application. See https://aka.ms/efcore-docs-migrations-lock for more information if this takes too long. + Information RelationalEventId.AcquiringMigrationLock + An ambient transaction has been detected, but the current provider does not support ambient transactions. See https://go.microsoft.com/fwlink/?LinkId=800142 Warning RelationalEventId.AmbientTransactionWarning @@ -773,6 +789,10 @@ A [Migration] attribute isn't specified on the '{class}' class. Warning RelationalEventId.MigrationAttributeMissingWarning string + + A transaction was started before applying migrations. This prevents a database lock to be acquired and hence the database will not be protected from concurrent migration applications. The transactions and execution strategy are already managed by EF as needed. Remove the external transaction. + Warning RelationalEventId.MigrationsUserTransactionWarning + Compiling a query which loads related collections for more than one collection navigation, either via 'Include' or through projection, but no 'QuerySplittingBehavior' has been configured. By default, Entity Framework will use 'QuerySplittingBehavior.SingleQuery', which can potentially result in slow query performance. See https://go.microsoft.com/fwlink/?linkid=2134277 for more information. To identify the query that's triggering this warning call 'ConfigureWarnings(w => w.Throw(RelationalEventId.MultipleCollectionIncludeWarning))'. Warning RelationalEventId.MultipleCollectionIncludeWarning diff --git a/src/EFCore.Relational/Query/EnumerableExpression.cs b/src/EFCore.Relational/Query/EnumerableExpression.cs index a038c641d9f..48129ceb986 100644 --- a/src/EFCore.Relational/Query/EnumerableExpression.cs +++ b/src/EFCore.Relational/Query/EnumerableExpression.cs @@ -68,11 +68,12 @@ public virtual EnumerableExpression ApplySelector(Expression expression) => new(expression, IsDistinct, Predicate, Orderings); /// - /// Applies DISTINCT operator to the selector of the . + /// Sets whether the DISTINCT operator should be applied to the selector + /// of the . /// /// The new expression with specified component updated. - public virtual EnumerableExpression ApplyDistinct() - => new(Selector, distinct: true, Predicate, Orderings); + public virtual EnumerableExpression SetDistinct(bool value) + => new(Selector, distinct: value, Predicate, Orderings); /// /// Applies filter predicate to the . diff --git a/src/EFCore.Relational/Query/Internal/BufferedDataReader.cs b/src/EFCore.Relational/Query/Internal/BufferedDataReader.cs index e198a07c3c7..c6f464153ca 100644 --- a/src/EFCore.Relational/Query/Internal/BufferedDataReader.cs +++ b/src/EFCore.Relational/Query/Internal/BufferedDataReader.cs @@ -836,7 +836,8 @@ public ulong GetUInt64(int ordinal) public object GetValue(int ordinal) => GetFieldValue(ordinal); - public static int GetValues(object[] values) => throw new NotSupportedException(); + public static int GetValues(object[] values) + => throw new NotSupportedException(); public T GetFieldValue(int ordinal) => (_columnTypeCases[ordinal]) switch diff --git a/src/EFCore.Relational/Query/Internal/QuerySqlGeneratorFactory.cs b/src/EFCore.Relational/Query/Internal/QuerySqlGeneratorFactory.cs index 09774b492dd..b70f6aa61d4 100644 --- a/src/EFCore.Relational/Query/Internal/QuerySqlGeneratorFactory.cs +++ b/src/EFCore.Relational/Query/Internal/QuerySqlGeneratorFactory.cs @@ -18,9 +18,7 @@ public class QuerySqlGeneratorFactory : IQuerySqlGeneratorFactory /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public QuerySqlGeneratorFactory(QuerySqlGeneratorDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Relational provider-specific dependencies for this service. diff --git a/src/EFCore.Relational/Query/Internal/QueryableAggregateMethodTranslator.cs b/src/EFCore.Relational/Query/Internal/QueryableAggregateMethodTranslator.cs index cb3a659d2c9..da0acde1d53 100644 --- a/src/EFCore.Relational/Query/Internal/QueryableAggregateMethodTranslator.cs +++ b/src/EFCore.Relational/Query/Internal/QueryableAggregateMethodTranslator.cs @@ -22,9 +22,7 @@ public class QueryableAggregateMethodTranslator : IAggregateMethodCallTranslator /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public QueryableAggregateMethodTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Relational/Query/Internal/RelationalCommandCache.cs b/src/EFCore.Relational/Query/Internal/RelationalCommandCache.cs index 19a8c30bdb3..b8729a4cedf 100644 --- a/src/EFCore.Relational/Query/Internal/RelationalCommandCache.cs +++ b/src/EFCore.Relational/Query/Internal/RelationalCommandCache.cs @@ -36,12 +36,13 @@ public RelationalCommandCache( IRelationalParameterBasedSqlProcessorFactory relationalParameterBasedSqlProcessorFactory, Expression queryExpression, bool useRelationalNulls, - HashSet parametersToConstantize) + IReadOnlySet parametersToConstantize) { _memoryCache = memoryCache; _querySqlGeneratorFactory = querySqlGeneratorFactory; _queryExpression = queryExpression; - _relationalParameterBasedSqlProcessor = relationalParameterBasedSqlProcessorFactory.Create(new RelationalParameterBasedSqlProcessorParameters(useRelationalNulls, parametersToConstantize)); + _relationalParameterBasedSqlProcessor = relationalParameterBasedSqlProcessorFactory.Create( + new RelationalParameterBasedSqlProcessorParameters(useRelationalNulls, parametersToConstantize)); } /// diff --git a/src/EFCore.Relational/Query/Internal/RelationalParameterBasedSqlProcessorFactory.cs b/src/EFCore.Relational/Query/Internal/RelationalParameterBasedSqlProcessorFactory.cs index ece419ebaf1..13bd38c7582 100644 --- a/src/EFCore.Relational/Query/Internal/RelationalParameterBasedSqlProcessorFactory.cs +++ b/src/EFCore.Relational/Query/Internal/RelationalParameterBasedSqlProcessorFactory.cs @@ -19,9 +19,7 @@ public class RelationalParameterBasedSqlProcessorFactory : IRelationalParameterB /// public RelationalParameterBasedSqlProcessorFactory( RelationalParameterBasedSqlProcessorDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Relational provider-specific dependencies for this service. diff --git a/src/EFCore.Relational/Query/Internal/RelationalQueryCompilationContextFactory.cs b/src/EFCore.Relational/Query/Internal/RelationalQueryCompilationContextFactory.cs index 25d329bc8b3..3528e534c1d 100644 --- a/src/EFCore.Relational/Query/Internal/RelationalQueryCompilationContextFactory.cs +++ b/src/EFCore.Relational/Query/Internal/RelationalQueryCompilationContextFactory.cs @@ -54,5 +54,6 @@ public virtual QueryCompilationContext Create(bool async) /// [Experimental(EFDiagnostics.PrecompiledQueryExperimental)] public virtual QueryCompilationContext CreatePrecompiled(bool async, IReadOnlySet nonNullableReferenceTypeParameters) - => new RelationalQueryCompilationContext(Dependencies, RelationalDependencies, async, precompiling: true, nonNullableReferenceTypeParameters); + => new RelationalQueryCompilationContext( + Dependencies, RelationalDependencies, async, precompiling: true, nonNullableReferenceTypeParameters); } diff --git a/src/EFCore.Relational/Query/Internal/RelationalQueryMetadataExtractingExpressionVisitor.cs b/src/EFCore.Relational/Query/Internal/RelationalQueryMetadataExtractingExpressionVisitor.cs index 072dfe7ab88..a4d8c46e020 100644 --- a/src/EFCore.Relational/Query/Internal/RelationalQueryMetadataExtractingExpressionVisitor.cs +++ b/src/EFCore.Relational/Query/Internal/RelationalQueryMetadataExtractingExpressionVisitor.cs @@ -21,9 +21,7 @@ public class RelationalQueryMetadataExtractingExpressionVisitor : ExpressionVisi /// public RelationalQueryMetadataExtractingExpressionVisitor( RelationalQueryCompilationContext relationalQueryCompilationContext) - { - _relationalQueryCompilationContext = relationalQueryCompilationContext; - } + => _relationalQueryCompilationContext = relationalQueryCompilationContext; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Relational/Query/Internal/RelationalValueConverterCompensatingExpressionVisitor.cs b/src/EFCore.Relational/Query/Internal/RelationalValueConverterCompensatingExpressionVisitor.cs index 4d3277e86ea..6fa06292acc 100644 --- a/src/EFCore.Relational/Query/Internal/RelationalValueConverterCompensatingExpressionVisitor.cs +++ b/src/EFCore.Relational/Query/Internal/RelationalValueConverterCompensatingExpressionVisitor.cs @@ -24,9 +24,7 @@ public class RelationalValueConverterCompensatingExpressionVisitor : ExpressionV /// public RelationalValueConverterCompensatingExpressionVisitor( ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Relational/Query/Internal/SelectExpressionProjectionApplyingExpressionVisitor.cs b/src/EFCore.Relational/Query/Internal/SelectExpressionProjectionApplyingExpressionVisitor.cs index 540cd18cd05..cf67eccbf89 100644 --- a/src/EFCore.Relational/Query/Internal/SelectExpressionProjectionApplyingExpressionVisitor.cs +++ b/src/EFCore.Relational/Query/Internal/SelectExpressionProjectionApplyingExpressionVisitor.cs @@ -22,9 +22,7 @@ public class SelectExpressionProjectionApplyingExpressionVisitor : ExpressionVis /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SelectExpressionProjectionApplyingExpressionVisitor(QuerySplittingBehavior? querySplittingBehavior) - { - _querySplittingBehavior = querySplittingBehavior ?? QuerySplittingBehavior.SingleQuery; - } + => _querySplittingBehavior = querySplittingBehavior ?? QuerySplittingBehavior.SingleQuery; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -40,7 +38,8 @@ protected override Expression VisitExtension(Expression extensionExpression) selectExpression.ApplyProjection( shapedQueryExpression.ShaperExpression, shapedQueryExpression.ResultCardinality, _querySplittingBehavior)), - NonQueryExpression nonQueryExpression => nonQueryExpression, + UpdateExpression update => update, + DeleteExpression delete => delete, _ => base.VisitExtension(extensionExpression), }; diff --git a/src/EFCore.Relational/Query/Internal/SingleQueryResultCoordinator.cs b/src/EFCore.Relational/Query/Internal/SingleQueryResultCoordinator.cs index efc37c2cf1f..623a5672b7e 100644 --- a/src/EFCore.Relational/Query/Internal/SingleQueryResultCoordinator.cs +++ b/src/EFCore.Relational/Query/Internal/SingleQueryResultCoordinator.cs @@ -18,9 +18,7 @@ public sealed class SingleQueryResultCoordinator /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SingleQueryResultCoordinator() - { - ResultContext = new ResultContext(); - } + => ResultContext = new ResultContext(); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Relational/Query/Internal/SplitQueryDataReaderContext.cs b/src/EFCore.Relational/Query/Internal/SplitQueryDataReaderContext.cs index a94387edbe2..7969143566c 100644 --- a/src/EFCore.Relational/Query/Internal/SplitQueryDataReaderContext.cs +++ b/src/EFCore.Relational/Query/Internal/SplitQueryDataReaderContext.cs @@ -19,9 +19,7 @@ public sealed class SplitQueryDataReaderContext /// public SplitQueryDataReaderContext( RelationalDataReader dataReader) - { - DataReader = dataReader; - } + => DataReader = dataReader; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Relational/Query/Internal/SplitQueryResultCoordinator.cs b/src/EFCore.Relational/Query/Internal/SplitQueryResultCoordinator.cs index 78c60bd3183..0e69cf3419f 100644 --- a/src/EFCore.Relational/Query/Internal/SplitQueryResultCoordinator.cs +++ b/src/EFCore.Relational/Query/Internal/SplitQueryResultCoordinator.cs @@ -18,9 +18,7 @@ public sealed class SplitQueryResultCoordinator /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SplitQueryResultCoordinator() - { - ResultContext = new ResultContext(); - } + => ResultContext = new ResultContext(); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Relational/Query/Internal/TpcTablesExpression.cs b/src/EFCore.Relational/Query/Internal/TpcTablesExpression.cs index 834a14e080a..00a30da2122 100644 --- a/src/EFCore.Relational/Query/Internal/TpcTablesExpression.cs +++ b/src/EFCore.Relational/Query/Internal/TpcTablesExpression.cs @@ -122,7 +122,7 @@ protected override Expression VisitChildren(ExpressionVisitor visitor) var visitedColumn = (ColumnExpression)visitor.Visit(DiscriminatorColumn); return visitedColumn == DiscriminatorColumn ? this - : new(Alias, EntityType, SelectExpressions, visitedColumn, DiscriminatorValues, Annotations); + : new TpcTablesExpression(Alias, EntityType, SelectExpressions, visitedColumn, DiscriminatorValues, Annotations); } /// diff --git a/src/EFCore.Relational/Query/Internal/Translators/ByteArraySequenceEqualTranslator.cs b/src/EFCore.Relational/Query/Internal/Translators/ByteArraySequenceEqualTranslator.cs index e8bb824ea65..45cb358e4f3 100644 --- a/src/EFCore.Relational/Query/Internal/Translators/ByteArraySequenceEqualTranslator.cs +++ b/src/EFCore.Relational/Query/Internal/Translators/ByteArraySequenceEqualTranslator.cs @@ -23,9 +23,7 @@ public class ByteArraySequenceEqualTranslator : IMethodCallTranslator /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public ByteArraySequenceEqualTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Relational/Query/Internal/Translators/ComparisonTranslator.cs b/src/EFCore.Relational/Query/Internal/Translators/ComparisonTranslator.cs index 5e6b784bbe9..718ac057cd3 100644 --- a/src/EFCore.Relational/Query/Internal/Translators/ComparisonTranslator.cs +++ b/src/EFCore.Relational/Query/Internal/Translators/ComparisonTranslator.cs @@ -23,9 +23,7 @@ public class ComparisonTranslator : IMethodCallTranslator /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public ComparisonTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Relational/Query/Internal/Translators/ContainsTranslator.cs b/src/EFCore.Relational/Query/Internal/Translators/ContainsTranslator.cs index 069d05a6a80..04cddb50d17 100644 --- a/src/EFCore.Relational/Query/Internal/Translators/ContainsTranslator.cs +++ b/src/EFCore.Relational/Query/Internal/Translators/ContainsTranslator.cs @@ -24,9 +24,7 @@ public class ContainsTranslator : IMethodCallTranslator /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public ContainsTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Relational/Query/Internal/Translators/EnumMethodTranslator.cs b/src/EFCore.Relational/Query/Internal/Translators/EnumMethodTranslator.cs index d1cdfd4b487..2911a5a33d2 100644 --- a/src/EFCore.Relational/Query/Internal/Translators/EnumMethodTranslator.cs +++ b/src/EFCore.Relational/Query/Internal/Translators/EnumMethodTranslator.cs @@ -29,9 +29,7 @@ private static readonly MethodInfo ToStringMethodInfo /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public EnumMethodTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -63,9 +61,10 @@ public EnumMethodTranslator(ISqlExpressionFactory sqlExpressionFactory) case not null when converterType.GetGenericTypeDefinition() == typeof(EnumToNumberConverter<,>): var whenClauses = Enum.GetValues(instance.Type) .Cast() - .Select(value => new CaseWhenClause( - _sqlExpressionFactory.Constant(value), - _sqlExpressionFactory.Constant(value.ToString(), typeof(string)))) + .Select( + value => new CaseWhenClause( + _sqlExpressionFactory.Constant(value), + _sqlExpressionFactory.Constant(value.ToString(), typeof(string)))) .ToArray(); var elseResult = _sqlExpressionFactory.Coalesce( diff --git a/src/EFCore.Relational/Query/Internal/Translators/EqualsTranslator.cs b/src/EFCore.Relational/Query/Internal/Translators/EqualsTranslator.cs index 6061dc8f5e3..524ee978349 100644 --- a/src/EFCore.Relational/Query/Internal/Translators/EqualsTranslator.cs +++ b/src/EFCore.Relational/Query/Internal/Translators/EqualsTranslator.cs @@ -23,9 +23,7 @@ public class EqualsTranslator : IMethodCallTranslator /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public EqualsTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Relational/Query/Internal/Translators/GetValueOrDefaultTranslator.cs b/src/EFCore.Relational/Query/Internal/Translators/GetValueOrDefaultTranslator.cs index 7d926a1a55c..4ff9d6b80af 100644 --- a/src/EFCore.Relational/Query/Internal/Translators/GetValueOrDefaultTranslator.cs +++ b/src/EFCore.Relational/Query/Internal/Translators/GetValueOrDefaultTranslator.cs @@ -23,9 +23,7 @@ public class GetValueOrDefaultTranslator : IMethodCallTranslator /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public GetValueOrDefaultTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Relational/Query/Internal/Translators/LikeTranslator.cs b/src/EFCore.Relational/Query/Internal/Translators/LikeTranslator.cs index 7cc82929101..13e52bcd8ef 100644 --- a/src/EFCore.Relational/Query/Internal/Translators/LikeTranslator.cs +++ b/src/EFCore.Relational/Query/Internal/Translators/LikeTranslator.cs @@ -31,9 +31,7 @@ private static readonly MethodInfo MethodInfoWithEscape /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public LikeTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Relational/Query/Internal/Translators/RandomTranslator.cs b/src/EFCore.Relational/Query/Internal/Translators/RandomTranslator.cs index ccae9804087..186975efc8a 100644 --- a/src/EFCore.Relational/Query/Internal/Translators/RandomTranslator.cs +++ b/src/EFCore.Relational/Query/Internal/Translators/RandomTranslator.cs @@ -26,9 +26,7 @@ public class RandomTranslator : IMethodCallTranslator /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public RandomTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Relational/Query/Internal/Translators/StringMethodTranslator.cs b/src/EFCore.Relational/Query/Internal/Translators/StringMethodTranslator.cs index 3b62a210783..7181d61b31a 100644 --- a/src/EFCore.Relational/Query/Internal/Translators/StringMethodTranslator.cs +++ b/src/EFCore.Relational/Query/Internal/Translators/StringMethodTranslator.cs @@ -36,9 +36,7 @@ private static readonly MethodInfo ConcatMethodInfoFourArgs /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public StringMethodTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Relational/Query/NonQueryExpression.cs b/src/EFCore.Relational/Query/NonQueryExpression.cs deleted file mode 100644 index 2f72740957d..00000000000 --- a/src/EFCore.Relational/Query/NonQueryExpression.cs +++ /dev/null @@ -1,108 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.EntityFrameworkCore.Query.SqlExpressions; - -namespace Microsoft.EntityFrameworkCore.Query; - -/// -/// -/// An expression that contains a non-query expression. The result of a non-query expression is typically the number of rows affected. -/// -/// -/// This type is typically used by database providers (and other extensions). It is generally not used in application code. -/// -/// -/// -/// See Implementation of database providers and extensions -/// and How EF Core queries work for more information and examples. -/// -public class NonQueryExpression : Expression, IPrintableExpression -{ - /// - /// Creates a new instance of the class with associated query expression and command source. - /// - /// The expression to affect rows on the server. - /// The command source to use for this non-query operation. - public NonQueryExpression(Expression expression, CommandSource commandSource) - { - Expression = expression; - CommandSource = commandSource; - } - - /// - /// Creates a new instance of the class with associated delete expression. - /// - /// The delete expression to delete rows on the server. - public NonQueryExpression(DeleteExpression deleteExpression) - : this(deleteExpression, CommandSource.ExecuteDelete) - { - } - - /// - /// Creates a new instance of the class with associated update expression. - /// - /// The update expression to update rows on the server. - public NonQueryExpression(UpdateExpression updateExpression) - : this(updateExpression, CommandSource.ExecuteUpdate) - { - } - - /// - /// An expression representing the non-query operation to be run against server. - /// - public virtual Expression Expression { get; } - - /// - /// The command source to use for this non-query operation. - /// - public virtual CommandSource CommandSource { get; } - - /// - public override Type Type - => typeof(int); - - /// - public sealed override ExpressionType NodeType - => ExpressionType.Extension; - - /// - protected override Expression VisitChildren(ExpressionVisitor visitor) - { - var expression = visitor.Visit(Expression); - - return Update(expression); - } - - /// - /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will - /// return this expression. - /// - /// The property of the result. - /// This expression if no children changed, or an expression with the updated children. - public virtual NonQueryExpression Update(Expression expression) - => expression != Expression - ? new NonQueryExpression(expression, CommandSource) - : this; - - /// - public virtual void Print(ExpressionPrinter expressionPrinter) - { - expressionPrinter.Append($"({nameof(NonQueryExpression)}: "); - expressionPrinter.Visit(Expression); - } - - /// - public override bool Equals(object? obj) - => obj != null - && (ReferenceEquals(this, obj) - || obj is NonQueryExpression nonQueryExpression - && Equals(nonQueryExpression)); - - private bool Equals(NonQueryExpression nonQueryExpression) - => Expression == nonQueryExpression.Expression; - - /// - public override int GetHashCode() - => Expression.GetHashCode(); -} diff --git a/src/EFCore.Relational/Query/RelationalCompiledQueryCacheKeyGenerator.cs b/src/EFCore.Relational/Query/RelationalCompiledQueryCacheKeyGenerator.cs index b193a826cd4..34f1571ec13 100644 --- a/src/EFCore.Relational/Query/RelationalCompiledQueryCacheKeyGenerator.cs +++ b/src/EFCore.Relational/Query/RelationalCompiledQueryCacheKeyGenerator.cs @@ -15,9 +15,7 @@ public RelationalCompiledQueryCacheKeyGenerator( CompiledQueryCacheKeyGeneratorDependencies dependencies, RelationalCompiledQueryCacheKeyGeneratorDependencies relationalDependencies) : base(dependencies) - { - RelationalDependencies = relationalDependencies; - } + => RelationalDependencies = relationalDependencies; /// /// Relational provider-specific dependencies for this service. diff --git a/src/EFCore.Relational/Query/RelationalCompiledQueryCacheKeyGeneratorDependencies.cs b/src/EFCore.Relational/Query/RelationalCompiledQueryCacheKeyGeneratorDependencies.cs index cdae2325689..48fb9ec71b2 100644 --- a/src/EFCore.Relational/Query/RelationalCompiledQueryCacheKeyGeneratorDependencies.cs +++ b/src/EFCore.Relational/Query/RelationalCompiledQueryCacheKeyGeneratorDependencies.cs @@ -46,9 +46,7 @@ public sealed record RelationalCompiledQueryCacheKeyGeneratorDependencies /// [EntityFrameworkInternal] public RelationalCompiledQueryCacheKeyGeneratorDependencies(IDbContextOptions contextOptions) - { - ContextOptions = contextOptions; - } + => ContextOptions = contextOptions; /// /// Options for the current instance. diff --git a/src/EFCore.Relational/Query/RelationalEvaluatableExpressionFilter.cs b/src/EFCore.Relational/Query/RelationalEvaluatableExpressionFilter.cs index 29df9899207..91810a03cdb 100644 --- a/src/EFCore.Relational/Query/RelationalEvaluatableExpressionFilter.cs +++ b/src/EFCore.Relational/Query/RelationalEvaluatableExpressionFilter.cs @@ -21,9 +21,7 @@ public RelationalEvaluatableExpressionFilter( EvaluatableExpressionFilterDependencies dependencies, RelationalEvaluatableExpressionFilterDependencies relationalDependencies) : base(dependencies) - { - RelationalDependencies = relationalDependencies; - } + => RelationalDependencies = relationalDependencies; /// /// Relational provider-specific dependencies for this service. diff --git a/src/EFCore.Relational/Query/RelationalExpressionQuotingUtilities.cs b/src/EFCore.Relational/Query/RelationalExpressionQuotingUtilities.cs index 58eaafd3a9f..3a53643f098 100644 --- a/src/EFCore.Relational/Query/RelationalExpressionQuotingUtilities.cs +++ b/src/EFCore.Relational/Query/RelationalExpressionQuotingUtilities.cs @@ -16,6 +16,7 @@ public static class RelationalExpressionQuotingUtilities { private static readonly ParameterExpression RelationalModelParameter = Parameter(typeof(RelationalModel), "relationalModel"); + private static readonly ParameterExpression RelationalTypeMappingSourceParameter = Parameter(typeof(RelationalTypeMappingSource), "relationalTypeMappingSource"); @@ -53,7 +54,8 @@ private static readonly MethodInfo RelationalTypeMappingSourceFindMappingMethod /// If is , returns a with a /// value. Otherwise, calls and returns the result. /// - public static Expression QuoteOrNull(T? expression) where T : IRelationalQuotableExpression + public static Expression QuoteOrNull(T? expression) + where T : IRelationalQuotableExpression => expression is null ? Constant(null, typeof(T)) : expression.Quote(); /// diff --git a/src/EFCore.Relational/Query/RelationalGroupByShaperExpression.cs b/src/EFCore.Relational/Query/RelationalGroupByShaperExpression.cs index fe752b73483..98977f2c0a5 100644 --- a/src/EFCore.Relational/Query/RelationalGroupByShaperExpression.cs +++ b/src/EFCore.Relational/Query/RelationalGroupByShaperExpression.cs @@ -26,9 +26,7 @@ public RelationalGroupByShaperExpression( Expression elementSelector, ShapedQueryExpression groupingEnumerable) : base(keySelector, groupingEnumerable) - { - ElementSelector = elementSelector; - } + => ElementSelector = elementSelector; /// /// The expression representing the element selector for this grouping result. diff --git a/src/EFCore.Relational/Query/RelationalLiftableConstantFactory.cs b/src/EFCore.Relational/Query/RelationalLiftableConstantFactory.cs index d2d1155fe92..61739b1bee8 100644 --- a/src/EFCore.Relational/Query/RelationalLiftableConstantFactory.cs +++ b/src/EFCore.Relational/Query/RelationalLiftableConstantFactory.cs @@ -14,7 +14,8 @@ namespace Microsoft.EntityFrameworkCore.Query; [Experimental(EFDiagnostics.PrecompiledQueryExperimental)] public class RelationalLiftableConstantFactory( LiftableConstantExpressionDependencies dependencies, - RelationalLiftableConstantExpressionDependencies relationalDependencies) : LiftableConstantFactory(dependencies), IRelationalLiftableConstantFactory + RelationalLiftableConstantExpressionDependencies relationalDependencies) + : LiftableConstantFactory(dependencies), IRelationalLiftableConstantFactory { /// /// This is an experimental API used by the Entity Framework Core feature and it is not subject to diff --git a/src/EFCore.Relational/Query/RelationalLiftableConstantProcessor.cs b/src/EFCore.Relational/Query/RelationalLiftableConstantProcessor.cs index adbccbefe6d..2d0b9fa8c0c 100644 --- a/src/EFCore.Relational/Query/RelationalLiftableConstantProcessor.cs +++ b/src/EFCore.Relational/Query/RelationalLiftableConstantProcessor.cs @@ -27,9 +27,10 @@ public RelationalLiftableConstantProcessor( RelationalShapedQueryCompilingExpressionVisitorDependencies relationalDependencies, RelationalCommandBuilderDependencies commandBuilderDependencies) : base(dependencies) - => _relationalMaterializerLiftableConstantContext = new(dependencies, relationalDependencies, commandBuilderDependencies); + => _relationalMaterializerLiftableConstantContext = new RelationalMaterializerLiftableConstantContext( + dependencies, relationalDependencies, commandBuilderDependencies); - /// + /// protected override ConstantExpression InlineConstant(LiftableConstantExpression liftableConstant) { if (liftableConstant.ResolverExpression is Expression> diff --git a/src/EFCore.Relational/Query/RelationalMaterializerLiftableConstantContext.cs b/src/EFCore.Relational/Query/RelationalMaterializerLiftableConstantContext.cs index 9b7227cd841..f49f391b9bf 100644 --- a/src/EFCore.Relational/Query/RelationalMaterializerLiftableConstantContext.cs +++ b/src/EFCore.Relational/Query/RelationalMaterializerLiftableConstantContext.cs @@ -13,7 +13,7 @@ namespace Microsoft.EntityFrameworkCore.Query; /// [Experimental(EFDiagnostics.PrecompiledQueryExperimental)] public record RelationalMaterializerLiftableConstantContext( - ShapedQueryCompilingExpressionVisitorDependencies Dependencies, - RelationalShapedQueryCompilingExpressionVisitorDependencies RelationalDependencies, - RelationalCommandBuilderDependencies CommandBuilderDependencies) + ShapedQueryCompilingExpressionVisitorDependencies Dependencies, + RelationalShapedQueryCompilingExpressionVisitorDependencies RelationalDependencies, + RelationalCommandBuilderDependencies CommandBuilderDependencies) : MaterializerLiftableConstantContext(Dependencies); diff --git a/src/EFCore.Relational/Query/RelationalParameterBasedSqlProcessorParameters.cs b/src/EFCore.Relational/Query/RelationalParameterBasedSqlProcessorParameters.cs index bbd689d9ab9..efbe9d7416f 100644 --- a/src/EFCore.Relational/Query/RelationalParameterBasedSqlProcessorParameters.cs +++ b/src/EFCore.Relational/Query/RelationalParameterBasedSqlProcessorParameters.cs @@ -4,27 +4,27 @@ namespace Microsoft.EntityFrameworkCore.Query; /// -/// Parameters for . +/// Parameters for . /// public sealed record RelationalParameterBasedSqlProcessorParameters { /// - /// A value indicating if relational nulls should be used. + /// A value indicating if relational nulls should be used. /// public bool UseRelationalNulls { get; init; } /// - /// A collection of parameter names to constantize. + /// A collection of parameter names to constantize. /// - public HashSet ParametersToConstantize { get; init; } + public IReadOnlySet ParametersToConstantize { get; init; } /// - /// Creates a new instance of . + /// Creates a new instance of . /// /// A value indicating if relational nulls should be used. /// A collection of parameter names to constantize. [EntityFrameworkInternal] - public RelationalParameterBasedSqlProcessorParameters(bool useRelationalNulls, HashSet parametersToConstantize) + public RelationalParameterBasedSqlProcessorParameters(bool useRelationalNulls, IReadOnlySet parametersToConstantize) { UseRelationalNulls = useRelationalNulls; ParametersToConstantize = parametersToConstantize; diff --git a/src/EFCore.Relational/Query/RelationalQueryCompilationContextDependencies.cs b/src/EFCore.Relational/Query/RelationalQueryCompilationContextDependencies.cs index afecb979d90..5c55a9944a9 100644 --- a/src/EFCore.Relational/Query/RelationalQueryCompilationContextDependencies.cs +++ b/src/EFCore.Relational/Query/RelationalQueryCompilationContextDependencies.cs @@ -1,8 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.EntityFrameworkCore.Query.Internal; - namespace Microsoft.EntityFrameworkCore.Query; /// diff --git a/src/EFCore.Relational/Query/RelationalQueryContext.cs b/src/EFCore.Relational/Query/RelationalQueryContext.cs index 16de8fb6f48..a2870e75bd6 100644 --- a/src/EFCore.Relational/Query/RelationalQueryContext.cs +++ b/src/EFCore.Relational/Query/RelationalQueryContext.cs @@ -29,9 +29,7 @@ public RelationalQueryContext( QueryContextDependencies dependencies, RelationalQueryContextDependencies relationalDependencies) : base(dependencies) - { - RelationalDependencies = relationalDependencies; - } + => RelationalDependencies = relationalDependencies; /// /// Relational provider-specific dependencies for this service. diff --git a/src/EFCore.Relational/Query/RelationalQueryRootProcessor.cs b/src/EFCore.Relational/Query/RelationalQueryRootProcessor.cs index a9449c4411b..09f740ccab7 100644 --- a/src/EFCore.Relational/Query/RelationalQueryRootProcessor.cs +++ b/src/EFCore.Relational/Query/RelationalQueryRootProcessor.cs @@ -22,9 +22,7 @@ public RelationalQueryRootProcessor( RelationalQueryTranslationPreprocessorDependencies relationalDependencies, QueryCompilationContext queryCompilationContext) : base(dependencies, queryCompilationContext) - { - _model = queryCompilationContext.Model; - } + => _model = queryCompilationContext.Model; /// /// Indicates that a can be converted to a ; diff --git a/src/EFCore.Relational/Query/RelationalQueryTranslationPostprocessor.cs b/src/EFCore.Relational/Query/RelationalQueryTranslationPostprocessor.cs index 9589eaaa041..c42f16f0fa1 100644 --- a/src/EFCore.Relational/Query/RelationalQueryTranslationPostprocessor.cs +++ b/src/EFCore.Relational/Query/RelationalQueryTranslationPostprocessor.cs @@ -48,7 +48,7 @@ public override Expression Process(Expression query) var afterBase = base.Process(query); var afterTypeMappings = ProcessTypeMappings(afterBase); var afterProjectionApplication = new SelectExpressionProjectionApplyingExpressionVisitor( - ((RelationalQueryCompilationContext)QueryCompilationContext).QuerySplittingBehavior) + ((RelationalQueryCompilationContext)QueryCompilationContext).QuerySplittingBehavior) .Visit(afterTypeMappings); var afterPruning = Prune(afterProjectionApplication); @@ -76,11 +76,12 @@ public override Expression Process(Expression query) /// /// The query expression to process. protected virtual Expression ProcessTypeMappings(Expression expression) - => new RelationalTypeMappingPostprocessor(Dependencies, RelationalDependencies, RelationalQueryCompilationContext).Process(expression); + => new RelationalTypeMappingPostprocessor(Dependencies, RelationalDependencies, RelationalQueryCompilationContext).Process( + expression); /// - /// Prunes unnecessary objects from the SQL tree, e.g. tables which aren't referenced by any column. - /// Can be overridden by providers for provider-specific pruning. + /// Prunes unnecessary objects from the SQL tree, e.g. tables which aren't referenced by any column. + /// Can be overridden by providers for provider-specific pruning. /// protected virtual Expression Prune(Expression query) => _pruner.Prune(query); diff --git a/src/EFCore.Relational/Query/RelationalQueryTranslationPreprocessorDependencies.cs b/src/EFCore.Relational/Query/RelationalQueryTranslationPreprocessorDependencies.cs index 6bd82bdce6a..6bcd9d6f1b0 100644 --- a/src/EFCore.Relational/Query/RelationalQueryTranslationPreprocessorDependencies.cs +++ b/src/EFCore.Relational/Query/RelationalQueryTranslationPreprocessorDependencies.cs @@ -46,9 +46,7 @@ public sealed record RelationalQueryTranslationPreprocessorDependencies /// [EntityFrameworkInternal] public RelationalQueryTranslationPreprocessorDependencies(IRelationalTypeMappingSource relationalTypeMappingSource) - { - RelationalTypeMappingSource = relationalTypeMappingSource; - } + => RelationalTypeMappingSource = relationalTypeMappingSource; /// /// The type mapping source. diff --git a/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.CreateSelect.cs b/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.CreateSelect.cs index bf3117141e9..502b716f498 100644 --- a/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.CreateSelect.cs +++ b/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.CreateSelect.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Query.Internal; using Microsoft.EntityFrameworkCore.Query.SqlExpressions; @@ -204,7 +203,7 @@ [new TableExpression(alias, table)], var declaringEntityType = property.DeclaringType.ContainingEntityType; var projection = declaringEntityType.IsAssignableFrom(concreteEntityType) ? CreateColumnExpression(property, table, tableAlias, declaringEntityType != entityType) - : (SqlExpression)_sqlExpressionFactory.Constant( + : _sqlExpressionFactory.Constant( null, property.ClrType.MakeNullable(), property.GetRelationalTypeMapping()); projections.Add(new ProjectionExpression(projection, propertyNames[j])); } @@ -409,15 +408,15 @@ private SelectExpression CreateSelect(IEntityType entityType, TableExpressionBas } /*** - * We need to add additional conditions on basic SelectExpression for certain cases - * - If we are selecting from TPH then we need to add condition for discriminator if mapping is incomplete - * - When we are selecting optional dependent sharing table, we need to add condition to figure out existence - * ** Optional Dependent ** - * - Only root type can be the dependent - * - Dependents will have a non-principal-non-PK-shared required property - * - Principal can be any type in TPH/TPT or leaf type in TPC - * - Dependent side can be TPH or TPT but not TPC - ***/ + * We need to add additional conditions on basic SelectExpression for certain cases + * - If we are selecting from TPH then we need to add condition for discriminator if mapping is incomplete + * - When we are selecting optional dependent sharing table, we need to add condition to figure out existence + * ** Optional Dependent ** + * - Only root type can be the dependent + * - Dependents will have a non-principal-non-PK-shared required property + * - Principal can be any type in TPH/TPT or leaf type in TPC + * - Dependent side can be TPH or TPT but not TPC + ***/ private void AddEntitySelectConditions(SelectExpression selectExpression, IEntityType entityType) { // First add condition for discriminator mapping @@ -689,7 +688,8 @@ private static ColumnExpression CreateColumnExpression( IColumnBase column, string tableAlias, bool nullable) - => new(column.Name, + => new( + column.Name, tableAlias, property.ClrType.UnwrapNullableType(), column.PropertyMappings.First(m => m.Property == property).TypeMapping, diff --git a/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteDelete.cs b/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteDelete.cs index a21bdaf7ba5..5d379eace35 100644 --- a/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteDelete.cs +++ b/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteDelete.cs @@ -10,7 +10,7 @@ namespace Microsoft.EntityFrameworkCore.Query; public partial class RelationalQueryableMethodTranslatingExpressionVisitor { /// - protected override NonQueryExpression? TranslateExecuteDelete(ShapedQueryExpression source) + protected override DeleteExpression? TranslateExecuteDelete(ShapedQueryExpression source) { source = source.UpdateShaperExpression(new IncludePruner().Visit(source.ShaperExpression)); @@ -39,54 +39,87 @@ public partial class RelationalQueryableMethodTranslatingExpressionVisitor return null; } - if (entityType.GetViewOrTableMappings().Count() != 1) + // Find the table model that maps to the entity type; there must be exactly one (e.g. no entity splitting). + ITable targetTable; + switch (entityType.GetTableMappings().ToList()) { - AddTranslationErrorDetails( - RelationalStrings.ExecuteOperationOnEntitySplitting( - nameof(EntityFrameworkQueryableExtensions.ExecuteDelete), entityType.DisplayName())); - return null; + case []: + throw new InvalidOperationException( + RelationalStrings.ExecuteUpdateDeleteOnEntityNotMappedToTable(entityType.DisplayName())); + + case [var singleTableMapping]: + targetTable = singleTableMapping.Table; + break; + + default: + AddTranslationErrorDetails( + RelationalStrings.ExecuteOperationOnEntitySplitting( + nameof(EntityFrameworkQueryableExtensions.ExecuteDelete), entityType.DisplayName())); + return null; } - // First, check if the provider has a native translation for the delete represented by the select expression. - // The default relational implementation handles simple, universally-supported cases (i.e. no operators except for predicate). - // Providers may override IsValidSelectExpressionForExecuteDelete to add support for more cases via provider-specific DELETE syntax. var selectExpression = (SelectExpression)source.QueryExpression; - if (IsValidSelectExpressionForExecuteDelete(selectExpression, shaper, out var tableExpression)) + + // Find the table expression in the SelectExpression that corresponds to the projected entity type. + var projectionBindingExpression = (ProjectionBindingExpression)shaper.ValueBufferExpression; + var projection = (StructuralTypeProjectionExpression)selectExpression.GetProjection(projectionBindingExpression); + var column = projection.BindProperty(shaper.StructuralType.GetProperties().First()); + var tableExpression = selectExpression.GetTable(column, out var tableIndex); + + // If the projected table expression (the thing to be deleted) isn't a TableExpression (e.g. it's a set operation), we can't + // translate to a simple DELETE (which requires a simple target table), and must fall back to rewriting as a subquery. + if (tableExpression.UnwrapJoin() is TableExpression unwrappedTableExpression) { - if (AreOtherNonOwnedEntityTypesInTheTable(entityType.GetRootType(), tableExpression.Table)) + // In normal cases, the table expression will be refer to the same table model we found above for the entity type. + if (unwrappedTableExpression.Table is ITable) { - AddTranslationErrorDetails( - RelationalStrings.ExecuteDeleteOnTableSplitting(tableExpression.Table.SchemaQualifiedName)); - - return null; + Check.DebugAssert( + unwrappedTableExpression.Table == targetTable, + "Projected table is a table, but not the same one mapped to the entity type"); + } + else + { + // If the entity is also mapped to a view, the SelectExpression will refer to the view instead, since translation happens + // with the assumption that we're querying, not deleting. + // For this case, we must replace the TableExpression in the SelectExpression - referring to the view - with the one that + // refers to the mutable table. + Check.DebugAssert( + unwrappedTableExpression.Table.EntityTypeMappings.Any(etm => etm.TypeBase == entityType), + "Projected table is not mapped to the entity type projected by the shaper"); + + unwrappedTableExpression = new TableExpression(unwrappedTableExpression.Alias, targetTable); + tableExpression = tableExpression is JoinExpressionBase join + ? join.Update(unwrappedTableExpression) + : unwrappedTableExpression; + var newTables = selectExpression.Tables.ToList(); + newTables[tableIndex] = tableExpression; + + // Note that we need to keep the select mutable, because if IsValidSelectExpressionForExecuteDelete below returns false, + // we need to compose on top of it. + selectExpression.SetTables(newTables); } - selectExpression.ReplaceProjection(new List()); - selectExpression.ApplyProjection(); - - return new NonQueryExpression(new DeleteExpression(tableExpression, selectExpression)); - - static bool AreOtherNonOwnedEntityTypesInTheTable(IEntityType rootType, ITableBase table) + // Finally, check if the provider has a native translation for the delete represented by the select expression. + // The default relational implementation handles simple, universally-supported cases (i.e. no operators except for predicate). + // Providers may override IsValidSelectExpressionForExecuteDelete to add support for more cases via provider-specific DELETE syntax. + if (IsValidSelectExpressionForExecuteDelete(selectExpression)) { - foreach (var entityTypeMapping in table.EntityTypeMappings) + if (AreOtherNonOwnedEntityTypesInTheTable(entityType.GetRootType(), targetTable)) { - var typeBase = entityTypeMapping.TypeBase; - if ((entityTypeMapping.IsSharedTablePrincipal == true - && typeBase != rootType) - || (entityTypeMapping.IsSharedTablePrincipal == false - && typeBase is IEntityType entityType - && entityType.GetRootType() != rootType - && !entityType.IsOwned())) - { - return true; - } + AddTranslationErrorDetails( + RelationalStrings.ExecuteDeleteOnTableSplitting(unwrappedTableExpression.Table.SchemaQualifiedName)); + + return null; } - return false; + selectExpression.ReplaceProjection(new List()); + selectExpression.ApplyProjection(); + + return new DeleteExpression(unwrappedTableExpression, selectExpression); } } - // The provider doesn't natively support the delete. + // We can't translate to a simple delete (e.g. the provider doesn't support one of the clauses). // As a fallback, we place the original query in a Contains subquery, which will get translated via the regular entity equality/ // containment mechanism (InExpression for non-composite keys, Any for composite keys) var pk = entityType.FindPrimaryKey(); @@ -109,6 +142,25 @@ static bool AreOtherNonOwnedEntityTypesInTheTable(IEntityType rootType, ITableBa Expression.Quote(Expression.Lambda(predicateBody, entityParameter))); return TranslateExecuteDelete((ShapedQueryExpression)Visit(newSource)); + + static bool AreOtherNonOwnedEntityTypesInTheTable(IEntityType rootType, ITableBase table) + { + foreach (var entityTypeMapping in table.EntityTypeMappings) + { + var typeBase = entityTypeMapping.TypeBase; + if ((entityTypeMapping.IsSharedTablePrincipal == true + && typeBase != rootType) + || (entityTypeMapping.IsSharedTablePrincipal == false + && typeBase is IEntityType entityType + && entityType.GetRootType() != rootType + && !entityType.IsOwned())) + { + return true; + } + } + + return false; + } } /// @@ -126,32 +178,17 @@ static bool AreOtherNonOwnedEntityTypesInTheTable(IEntityType rootType, ITableBa /// /// /// The select expression to validate. - /// The structural type shaper expression on which the delete operation is being applied. - /// The table expression from which rows are being deleted. /// /// Returns if the current select expression can be used for delete as-is, otherwise. /// - protected virtual bool IsValidSelectExpressionForExecuteDelete( - SelectExpression selectExpression, - StructuralTypeShaperExpression shaper, - [NotNullWhen(true)] out TableExpression? tableExpression) - { - if (selectExpression is - { - Tables: [TableExpression expression], - Orderings: [], - Offset: null, - Limit: null, - GroupBy: [], - Having: null - }) + protected virtual bool IsValidSelectExpressionForExecuteDelete(SelectExpression selectExpression) + => selectExpression is { - tableExpression = expression; - - return true; - } - - tableExpression = null; - return false; - } + Tables: [TableExpression], + Orderings: [], + Offset: null, + Limit: null, + GroupBy: [], + Having: null + }; } diff --git a/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteUpdate.cs b/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteUpdate.cs index dbda2f208d3..5657fd6e6f3 100644 --- a/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteUpdate.cs +++ b/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteUpdate.cs @@ -4,6 +4,7 @@ using System.Diagnostics.CodeAnalysis; using Microsoft.EntityFrameworkCore.Query.Internal; using Microsoft.EntityFrameworkCore.Query.SqlExpressions; +using static Microsoft.EntityFrameworkCore.Query.QueryHelpers; namespace Microsoft.EntityFrameworkCore.Query; @@ -15,7 +16,7 @@ public partial class RelationalQueryableMethodTranslatingExpressionVisitor typeof(RelationalSqlTranslatingExpressionVisitor).GetTypeInfo().GetDeclaredMethod(nameof(ParameterValueExtractor))!; /// - protected override NonQueryExpression? TranslateExecuteUpdate(ShapedQueryExpression source, LambdaExpression setPropertyCalls) + protected override UpdateExpression? TranslateExecuteUpdate(ShapedQueryExpression source, LambdaExpression setPropertyCalls) { // Our source may have IncludeExpressions because of owned entities or auto-include; unwrap these, as they're meaningless for // ExecuteUpdate's lambdas. Note that we don't currently support updates across tables. @@ -61,7 +62,7 @@ public partial class RelationalQueryableMethodTranslatingExpressionVisitor selectExpression.ReplaceProjection(new List()); selectExpression.ApplyProjection(); - return new NonQueryExpression(new UpdateExpression(tableExpression, selectExpression, translatedSetters)); + return new UpdateExpression(tableExpression, selectExpression, translatedSetters); } return PushdownWithPkInnerJoinPredicate(); @@ -105,6 +106,8 @@ bool TranslateSetters( [NotNullWhen(true)] out List? translatedSetters, [NotNullWhen(true)] out TableExpressionBase? targetTable) { + var select = (SelectExpression)source.QueryExpression; + targetTable = null; string? targetTableAlias = null; var tempTranslatedSetters = new List(); @@ -118,27 +121,88 @@ bool TranslateSetters( (propertySelector, var valueSelector) = setter; var propertySelectorBody = RemapLambdaBody(source, propertySelector).UnwrapTypeConversion(out _); - switch (_sqlTranslator.TranslateProjection(propertySelectorBody)) + // The top-most node on the property selector must be a member access; chop it off to get the base expression and member. + // We'll bind the member manually below, so as to get the IPropertyBase it represents - that's important for later. + if (!IsMemberAccess(propertySelectorBody, QueryCompilationContext.Model, out var baseExpression, out var member)) + { + AddTranslationErrorDetails(RelationalStrings.InvalidPropertyInSetProperty(propertySelector.Print())); + return false; + } + + if (!_sqlTranslator.TryBindMember(_sqlTranslator.Visit(baseExpression), member, out var translatedBaseExpression, out var propertyBase)) + { + AddTranslationErrorDetails(RelationalStrings.InvalidPropertyInSetProperty(propertySelector.Print())); + return false; + } + + // Hack: when returning a StructuralTypeShaperExpression, _sqlTranslator returns it wrapped by a + // StructuralTypeReferenceExpression, which is supposed to be a private wrapper only with the SQL translator. + // Call TranslateProjection to unwrap it (need to look into getting rid StructuralTypeReferenceExpression altogether). + translatedBaseExpression = _sqlTranslator.TranslateProjection(translatedBaseExpression); + + switch (translatedBaseExpression) { case ColumnExpression column: { + if (propertyBase is not IProperty property) + { + throw new UnreachableException("Property selector translated to ColumnExpression but no IProperty"); + } + + var tableExpression = select.GetTable(column, out var tableIndex); + if (tableExpression.UnwrapJoin() is TableExpression { Table: not ITable } unwrappedTableExpression) + { + // If the entity is also mapped to a view, the SelectExpression will refer to the view instead, since + // translation happens with the assumption that we're querying, not deleting. + // For this case, we must replace the TableExpression in the SelectExpression - referring to the view - with the + // one that refers to the mutable table. + + // Get the column on the (mutable) table which corresponds to the property being set + var targetColumnModel = property.DeclaringType.GetTableMappings() + .SelectMany(tm => tm.ColumnMappings) + .Where(cm => cm.Property == property) + .Select(cm => cm.Column) + .SingleOrDefault(); + + if (targetColumnModel is null) + { + throw new InvalidOperationException( + RelationalStrings.ExecuteUpdateDeleteOnEntityNotMappedToTable(property.DeclaringType.DisplayName())); + } + + unwrappedTableExpression = new TableExpression(unwrappedTableExpression.Alias, targetColumnModel.Table); + tableExpression = tableExpression is JoinExpressionBase join + ? join.Update(unwrappedTableExpression) + : unwrappedTableExpression; + var newTables = select.Tables.ToList(); + newTables[tableIndex] = tableExpression; + + // Note that we need to keep the select mutable, because if IsValidSelectExpressionForExecuteDelete below + // returns false, we need to compose on top of it. + select.SetTables(newTables); + } + if (!IsColumnOnSameTable(column, propertySelector) || TranslateSqlSetterValueSelector(source, valueSelector, column) is not SqlExpression translatedValueSelector) { return false; } - tempTranslatedSetters.Add(new(column, translatedValueSelector)); + tempTranslatedSetters.Add(new ColumnValueSetter(column, translatedValueSelector)); break; } // TODO: This is for column flattening; implement JSON complex type support as well. case StructuralTypeShaperExpression { - StructuralType: IComplexType, + StructuralType: IComplexType complexType, ValueBufferExpression: StructuralTypeProjectionExpression } shaper: { + Check.DebugAssert( + propertyBase is IComplexProperty complexProperty && complexProperty.ComplexType == complexType, + "PropertyBase should be a complex property referring to the correct complex type"); + if (TranslateSetterValueSelector(source, valueSelector, shaper.Type) is not Expression translatedValueSelector || !TryProcessComplexType(shaper, translatedValueSelector)) { @@ -203,7 +267,7 @@ bool TryProcessComplexType(StructuralTypeShaperExpression shaperExpression, Expr return false; } - tempTranslatedSetters.Add(new(column, translatedValueSelector)); + tempTranslatedSetters.Add(new ColumnValueSetter(column, translatedValueSelector)); } foreach (var complexProperty in complexType.GetComplexProperties()) @@ -356,7 +420,7 @@ when parameter.Name.StartsWith(QueryCompilationContext.QueryParameterPrefix, Str return translatedValueSelector; } - NonQueryExpression? PushdownWithPkInnerJoinPredicate() + UpdateExpression? PushdownWithPkInnerJoinPredicate() { // The provider doesn't natively support the update. // As a fallback, we place the original query in a subquery and user an INNER JOIN on the primary key columns. @@ -373,26 +437,12 @@ when parameter.Name.StartsWith(QueryCompilationContext.QueryParameterPrefix, Str // The following mechanism for extracting the entity type from property selectors only supports simple member access, // EF.Function, etc. We also unwrap casts to interface/base class (#29618). Note that owned IncludeExpressions have already // been pruned from the source before remapping the lambda (#28727). - var firstPropertySelector = setters[0].PropertySelector; - var shaper = RemapLambdaBody(source, firstPropertySelector).UnwrapTypeConversion(out _) switch - { - MemberExpression { Expression : not null } memberExpression - when memberExpression.Expression.UnwrapTypeConversion(out _) is StructuralTypeShaperExpression s - => s, - - MethodCallExpression mce when mce.TryGetEFPropertyArguments(out var source, out _) - && source.UnwrapTypeConversion(out _) is StructuralTypeShaperExpression s - => s, - - MethodCallExpression mce when mce.TryGetIndexerArguments(RelationalDependencies.Model, out var source2, out _) - && source2.UnwrapTypeConversion(out _) is StructuralTypeShaperExpression s - => s, - - _ => null - }; - - if (shaper is null) + if (!IsMemberAccess( + RemapLambdaBody(source, firstPropertySelector).UnwrapTypeConversion(out _), + RelationalDependencies.Model, + out var baseExpression) + || baseExpression.UnwrapTypeConversion(out _) is not StructuralTypeShaperExpression shaper) { AddTranslationErrorDetails(RelationalStrings.InvalidPropertyInSetProperty(firstPropertySelector)); return null; @@ -468,26 +518,15 @@ MethodCallExpression mce when mce.TryGetIndexerArguments(RelationalDependencies. outerSelectExpression.ReplaceProjection(new List()); outerSelectExpression.ApplyProjection(); - return new NonQueryExpression(new UpdateExpression(tableExpression, outerSelectExpression, translatedSetters)); + return new UpdateExpression(tableExpression, outerSelectExpression, translatedSetters); } static Expression GetEntitySource(IModel model, Expression propertyAccessExpression) { propertyAccessExpression = propertyAccessExpression.UnwrapTypeConversion(out _); - if (propertyAccessExpression is MethodCallExpression mce) - { - if (mce.TryGetEFPropertyArguments(out var source, out _)) - { - return source; - } - - if (mce.TryGetIndexerArguments(model, out var source2, out _)) - { - return source2; - } - } - - return ((MemberExpression)propertyAccessExpression).Expression!; + return IsMemberAccess(propertyAccessExpression, model, out var source) + ? source + : ((MemberExpression)propertyAccessExpression).Expression!; } } diff --git a/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs b/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs index a98c0d070c1..b7b2657ca67 100644 --- a/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs +++ b/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs @@ -2,11 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics.CodeAnalysis; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Metadata.Internal; +using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Query.Internal; using Microsoft.EntityFrameworkCore.Query.SqlExpressions; -using Microsoft.EntityFrameworkCore.Storage; namespace Microsoft.EntityFrameworkCore.Query; @@ -242,7 +240,8 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp && method.GetGenericMethodDefinition() == QueryableMethods.Contains && methodCallExpression.Arguments[0] is ParameterQueryRootExpression parameterSource && TranslateExpression(methodCallExpression.Arguments[1]) is SqlExpression item - && _sqlTranslator.Visit(parameterSource.ParameterExpression) is SqlParameterExpression sqlParameterExpression) + && _sqlTranslator.Visit(parameterSource.ParameterExpression) is SqlParameterExpression sqlParameterExpression + && !QueryCompilationContext.ParametersToNotConstantize.Contains(sqlParameterExpression.Name)) { var inExpression = _sqlExpressionFactory.In(item, sqlParameterExpression); var selectExpression = new SelectExpression(inExpression, _sqlAliasManager); @@ -294,9 +293,13 @@ JsonScalarExpression jsonScalar Check.DebugAssert(sqlParameterExpression is not null, "sqlParameterExpression is not null"); - var tableAlias = _sqlAliasManager.GenerateTableAlias(sqlParameterExpression.Name.TrimStart('_')); + var primitiveCollectionsBehavior = RelationalOptionsExtension.Extract(QueryCompilationContext.ContextOptions) + .ParameterizedCollectionTranslationMode; - if (QueryCompilationContext.ParametersToConstantize.Contains(sqlParameterExpression.Name)) + var tableAlias = _sqlAliasManager.GenerateTableAlias(sqlParameterExpression.Name.TrimStart('_')); + if (QueryCompilationContext.ParametersToConstantize.Contains(sqlParameterExpression.Name) + || (primitiveCollectionsBehavior == ParameterizedCollectionTranslationMode.Constantize + && !QueryCompilationContext.ParametersToNotConstantize.Contains(sqlParameterExpression.Name))) { var valuesExpression = new ValuesExpression( tableAlias, @@ -411,6 +414,7 @@ sqlExpression.TypeMapping is null && inferredTypeMaping is not null : sqlExpression }); } + var alias = _sqlAliasManager.GenerateTableAlias("values"); var valuesExpression = new ValuesExpression(alias, rowExpressions, new[] { ValuesOrderingColumnName, ValuesValueColumnName }); @@ -465,6 +469,7 @@ private static ShapedQueryExpression CreateShapedQueryExpression(IEntityType ent { subquery.ClearOrdering(); } + subquery.IsDistinct = false; translation = _sqlExpressionFactory.Not(_sqlExpressionFactory.Exists(subquery)); @@ -497,6 +502,7 @@ private static ShapedQueryExpression CreateShapedQueryExpression(IEntityType ent { subquery.ClearOrdering(); } + subquery.IsDistinct = false; var translation = _sqlExpressionFactory.Exists(subquery); @@ -583,6 +589,7 @@ protected override ShapedQueryExpression TranslateConcat(ShapedQueryExpression s { subquery.ClearOrdering(); } + subquery.IsDistinct = false; subquery.ReplaceProjection(new List { projection }); @@ -947,6 +954,9 @@ private SqlExpression CreateJoinPredicate(Expression outerKey, Expression innerK /// protected override ShapedQueryExpression? TranslateMax(ShapedQueryExpression source, LambdaExpression? selector, Type resultType) { + var selectExpression = (SelectExpression)source.QueryExpression; + selectExpression.IsDistinct = false; + // For Max() over an inline array, translate to GREATEST() if possible; otherwise use the default translation of aggregate SQL // MAX(). // Note that some providers propagate NULL arguments (SQLite, MySQL), while others only return NULL if all arguments evaluate to @@ -967,6 +977,9 @@ private SqlExpression CreateJoinPredicate(Expression outerKey, Expression innerK /// protected override ShapedQueryExpression? TranslateMin(ShapedQueryExpression source, LambdaExpression? selector, Type resultType) { + var selectExpression = (SelectExpression)source.QueryExpression; + selectExpression.IsDistinct = false; + // See comments above in TranslateMax() if (TryExtractBareInlineCollectionValues(source, out var values) && _sqlTranslator.GenerateLeast(values, resultType.UnwrapNullableType()) is SqlFunctionExpression leastExpression @@ -2066,10 +2079,14 @@ private bool TryGetProjection(ShapedQueryExpression shapedQueryExpression, [NotN projection = null; return false; } + private bool TryExtractBareInlineCollectionValues(ShapedQueryExpression shapedQuery, [NotNullWhen(true)] out SqlExpression[]? values) => TryExtractBareInlineCollectionValues(shapedQuery, out values, out _); - private bool TryExtractBareInlineCollectionValues(ShapedQueryExpression shapedQuery, out SqlExpression[]? values, out SqlParameterExpression? valuesParameter) + private bool TryExtractBareInlineCollectionValues( + ShapedQueryExpression shapedQuery, + out SqlExpression[]? values, + out SqlParameterExpression? valuesParameter) { if (TryGetProjection(shapedQuery, out var projection) && shapedQuery.QueryExpression is SelectExpression @@ -2146,7 +2163,7 @@ private ShapedQueryExpression CreateShapedQueryExpressionForValuesExpression( selectExpression.AppendOrdering(new OrderingExpression(orderingColumn, ascending: true)); Expression shaperExpression = new ProjectionBindingExpression( - selectExpression, new ProjectionMember(), encounteredNull ? elementType.MakeNullable() : elementType); + selectExpression, new ProjectionMember(), encounteredNull ? elementType.MakeNullable() : elementType); if (elementType != shaperExpression.Type) { @@ -2164,6 +2181,7 @@ private ShapedQueryExpression CreateShapedQueryExpressionForValuesExpression( /// This visitor has been obsoleted; Extend RelationalTypeMappingPostprocessor instead, and invoke it from /// . /// - [Obsolete("Extend RelationalTypeMappingPostprocessor instead, and invoke it from RelationalQueryTranslationPostprocessor.ProcessTypeMappings().")] + [Obsolete( + "Extend RelationalTypeMappingPostprocessor instead, and invoke it from RelationalQueryTranslationPostprocessor.ProcessTypeMappings().")] protected class RelationalInferredTypeMappingApplier; } diff --git a/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.ClientMethods.cs b/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.ClientMethods.cs index eb13af861a1..a95f045c940 100644 --- a/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.ClientMethods.cs +++ b/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.ClientMethods.cs @@ -661,8 +661,8 @@ public static void PopulateCollection( } if (!CompareIdentifiers( - outerIdentifierValueComparers, - outerIdentifier(queryContext, dbDataReader), collectionMaterializationContext.OuterIdentifier)) + outerIdentifierValueComparers, + outerIdentifier(queryContext, dbDataReader), collectionMaterializationContext.OuterIdentifier)) { // Outer changed so collection has ended. Materialize last element. GenerateCurrentElementIfPending(); @@ -687,8 +687,8 @@ public static void PopulateCollection( if (collectionMaterializationContext.SelfIdentifier != null) { if (CompareIdentifiers( - selfIdentifierValueComparers, - innerKey, collectionMaterializationContext.SelfIdentifier)) + selfIdentifierValueComparers, + innerKey, collectionMaterializationContext.SelfIdentifier)) { // repeated row for current element // If it is pending materialization then it may have nested elements diff --git a/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.cs b/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.cs index f738b6256ad..8b5ff6bd2e2 100644 --- a/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.cs +++ b/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.cs @@ -94,10 +94,10 @@ private static readonly MethodInfo Utf8GetBytesMethod private static readonly PropertyInfo Utf8JsonReaderTokenTypeProperty = typeof(Utf8JsonReader).GetProperty(nameof(Utf8JsonReader.TokenType))!; - private readonly static MethodInfo PropertyGetJsonValueReaderWriterMethod = + private static readonly MethodInfo PropertyGetJsonValueReaderWriterMethod = typeof(IReadOnlyProperty).GetMethod(nameof(IReadOnlyProperty.GetJsonValueReaderWriter), [])!; - private readonly static MethodInfo PropertyGetTypeMappingMethod = + private static readonly MethodInfo PropertyGetTypeMappingMethod = typeof(IReadOnlyProperty).GetMethod(nameof(IReadOnlyProperty.GetTypeMapping), [])!; private readonly RelationalShapedQueryCompilingExpressionVisitor _parentVisitor; @@ -360,7 +360,8 @@ public LambdaExpression ProcessShaper( // see issue #33073 for more context if (_queryStateManager && !_isTracking && collectionId == 0) { - var jsonCorrectOrderOfEntitiesForChangeTrackerValidator = new JsonCorrectOrderOfEntitiesForChangeTrackerValidator(_selectExpression); + var jsonCorrectOrderOfEntitiesForChangeTrackerValidator = + new JsonCorrectOrderOfEntitiesForChangeTrackerValidator(_selectExpression); jsonCorrectOrderOfEntitiesForChangeTrackerValidator.Validate(shaperExpression); } @@ -457,7 +458,8 @@ public LambdaExpression ProcessShaper( relationalCommandResolver = _generateCommandResolver ? _parentVisitor.CreateRelationalCommandResolverExpression(_selectExpression) - : Constant(null, typeof(RelationalCommandCache));; + : Constant(null, typeof(RelationalCommandCache)); + ; readerColumns = _readerColumns; collectionId = _collectionId; @@ -501,16 +503,15 @@ protected override Expression VisitBinary(BinaryExpression binaryExpression) ? value : propertyMap.Values.Max() + 1; - var updatedExpression = newExpression.Update( - new[] - { + var updatedExpression = newExpression.Update( + [ _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant( - ValueBuffer.Empty, - static _ => ValueBuffer.Empty, - "emptyValueBuffer", - typeof(ValueBuffer)), - newExpression.Arguments[1] - }); + ValueBuffer.Empty, + static _ => ValueBuffer.Empty, + "emptyValueBuffer", + typeof(ValueBuffer)), + newExpression.Arguments[1] + ]); return Assign(binaryExpression.Left, updatedExpression); } @@ -522,15 +523,14 @@ protected override Expression VisitBinary(BinaryExpression binaryExpression) _jsonMaterializationContextToJsonReaderDataAndKeyValuesParameterMapping[parameterExpression] = mappedParameter; var updatedExpression = newExpression.Update( - new[] - { - _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant( + [ + _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant( ValueBuffer.Empty, static _ => ValueBuffer.Empty, "emptyValueBuffer", typeof(ValueBuffer)), newExpression.Arguments[1] - }); + ]); return Assign(binaryExpression.Left, updatedExpression); } @@ -909,29 +909,35 @@ when GetProjectionIndex(collectionResultExpression.ProjectionBindingExpression) outerIdentifierLambda, selfIdentifierLambda, _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant( - relationalCollectionShaperExpression.ParentIdentifierValueComparers.Select(x => (Func)x.Equals).ToArray(), + relationalCollectionShaperExpression.ParentIdentifierValueComparers + .Select(x => (Func)x.Equals).ToArray(), Lambda>( NewArrayInit( typeof(Func), - relationalCollectionShaperExpression.ParentIdentifierValueComparers.Select(vc => vc.ObjectEqualsExpression)), + relationalCollectionShaperExpression.ParentIdentifierValueComparers.Select( + vc => vc.ObjectEqualsExpression)), Parameter(typeof(MaterializerLiftableConstantContext), "_")), "parentIdentifierValueComparers", typeof(Func[])), _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant( - relationalCollectionShaperExpression.OuterIdentifierValueComparers.Select(x => (Func)x.Equals).ToArray(), + relationalCollectionShaperExpression.OuterIdentifierValueComparers + .Select(x => (Func)x.Equals).ToArray(), Lambda>( NewArrayInit( typeof(Func), - relationalCollectionShaperExpression.OuterIdentifierValueComparers.Select(vc => vc.ObjectEqualsExpression)), + relationalCollectionShaperExpression.OuterIdentifierValueComparers.Select( + vc => vc.ObjectEqualsExpression)), Parameter(typeof(MaterializerLiftableConstantContext), "_")), "outerIdentifierValueComparers", typeof(Func[])), _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant( - relationalCollectionShaperExpression.SelfIdentifierValueComparers.Select(x => (Func)x.Equals).ToArray(), + relationalCollectionShaperExpression.SelfIdentifierValueComparers + .Select(x => (Func)x.Equals).ToArray(), Lambda>( NewArrayInit( typeof(Func), - relationalCollectionShaperExpression.SelfIdentifierValueComparers.Select(vc => vc.ObjectEqualsExpression)), + relationalCollectionShaperExpression.SelfIdentifierValueComparers.Select( + vc => vc.ObjectEqualsExpression)), Parameter(typeof(MaterializerLiftableConstantContext), "_")), "selfIdentifierValueComparers", typeof(Func[])), @@ -1025,16 +1031,20 @@ when GetProjectionIndex(collectionResultExpression.ProjectionBindingExpression) _resultCoordinatorParameter, childIdentifierLambda, _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant( - relationalSplitCollectionShaperExpression.IdentifierValueComparers.Select(x => (Func)x.Equals).ToArray(), + relationalSplitCollectionShaperExpression.IdentifierValueComparers + .Select(x => (Func)x.Equals).ToArray(), Lambda>( NewArrayInit( typeof(Func), - relationalSplitCollectionShaperExpression.IdentifierValueComparers.Select(vc => vc.ObjectEqualsExpression)), + relationalSplitCollectionShaperExpression.IdentifierValueComparers.Select( + vc => vc.ObjectEqualsExpression)), Parameter(typeof(MaterializerLiftableConstantContext), "_")), "identifierValueComparers", typeof(Func[])), innerShaper, - relatedDataLoaders ?? (Expression)Constant(null, + relatedDataLoaders + ?? (Expression)Constant( + null, _isAsync ? typeof(Func) : typeof(Action)), @@ -1187,29 +1197,35 @@ when GetProjectionIndex(collectionResultExpression.ProjectionBindingExpression) outerIdentifierLambda, selfIdentifierLambda, _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant( - relationalCollectionShaperExpression.ParentIdentifierValueComparers.Select(x => (Func)x.Equals).ToArray(), + relationalCollectionShaperExpression.ParentIdentifierValueComparers + .Select(x => (Func)x.Equals).ToArray(), Lambda>( NewArrayInit( typeof(Func), - relationalCollectionShaperExpression.ParentIdentifierValueComparers.Select(vc => vc.ObjectEqualsExpression)), + relationalCollectionShaperExpression.ParentIdentifierValueComparers.Select( + vc => vc.ObjectEqualsExpression)), Parameter(typeof(MaterializerLiftableConstantContext), "_")), "parentIdentifierValueComparers", typeof(Func[])), _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant( - relationalCollectionShaperExpression.OuterIdentifierValueComparers.Select(x => (Func)x.Equals).ToArray(), + relationalCollectionShaperExpression.OuterIdentifierValueComparers + .Select(x => (Func)x.Equals).ToArray(), Lambda>( NewArrayInit( typeof(Func), - relationalCollectionShaperExpression.OuterIdentifierValueComparers.Select(vc => vc.ObjectEqualsExpression)), + relationalCollectionShaperExpression.OuterIdentifierValueComparers.Select( + vc => vc.ObjectEqualsExpression)), Parameter(typeof(MaterializerLiftableConstantContext), "_")), "parentIdentifierValueComparers", typeof(Func[])), _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant( - relationalCollectionShaperExpression.SelfIdentifierValueComparers.Select(x => (Func)x.Equals).ToArray(), + relationalCollectionShaperExpression.SelfIdentifierValueComparers + .Select(x => (Func)x.Equals).ToArray(), Lambda>( NewArrayInit( typeof(Func), - relationalCollectionShaperExpression.SelfIdentifierValueComparers.Select(vc => vc.ObjectEqualsExpression)), + relationalCollectionShaperExpression.SelfIdentifierValueComparers.Select( + vc => vc.ObjectEqualsExpression)), Parameter(typeof(MaterializerLiftableConstantContext), "_")), "parentIdentifierValueComparers", typeof(Func[])), @@ -1299,19 +1315,22 @@ when GetProjectionIndex(collectionResultExpression.ProjectionBindingExpression) _resultCoordinatorParameter, childIdentifierLambda, _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant( - relationalSplitCollectionShaperExpression.IdentifierValueComparers.Select(x => (Func)x.Equals).ToArray(), + relationalSplitCollectionShaperExpression.IdentifierValueComparers + .Select(x => (Func)x.Equals).ToArray(), Lambda>( NewArrayInit( typeof(Func), - relationalSplitCollectionShaperExpression.IdentifierValueComparers.Select(vc => vc.ObjectEqualsExpression)), + relationalSplitCollectionShaperExpression.IdentifierValueComparers.Select( + vc => vc.ObjectEqualsExpression)), Parameter(typeof(MaterializerLiftableConstantContext), "_")), "identifierValueComparers", typeof(Func[])), innerShaper, relatedDataLoaders == null - ? Constant(null, _isAsync - ? typeof(Func) - : typeof(Action)) + ? Constant( + null, _isAsync + ? typeof(Func) + : typeof(Action)) : relatedDataLoaders)); _variableShaperMapping[relationalSplitCollectionShaperExpression] = accessor; @@ -1371,7 +1390,7 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp var valueExpression = MakeIndex( keyPropertyValuesParameter, ObjectArrayIndexerPropertyInfo, - new[] { Constant(index) }); + [Constant(index)]); return methodCallExpression.Type != valueExpression.Type ? Convert(valueExpression, methodCallExpression.Type) : valueExpression; @@ -1723,8 +1742,11 @@ protected override Expression VisitSwitch(SwitchExpression switchExpression) //sometimes we have shadow snapshot and sometimes not, but type initializer always comes last switch (body.Expressions[^1]) { - case UnaryExpression { Operand: BlockExpression innerBlock } jsonEntityTypeInitializerUnary - when jsonEntityTypeInitializerUnary.NodeType is ExpressionType.Convert or ExpressionType.ConvertChecked: + case UnaryExpression + { + Operand: BlockExpression innerBlock, + NodeType: ExpressionType.Convert or ExpressionType.ConvertChecked + } jsonEntityTypeInitializerUnary: { // in case of proxies, the entity initializer block is wrapped around Convert node // that converts from the proxy type to the actual entity type. @@ -1775,7 +1797,7 @@ protected override Expression VisitSwitch(SwitchExpression switchExpression) case NewExpression jsonEntityTypeInitializerCtor: var newInstanceVariable = Variable(jsonEntityTypeInitializerCtor.Type, "instance"); jsonEntityTypeInitializerBlock = Block( - new[] { newInstanceVariable }, + [newInstanceVariable], Assign(newInstanceVariable, jsonEntityTypeInitializerCtor), newInstanceVariable); break; @@ -1865,14 +1887,7 @@ protected override Expression VisitSwitch(SwitchExpression switchExpression) // Fixup is only needed for non-tracking queries, in case of tracking (or NoTrackingWithIdentityResolution) - ChangeTracker does the job // or for empty/null collections of a tracking queries. - if (queryStateManager) - { - ProcessFixup(trackingInnerFixupMap); - } - else - { - ProcessFixup(innerFixupMap); - } + ProcessFixup(queryStateManager ? trackingInnerFixupMap : innerFixupMap); finalBlockExpressions.Add(jsonEntityTypeVariable); @@ -2092,7 +2107,7 @@ protected override Expression VisitConditional(ConditionalExpression conditional Block( ifTrueBlock.Variables, ifTrueBlock.Expressions.Concat( - new Expression[] { Assign(entityAlreadyTrackedVariable, Constant(true)), Default(typeof(void)) }))) + [Assign(entityAlreadyTrackedVariable, Constant(true)), Default(typeof(void))]))) }; resultBlockVariables.AddRange(ifFalseBlock.Variables.ToList()); @@ -2194,9 +2209,7 @@ private sealed class ValueBufferTryReadValueMethodsFinder : ExpressionVisitor private readonly List _valueBufferTryReadValueMethods = []; public ValueBufferTryReadValueMethodsFinder(IEntityType entityType) - { - _nonKeyProperties = entityType.GetProperties().Where(p => !p.IsPrimaryKey()).ToList(); - } + => _nonKeyProperties = entityType.GetProperties().Where(p => !p.IsPrimaryKey()).ToList(); public List FindValueBufferTryReadValueMethods(Expression expression) { @@ -2247,7 +2260,7 @@ protected override Expression VisitBinary(BinaryExpression node) ? (Expression)currentVariable : Convert(currentVariable, genericMethod.GetParameters()[1].ParameterType); return Block( - new[] { currentVariable }, + [currentVariable], MakeMemberAccess(instance, property.GetMemberInfo(forMaterialization: true, forSet: false)) .Assign(currentVariable), IfThenElse( @@ -2503,7 +2516,7 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp if (methodCallExpression is { Method: { IsGenericMethod: true } method, - Arguments: [_, _, Expression argumentExpression] + Arguments: [_, _, Expression argumentExpression] } && argumentExpression.TryGetNonNullConstantValue(out var property) && method.GetGenericMethodDefinition() == Infrastructure.ExpressionExtensions.ValueBufferTryReadValueMethod @@ -2620,7 +2633,7 @@ private Expression GetOrCreateCollectionObjectLambda( CollectionAccessorGetOrCreateMethodInfo, prm, Constant(true))), - prm); + prm); } private Expression AddToCollectionNavigation( @@ -2724,10 +2737,12 @@ Expression valueExpression // return incorrect mapping. So for that case we would prefer to incorporate the FromProvider lambda, like we used to do before AOT // and only resort to unreliable TypeMappingSource lookup, if the converter expression captures "forbidden" constant // see issue #33517 for more details - var requiresLiftableConstant = new ConstantValidator().RequiresLiftableConstant(converter.ConvertFromProviderExpression.Body); + var requiresLiftableConstant = + new ConstantValidator().RequiresLiftableConstant(converter.ConvertFromProviderExpression.Body); if (property != null || requiresLiftableConstant) { - var typeMappingExpression = CreateTypeMappingExpression(property, type, typeMapping, _parentVisitor.Dependencies.LiftableConstantFactory); + var typeMappingExpression = CreateTypeMappingExpression( + property, type, typeMapping, _parentVisitor.Dependencies.LiftableConstantFactory); converterExpression = Property(typeMappingExpression, nameof(CoreTypeMapping.Converter)); var converterType = converter.GetType(); @@ -2940,16 +2955,16 @@ private Expression CreateReadJsonPropertyValueExpression( var jsonReaderWriterExpression = _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant( property.GetJsonValueReaderWriter() ?? property.GetTypeMapping().JsonValueReaderWriter!, Lambda>( - Coalesce( - Call( - LiftableConstantExpressionHelpers.BuildMemberAccessForProperty(property, prm), - PropertyGetJsonValueReaderWriterMethod), - Property( + Coalesce( Call( LiftableConstantExpressionHelpers.BuildMemberAccessForProperty(property, prm), - PropertyGetTypeMappingMethod), - nameof(CoreTypeMapping.JsonValueReaderWriter))), - prm), + PropertyGetJsonValueReaderWriterMethod), + Property( + Call( + LiftableConstantExpressionHelpers.BuildMemberAccessForProperty(property, prm), + PropertyGetTypeMappingMethod), + nameof(CoreTypeMapping.JsonValueReaderWriter))), + prm), property.Name + "PropertyName", jsonReaderWriter.GetType()); @@ -3034,7 +3049,11 @@ private sealed class JsonCorrectOrderOfEntitiesForChangeTrackerValidator(SelectE { private bool _insideCollection; private bool _insideInclude; - private readonly List<(IEntityType JsonEntityType, List<(IProperty? KeyProperty, int? ConstantKeyValue, int? KeyProjectionIndex)> KeyAccessInfo)> _projectedKeyAccessInfos = []; + private SelectExpression _selectExpression = selectExpression; + private readonly + List<(IEntityType JsonEntityType, List<(IProperty? KeyProperty, int? ConstantKeyValue, int? KeyProjectionIndex)> + KeyAccessInfo)> _projectedKeyAccessInfos = []; + private readonly List _includedJsonEntityTypes = []; public void Validate(Expression expression) @@ -3058,8 +3077,9 @@ public void Validate(Expression expression) { for (var i = _projectedKeyAccessInfos.Count - 1; i >= 0; i--) { - if (_includedJsonEntityTypes.Any(t => t == _projectedKeyAccessInfos[i].JsonEntityType - || _projectedKeyAccessInfos[i].JsonEntityType.IsInOwnershipPath(t))) + if (_includedJsonEntityTypes.Any( + t => t == _projectedKeyAccessInfos[i].JsonEntityType + || _projectedKeyAccessInfos[i].JsonEntityType.IsInOwnershipPath(t))) { _projectedKeyAccessInfos.RemoveAt(i); } @@ -3092,11 +3112,12 @@ public void Validate(Expression expression) // }) if (outerKeyAccessInfo.Any(x => x.KeyProperty == null && x.KeyProjectionIndex != null)) { - throw new InvalidOperationException(RelationalStrings.JsonProjectingCollectionElementAccessedUsingParmeterNoTrackingWithIdentityResolution( - outerJsonEntityType.DisplayName(), nameof(QueryTrackingBehavior.NoTrackingWithIdentityResolution))); + throw new InvalidOperationException( + RelationalStrings.JsonProjectingCollectionElementAccessedUsingParmeterNoTrackingWithIdentityResolution( + outerJsonEntityType.DisplayName(), nameof(QueryTrackingBehavior.NoTrackingWithIdentityResolution))); } - for (var j = _projectedKeyAccessInfos.Count -1; j > i; j--) + for (var j = _projectedKeyAccessInfos.Count - 1; j > i; j--) { var innerKeyAccessInfo = _projectedKeyAccessInfos[j].KeyAccessInfo; var innerJsonEntityType = _projectedKeyAccessInfos[j].JsonEntityType; @@ -3126,7 +3147,8 @@ public void Validate(Expression expression) continue; } - if ((outerJsonEntityType == innerJsonEntityType || innerJsonEntityType.IsInOwnershipPath(outerJsonEntityType)) + if ((outerJsonEntityType == innerJsonEntityType + || innerJsonEntityType.IsInOwnershipPath(outerJsonEntityType)) && outerKeyAccessInfo.Count <= innerKeyAccessInfo.Count) { // outer and inner are on same ownership paths and outer is the owner of inner @@ -3135,9 +3157,10 @@ public void Validate(Expression expression) continue; } - throw new InvalidOperationException(RelationalStrings.JsonProjectingEntitiesIncorrectOrderNoTrackingWithIdentityResolution( - outerJsonEntityType.DisplayName(), - nameof(QueryTrackingBehavior.NoTrackingWithIdentityResolution))); + throw new InvalidOperationException( + RelationalStrings.JsonProjectingEntitiesIncorrectOrderNoTrackingWithIdentityResolution( + outerJsonEntityType.DisplayName(), + nameof(QueryTrackingBehavior.NoTrackingWithIdentityResolution))); } } @@ -3183,8 +3206,11 @@ protected override Expression VisitExtension(Expression extensionExpression) { var insideCollection = _insideCollection; _insideCollection = true; + var oldSelectExpression = _selectExpression; + _selectExpression = splitCollectionShaperExpression.SelectExpression; Visit(splitCollectionShaperExpression.InnerShaper); _insideCollection = insideCollection; + _selectExpression = oldSelectExpression; return splitCollectionShaperExpression; } @@ -3197,9 +3223,12 @@ protected override Expression VisitExtension(Expression extensionExpression) _insideInclude = insideInclude; } - if (extensionExpression is StructuralTypeShaperExpression { ValueBufferExpression: ProjectionBindingExpression entityProjectionBindingExpression } entityShaperExpression) + if (extensionExpression is StructuralTypeShaperExpression + { + ValueBufferExpression: ProjectionBindingExpression entityProjectionBindingExpression + } entityShaperExpression) { - var entityProjection = selectExpression.GetProjection(entityProjectionBindingExpression).GetConstantValue(); + var entityProjection = _selectExpression.GetProjection(entityProjectionBindingExpression).GetConstantValue(); switch (entityProjection) { @@ -3232,16 +3261,21 @@ protected override Expression VisitExtension(Expression extensionExpression) } } - if (extensionExpression is CollectionResultExpression { ProjectionBindingExpression: ProjectionBindingExpression collectionProjectionBindingExpression } collectionResultExpression) + if (extensionExpression is CollectionResultExpression + { + ProjectionBindingExpression: ProjectionBindingExpression collectionProjectionBindingExpression + } collectionResultExpression) { - var collectionProjection = selectExpression.GetProjection(collectionProjectionBindingExpression).GetConstantValue(); + var collectionProjection = + _selectExpression.GetProjection(collectionProjectionBindingExpression).GetConstantValue(); switch (collectionProjection) { case QueryableJsonProjectionInfo: case JsonProjectionInfo when _insideCollection: throw new InvalidOperationException( - RelationalStrings.JsonProjectingQueryableOperationNoTrackingWithIdentityResolution(nameof(QueryTrackingBehavior.NoTrackingWithIdentityResolution))); + RelationalStrings.JsonProjectingQueryableOperationNoTrackingWithIdentityResolution( + nameof(QueryTrackingBehavior.NoTrackingWithIdentityResolution))); case JsonProjectionInfo jsonCollectionProjectionInfo: { diff --git a/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.cs b/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.cs index 494399d8d0b..2250db9b034 100644 --- a/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.cs +++ b/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.cs @@ -14,7 +14,7 @@ namespace Microsoft.EntityFrameworkCore.Query; /// public partial class RelationalShapedQueryCompilingExpressionVisitor : ShapedQueryCompilingExpressionVisitor { - private readonly HashSet _parametersToConstantize; + private readonly IReadOnlySet _parametersToConstantize; private readonly Type _contextType; private readonly ISet _tags; private readonly bool _threadSafetyChecksEnabled; @@ -53,10 +53,11 @@ public RelationalShapedQueryCompilingExpressionVisitor( { RelationalDependencies = relationalDependencies; - _parametersToConstantize = QueryCompilationContext.ParametersToConstantize; + _parametersToConstantize = (IReadOnlySet)QueryCompilationContext.ParametersToConstantize; _relationalParameterBasedSqlProcessor = - relationalDependencies.RelationalParameterBasedSqlProcessorFactory.Create(new RelationalParameterBasedSqlProcessorParameters(_useRelationalNulls, _parametersToConstantize)); + relationalDependencies.RelationalParameterBasedSqlProcessorFactory.Create( + new RelationalParameterBasedSqlProcessorParameters(_useRelationalNulls, _parametersToConstantize)); _querySqlGeneratorFactory = relationalDependencies.QuerySqlGeneratorFactory; _contextType = queryCompilationContext.ContextType; @@ -84,40 +85,26 @@ protected virtual int MaxNullableParametersForPregeneratedSql /// protected override Expression VisitExtension(Expression extensionExpression) - => extensionExpression is NonQueryExpression nonQueryExpression - ? VisitNonQuery(nonQueryExpression) - : base.VisitExtension(extensionExpression); - - /// - /// Visits the given , returning an expression that when compiled, can execute the non- - /// query operation against the database. - /// - /// The expression to be compiled. - /// An expression which executes a non-query operation. - protected virtual Expression VisitNonQuery(NonQueryExpression nonQueryExpression) { - // Apply tags - var innerExpression = nonQueryExpression.Expression; - switch (innerExpression) + return extensionExpression switch { - case UpdateExpression updateExpression: - innerExpression = updateExpression.ApplyTags(_tags); - break; + UpdateExpression updateExpression => GenerateNonQueryShaper(updateExpression.ApplyTags(_tags), CommandSource.ExecuteUpdate), + DeleteExpression deleteExpression => GenerateNonQueryShaper(deleteExpression.ApplyTags(_tags), CommandSource.ExecuteUpdate), + _ => base.VisitExtension(extensionExpression) + }; - case DeleteExpression deleteExpression: - innerExpression = deleteExpression.ApplyTags(_tags); - break; - } - - var relationalCommandResolver = CreateRelationalCommandResolverExpression(innerExpression); + Expression GenerateNonQueryShaper(Expression nonQueryExpression, CommandSource commandSource) + { + var relationalCommandResolver = CreateRelationalCommandResolverExpression(nonQueryExpression); - return Call( - QueryCompilationContext.IsAsync ? NonQueryAsyncMethodInfo : NonQueryMethodInfo, - Convert(QueryCompilationContext.QueryContextParameter, typeof(RelationalQueryContext)), - relationalCommandResolver, - Constant(_contextType), - Constant(nonQueryExpression.CommandSource), - Constant(_threadSafetyChecksEnabled)); + return Call( + QueryCompilationContext.IsAsync ? NonQueryAsyncMethodInfo : NonQueryMethodInfo, + Convert(QueryCompilationContext.QueryContextParameter, typeof(RelationalQueryContext)), + relationalCommandResolver, + Constant(_contextType), + Constant(commandSource), + Constant(_threadSafetyChecksEnabled)); + } } private static readonly MethodInfo NonQueryMethodInfo @@ -278,7 +265,7 @@ protected override Expression VisitShapedQuery(ShapedQueryExpression shapedQuery if (shapedQueryExpression.ShaperExpression is RelationalGroupByResultExpression relationalGroupByResultExpression) { - var elementSelector = new ShaperProcessingExpressionVisitor(this, selectExpression, selectExpression.Tags, splitQuery, false) + var elementSelector = new ShaperProcessingExpressionVisitor(this, selectExpression, _tags, splitQuery, indexMap: false) .ProcessRelationalGroupingResult( relationalGroupByResultExpression, out var relationalCommandResolver, @@ -313,7 +300,8 @@ protected override Expression VisitShapedQuery(ShapedQueryExpression shapedQuery keySelector, keyIdentifier, Dependencies.LiftableConstantFactory.CreateLiftableConstant( - relationalGroupByResultExpression.KeyIdentifierValueComparers.Select(x => (Func)x.Equals).ToArray(), + relationalGroupByResultExpression.KeyIdentifierValueComparers.Select(x => (Func)x.Equals) + .ToArray(), Lambda>( NewArrayInit( typeof(Func), @@ -338,7 +326,8 @@ protected override Expression VisitShapedQuery(ShapedQueryExpression shapedQuery keySelector, keyIdentifier, Dependencies.LiftableConstantFactory.CreateLiftableConstant( - relationalGroupByResultExpression.KeyIdentifierValueComparers.Select(x => (Func)x.Equals).ToArray(), + relationalGroupByResultExpression.KeyIdentifierValueComparers.Select(x => (Func)x.Equals) + .ToArray(), Lambda>( NewArrayInit( typeof(Func), @@ -724,17 +713,26 @@ Expression GenerateRelationalCommandExpression(IReadOnlyDictionary> GenerateRelationalCommandCacheExpression() { _hashSetConstructor ??= typeof(HashSet).GetConstructor([typeof(IEnumerable), typeof(StringComparer)])!; _stringComparerOrdinalProperty ??= typeof(StringComparer).GetProperty(nameof(StringComparer.Ordinal))!; _relationalCommandCacheConstructor ??= typeof(RelationalCommandCache).GetConstructors().Single(); - _dependenciesProperty ??= typeof(RelationalMaterializerLiftableConstantContext).GetProperty(nameof(RelationalMaterializerLiftableConstantContext.Dependencies))!; - _dependenciesMemoryCacheProperty ??= typeof(ShapedQueryCompilingExpressionVisitorDependencies).GetProperty(nameof(ShapedQueryCompilingExpressionVisitorDependencies.MemoryCache))!; - _relationalDependenciesProperty ??= typeof(RelationalMaterializerLiftableConstantContext).GetProperty(nameof(RelationalMaterializerLiftableConstantContext.RelationalDependencies))!; - _relationalDependenciesQuerySqlGeneratorFactoryProperty ??= typeof(RelationalShapedQueryCompilingExpressionVisitorDependencies).GetProperty(nameof(RelationalShapedQueryCompilingExpressionVisitorDependencies.QuerySqlGeneratorFactory))!; - _relationalDependenciesRelationalParameterBasedSqlProcessorFactoryProperty ??= typeof(RelationalShapedQueryCompilingExpressionVisitorDependencies).GetProperty(nameof(RelationalShapedQueryCompilingExpressionVisitorDependencies.RelationalParameterBasedSqlProcessorFactory))!; + _dependenciesProperty ??= + typeof(RelationalMaterializerLiftableConstantContext).GetProperty( + nameof(RelationalMaterializerLiftableConstantContext.Dependencies))!; + _dependenciesMemoryCacheProperty ??= + typeof(ShapedQueryCompilingExpressionVisitorDependencies).GetProperty( + nameof(ShapedQueryCompilingExpressionVisitorDependencies.MemoryCache))!; + _relationalDependenciesProperty ??= + typeof(RelationalMaterializerLiftableConstantContext).GetProperty( + nameof(RelationalMaterializerLiftableConstantContext.RelationalDependencies))!; + _relationalDependenciesQuerySqlGeneratorFactoryProperty ??= + typeof(RelationalShapedQueryCompilingExpressionVisitorDependencies).GetProperty( + nameof(RelationalShapedQueryCompilingExpressionVisitorDependencies.QuerySqlGeneratorFactory))!; + _relationalDependenciesRelationalParameterBasedSqlProcessorFactoryProperty ??= + typeof(RelationalShapedQueryCompilingExpressionVisitorDependencies).GetProperty( + nameof(RelationalShapedQueryCompilingExpressionVisitorDependencies.RelationalParameterBasedSqlProcessorFactory))!; var newHashSetExpression = New( _hashSetConstructor, @@ -767,7 +765,7 @@ private sealed class SqlParameterLocator : ExpressionVisitor public IReadOnlySet LocateParameters(Expression selectExpression) { - _parameters = new(); + _parameters = new HashSet(); Visit(selectExpression); return _parameters; } diff --git a/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitor.cs b/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitor.cs index 6a5993cb709..be1d116516f 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); } /// @@ -1266,7 +1266,7 @@ private SqlExpression BindProperty(StructuralTypeReferenceExpression typeReferen if (allRequiredNonPkProperties.Count > 0) { condition = allRequiredNonPkProperties.Select(p => projection.BindProperty(p)) - .Select(c => (SqlExpression)_sqlExpressionFactory.NotEqual(c, _sqlExpressionFactory.Constant(null, c.Type))) + .Select(c => _sqlExpressionFactory.NotEqual(c, _sqlExpressionFactory.Constant(null, c.Type))) .Aggregate((a, b) => _sqlExpressionFactory.AndAlso(a, b)); } @@ -1362,12 +1362,15 @@ protected virtual bool TryTranslateAggregateMethodCall( { switch (genericMethod.Name) { - case nameof(Queryable.Average) - when QueryableMethods.IsAverageWithoutSelector(genericMethod): case nameof(Queryable.Max) when genericMethod == QueryableMethods.MaxWithoutSelector: case nameof(Queryable.Min) when genericMethod == QueryableMethods.MinWithoutSelector: + enumerableExpression = enumerableExpression.SetDistinct(false); + break; + + case nameof(Queryable.Average) + when QueryableMethods.IsAverageWithoutSelector(genericMethod): case nameof(Queryable.Sum) when QueryableMethods.IsSumWithoutSelector(genericMethod): case nameof(Queryable.Count) @@ -1376,12 +1379,16 @@ when QueryableMethods.IsSumWithoutSelector(genericMethod): when genericMethod == QueryableMethods.LongCountWithoutPredicate: break; - case nameof(Queryable.Average) - when QueryableMethods.IsAverageWithSelector(genericMethod): case nameof(Queryable.Max) when genericMethod == QueryableMethods.MaxWithSelector: case nameof(Queryable.Min) when genericMethod == QueryableMethods.MinWithSelector: + enumerableExpression = enumerableExpression.SetDistinct(false); + enumerableExpression = ProcessSelector(enumerableExpression, arguments[1].UnwrapLambdaFromQuote()); + break; + + case nameof(Queryable.Average) + when QueryableMethods.IsAverageWithSelector(genericMethod): case nameof(Queryable.Sum) when QueryableMethods.IsSumWithSelector(genericMethod): enumerableExpression = ProcessSelector(enumerableExpression, arguments[1].UnwrapLambdaFromQuote()); @@ -1478,7 +1485,7 @@ private bool TryTranslateAsEnumerableExpression( if (!enumerableSource.IsDistinct) { - enumerableExpression = enumerableSource.ApplyDistinct(); + enumerableExpression = enumerableSource.SetDistinct(true); return true; } diff --git a/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitorFactory.cs b/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitorFactory.cs index ad7d4727000..97abbde7c74 100644 --- a/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitorFactory.cs +++ b/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitorFactory.cs @@ -12,9 +12,7 @@ public class RelationalSqlTranslatingExpressionVisitorFactory : IRelationalSqlTr /// The service dependencies. public RelationalSqlTranslatingExpressionVisitorFactory( RelationalSqlTranslatingExpressionVisitorDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore.Relational/Query/RelationalTypeMappingPostprocessor.cs b/src/EFCore.Relational/Query/RelationalTypeMappingPostprocessor.cs index b5edc9001b7..926e75ce5f5 100644 --- a/src/EFCore.Relational/Query/RelationalTypeMappingPostprocessor.cs +++ b/src/EFCore.Relational/Query/RelationalTypeMappingPostprocessor.cs @@ -282,10 +282,10 @@ protected override Expression VisitExtension(Expression node) // Similar to the above, but with ScalarSubqueryExpression the inferred type mapping is on the expression itself, while the // ColumnExpression we need is on the subquery's projection. case ScalarSubqueryExpression - { - TypeMapping: { } typeMapping, - Subquery.Projection: [{ Expression: ColumnExpression columnExpression }] - }: + { + TypeMapping: { } typeMapping, + Subquery.Projection: [{ Expression: ColumnExpression columnExpression }] + }: { var visitedSubquery = base.VisitExtension(node); @@ -299,10 +299,10 @@ protected override Expression VisitExtension(Expression node) // InExpression over a subquery: apply the item's type mapping on the subquery case InExpression - { - Item.TypeMapping: { } typeMapping, - Subquery.Projection: [{ Expression: ColumnExpression columnExpression }] - }: + { + Item.TypeMapping: { } typeMapping, + Subquery.Projection: [{ Expression: ColumnExpression columnExpression }] + }: { var visited = base.VisitExtension(node); diff --git a/src/EFCore.Relational/Query/SqlAliasManager.cs b/src/EFCore.Relational/Query/SqlAliasManager.cs index 4d1f247eea7..df484e8cecb 100644 --- a/src/EFCore.Relational/Query/SqlAliasManager.cs +++ b/src/EFCore.Relational/Query/SqlAliasManager.cs @@ -113,7 +113,7 @@ public virtual Expression PostprocessAliases(Expression expression) } else { - bitmap = aliasBitmaps[aliasBase] = new(aliasNum + 1); + bitmap = aliasBitmaps[aliasBase] = new BitArray(aliasNum + 1); } bitmap[aliasNum] = true; @@ -141,7 +141,7 @@ public virtual Expression PostprocessAliases(Expression expression) var j = i - numHoles; var newAlias = aliasBase + (j == 0 ? "" : (j - 1).ToString()); - aliasRewritingMap ??= new(); + aliasRewritingMap ??= new Dictionary(); aliasRewritingMap[oldAlias] = newAlias; } } diff --git a/src/EFCore.Relational/Query/SqlExpressionFactory.cs b/src/EFCore.Relational/Query/SqlExpressionFactory.cs index fcadf4a33a6..47f94f1d78b 100644 --- a/src/EFCore.Relational/Query/SqlExpressionFactory.cs +++ b/src/EFCore.Relational/Query/SqlExpressionFactory.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics.CodeAnalysis; -using Microsoft.EntityFrameworkCore.Query.Internal; using Microsoft.EntityFrameworkCore.Query.SqlExpressions; namespace Microsoft.EntityFrameworkCore.Query; @@ -358,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 }] }) { @@ -370,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); } @@ -468,12 +471,14 @@ private SqlExpression AndAlso(SqlExpression left, SqlExpression right, SqlExpres { return left; } + // true && x -> x // x && false -> false if (left is SqlConstantExpression { Value: true } || right is SqlConstantExpression { Value: false }) { return right; } + // x is null && x is not null -> false // x is not null && x is null -> false if (left is SqlUnaryExpression { OperatorType: ExpressionType.Equal or ExpressionType.NotEqual } leftUnary @@ -483,6 +488,7 @@ private SqlExpression AndAlso(SqlExpression left, SqlExpression right, SqlExpres // the case in which left and right are the same expression is handled above return Constant(false); } + if (existingExpression is SqlBinaryExpression { OperatorType: ExpressionType.AndAlso } binaryExpr && left == binaryExpr.Left && right == binaryExpr.Right) @@ -508,6 +514,7 @@ private SqlExpression OrElse(SqlExpression left, SqlExpression right, SqlExpress { return left; } + // false || x -> x // x || true -> true if (left is SqlConstantExpression { Value: false } @@ -515,6 +522,7 @@ private SqlExpression OrElse(SqlExpression left, SqlExpression right, SqlExpress { return right; } + // x is null || x is not null -> true // x is not null || x is null -> true if (left is SqlUnaryExpression { OperatorType: ExpressionType.Equal or ExpressionType.NotEqual } leftUnary @@ -524,6 +532,7 @@ private SqlExpression OrElse(SqlExpression left, SqlExpression right, SqlExpress // the case in which left and right are the same expression is handled above return Constant(true); } + if (existingExpression is SqlBinaryExpression { OperatorType: ExpressionType.OrElse } binaryExpr && left == binaryExpr.Left && right == binaryExpr.Right) @@ -578,7 +587,7 @@ public virtual SqlExpression Coalesce(SqlExpression left, SqlExpression right, R SqlConstantExpression { Value: null } => right, SqlConstantExpression { Value: not null } or - ColumnExpression { IsNullable: false } => left, + ColumnExpression { IsNullable: false } => left, _ => new SqlFunctionExpression( "COALESCE", @@ -663,9 +672,11 @@ private SqlExpression Not(SqlExpression operand, SqlExpression? existingExpressi => Equal(Not(binary.Left), binary.Right), // !(a == b) -> a != b - SqlBinaryExpression { OperatorType: ExpressionType.Equal } sqlBinaryOperand => NotEqual(sqlBinaryOperand.Left, sqlBinaryOperand.Right), + SqlBinaryExpression { OperatorType: ExpressionType.Equal } sqlBinaryOperand => NotEqual( + sqlBinaryOperand.Left, sqlBinaryOperand.Right), // !(a != b) -> a == b - SqlBinaryExpression { OperatorType: ExpressionType.NotEqual } sqlBinaryOperand => Equal(sqlBinaryOperand.Left, sqlBinaryOperand.Right), + SqlBinaryExpression { OperatorType: ExpressionType.NotEqual } sqlBinaryOperand => Equal( + sqlBinaryOperand.Left, sqlBinaryOperand.Right), // !(CASE x WHEN t1 THEN r1 ... ELSE rN) -> CASE x WHEN t1 THEN !r1 ... ELSE !rN CaseExpression caseExpression @@ -735,7 +746,7 @@ public virtual SqlExpression Case( test = nestedSingleClause.Test; } else if (nestedSingleClause.Result is SqlConstantExpression { Value: false or null } - && testExpr.ElseResult is SqlConstantExpression { Value: true }) + && testExpr.ElseResult is SqlConstantExpression { Value: true }) { // same for the negated results test = Not(nestedSingleClause.Test); @@ -810,7 +821,7 @@ public virtual SqlExpression Case( && typeMappedWhenClauses[^1].Result is CaseExpression { Operand: null, WhenClauses: [var lastClause] } lastCase && Equals(elseResult, lastCase.ElseResult)) { - typeMappedWhenClauses[^1] = new(AndAlso(typeMappedWhenClauses[^1].Test, lastClause.Test), lastClause.Result); + typeMappedWhenClauses[^1] = new CaseWhenClause(AndAlso(typeMappedWhenClauses[^1].Test, lastClause.Test), lastClause.Result); elseResult = lastCase.ElseResult; } @@ -818,8 +829,8 @@ public virtual SqlExpression Case( && operand == expr.Operand && typeMappedWhenClauses.SequenceEqual(expr.WhenClauses) && elseResult == expr.ElseResult - ? expr - : new CaseExpression(operand, typeMappedWhenClauses, elseResult); + ? expr + : new CaseExpression(operand, typeMappedWhenClauses, elseResult); bool IsSkipped(CaseWhenClause clause) => operand is null && clause.Test is SqlConstantExpression { Value: false or null }; diff --git a/src/EFCore.Relational/Query/SqlExpressions/CaseExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/CaseExpression.cs index ee52be5c94a..991b1dc91f8 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/CaseExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/CaseExpression.cs @@ -118,11 +118,12 @@ public override Expression Quote() var whenClauses = NewArrayInit( typeof(CaseWhenClause), initializers: WhenClauses - .Select(c => New( - _caseWhenClauseQuotingConstructor ??= - typeof(CaseWhenClause).GetConstructor([typeof(SqlExpression), typeof(SqlExpression)])!, - c.Test.Quote(), - c.Result.Quote()))); + .Select( + c => New( + _caseWhenClauseQuotingConstructor ??= + typeof(CaseWhenClause).GetConstructor([typeof(SqlExpression), typeof(SqlExpression)])!, + c.Test.Quote(), + c.Result.Quote()))); return Operand is null ? New( diff --git a/src/EFCore.Relational/Query/SqlExpressions/DeleteExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/DeleteExpression.cs index 88f40c34035..734da4bb1af 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/DeleteExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/DeleteExpression.cs @@ -11,6 +11,7 @@ namespace Microsoft.EntityFrameworkCore.Query.SqlExpressions; /// This type is typically used by database providers (and other extensions). It is generally not used in application code. /// /// +[DebuggerDisplay("{Microsoft.EntityFrameworkCore.Query.ExpressionPrinter.Print(this), nq}")] public sealed class DeleteExpression : Expression, IRelationalQuotableExpression, IPrintableExpression { private static ConstructorInfo? _quotingConstructor; @@ -63,7 +64,7 @@ public DeleteExpression ApplyTags(ISet tags) /// public override Type Type - => typeof(object); + => typeof(void); /// public override ExpressionType NodeType @@ -105,12 +106,16 @@ public Expression Quote() /// public void Print(ExpressionPrinter expressionPrinter) { - foreach (var tag in Tags) + if (Tags.Count > 0) { - expressionPrinter.Append($"-- {tag}"); + foreach (var tag in Tags) + { + expressionPrinter.Append($"-- {tag}"); + } + + expressionPrinter.AppendLine(); } - expressionPrinter.AppendLine(); expressionPrinter.AppendLine($"DELETE FROM {Table.Name} AS {Table.Alias}"); expressionPrinter.Visit(SelectExpression); } @@ -129,5 +134,4 @@ private bool Equals(DeleteExpression deleteExpression) /// public override int GetHashCode() => HashCode.Combine(Table, SelectExpression); - } diff --git a/src/EFCore.Relational/Query/SqlExpressions/FromSqlExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/FromSqlExpression.cs index c71e7b97736..5273cc1e656 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/FromSqlExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/FromSqlExpression.cs @@ -1,8 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; - namespace Microsoft.EntityFrameworkCore.Query.SqlExpressions; /// @@ -135,7 +133,8 @@ public override Expression Quote() ParameterExpression parameter when parameter.Type == typeof(object[]) => Call( - _parameterExpressionFactoryMethod ??= typeof(Expression).GetMethod(nameof(Parameter), [typeof(Type), typeof(string)])!, + _parameterExpressionFactoryMethod ??= typeof(Expression).GetMethod( + nameof(Parameter), [typeof(Type), typeof(string)])!, Constant(typeof(object[])), Constant(parameter.Name, typeof(string))), diff --git a/src/EFCore.Relational/Query/SqlExpressions/IntersectExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/IntersectExpression.cs index 85009fc32c2..c933e9b1482 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/IntersectExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/IntersectExpression.cs @@ -90,7 +90,10 @@ public override IntersectExpression WithAlias(string newAlias) public override Expression Quote() => New( _quotingConstructor ??= typeof(IntersectExpression).GetConstructor( - [typeof(string), typeof(SelectExpression), typeof(SelectExpression), typeof(bool), typeof(IReadOnlyDictionary)])!, + [ + typeof(string), typeof(SelectExpression), typeof(SelectExpression), typeof(bool), + typeof(IReadOnlyDictionary) + ])!, Constant(Alias, typeof(string)), Source1.Quote(), Source2.Quote(), diff --git a/src/EFCore.Relational/Query/SqlExpressions/LeftJoinExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/LeftJoinExpression.cs index a5e2ea0ebc5..910ce14caba 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/LeftJoinExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/LeftJoinExpression.cs @@ -73,7 +73,8 @@ protected override LeftJoinExpression WithAnnotations(IReadOnlyDictionary public override Expression Quote() => New( - _quotingConstructor ??= typeof(LeftJoinExpression).GetConstructor([typeof(TableExpressionBase), typeof(SqlExpression), typeof(bool), typeof(IReadOnlyDictionary)])!, + _quotingConstructor ??= typeof(LeftJoinExpression).GetConstructor( + [typeof(TableExpressionBase), typeof(SqlExpression), typeof(bool), typeof(IReadOnlyDictionary)])!, Table.Quote(), JoinPredicate.Quote(), Constant(IsPrunable), diff --git a/src/EFCore.Relational/Query/SqlExpressions/OrderingExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/OrderingExpression.cs index ad59d1151e1..a7325c30843 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/OrderingExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/OrderingExpression.cs @@ -61,7 +61,6 @@ public virtual OrderingExpression Update(SqlExpression expression) ? new OrderingExpression(expression, IsAscending) : this; - /// public Expression Quote() => New( diff --git a/src/EFCore.Relational/Query/SqlExpressions/OuterApplyExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/OuterApplyExpression.cs index 6692ce4cc51..49bf20c1b04 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/OuterApplyExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/OuterApplyExpression.cs @@ -59,7 +59,9 @@ protected override OuterApplyExpression WithAnnotations(IReadOnlyDictionary public override Expression Quote() => New( - _quotingConstructor ??= typeof(OuterApplyExpression).GetConstructor([typeof(TableExpressionBase), typeof(IReadOnlyDictionary)])!, + _quotingConstructor ??= + typeof(OuterApplyExpression).GetConstructor( + [typeof(TableExpressionBase), typeof(IReadOnlyDictionary)])!, Table.Quote(), RelationalExpressionQuotingUtilities.QuoteAnnotations(Annotations)); diff --git a/src/EFCore.Relational/Query/SqlExpressions/PredicateJoinExpressionBase.cs b/src/EFCore.Relational/Query/SqlExpressions/PredicateJoinExpressionBase.cs index ca361689f3e..baac3db4435 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/PredicateJoinExpressionBase.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/PredicateJoinExpressionBase.cs @@ -27,9 +27,7 @@ protected PredicateJoinExpressionBase( bool prunable, IReadOnlyDictionary? annotations = null) : base(table, prunable, annotations) - { - JoinPredicate = joinPredicate; - } + => JoinPredicate = joinPredicate; /// /// The predicate used in join. diff --git a/src/EFCore.Relational/Query/SqlExpressions/ScalarSubqueryExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/ScalarSubqueryExpression.cs index cf8cb38d6d4..52a9d5025c0 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/ScalarSubqueryExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/ScalarSubqueryExpression.cs @@ -22,15 +22,11 @@ public class ScalarSubqueryExpression : SqlExpression /// A subquery projecting single row with a single scalar projection. public ScalarSubqueryExpression(SelectExpression subquery) : this(subquery, subquery.Projection[0].Expression.TypeMapping) - { - Subquery = subquery; - } + => Subquery = subquery; private ScalarSubqueryExpression(SelectExpression subquery, RelationalTypeMapping? typeMapping) : base(Verify(subquery).Projection[0].Type, typeMapping) - { - Subquery = subquery; - } + => Subquery = subquery; private static SelectExpression Verify(SelectExpression selectExpression) { diff --git a/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs index e5a36ff1e33..d57e2210403 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs @@ -113,7 +113,8 @@ public SelectExpression( SqlExpression? limit, IReadOnlySet? tags = null, IReadOnlyDictionary? annotations = null) - : this(alias, tables.ToList(), predicate, groupBy.ToList(), having, projections.ToList(), distinct, orderings.ToList(), + : this( + alias, tables.ToList(), predicate, groupBy.ToList(), having, projections.ToList(), distinct, orderings.ToList(), offset, limit, tags?.ToHashSet() ?? [], annotations, sqlAliasManager: null, isMutable: false) { } @@ -127,7 +128,8 @@ private SelectExpression( IReadOnlyDictionary? annotations, SqlAliasManager sqlAliasManager) : this( - alias, tables, predicate: null, groupBy: groupBy, having: null, projections: projections, distinct: false, orderings: orderings, offset: null, + alias, tables, predicate: null, groupBy: groupBy, having: null, projections: projections, distinct: false, orderings: orderings, + offset: null, limit: null, tags: new HashSet(), annotations: annotations, sqlAliasManager: sqlAliasManager, isMutable: true) { @@ -235,6 +237,20 @@ public IReadOnlyList Orderings /// public SqlExpression? Offset { get; private set; } + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + [EntityFrameworkInternal] + public void SetTables(IReadOnlyList tables) + { + Check.DebugAssert(IsMutable, "Attempt to mutate an immutable SelectExpression"); + _tables.Clear(); + _tables.AddRange(tables); + } + /// /// Applies a given set of tags. /// @@ -253,6 +269,11 @@ public void ApplyDistinct() throw new InvalidOperationException(RelationalStrings.DistinctOnCollectionNotSupported); } + if (Limit is SqlConstantExpression { Value: 1 }) + { + return; + } + if (Limit != null || Offset != null) { @@ -1899,6 +1920,11 @@ public void ApplyLimit(SqlExpression sqlExpression) } Limit = sqlExpression; + + if (Offset is null && Limit is SqlConstantExpression { Value: 1 }) + { + IsDistinct = false; + } } /// @@ -1955,7 +1981,8 @@ private void ApplySetOperation( { // TODO: Introduce clone method? See issue#24460 var select1 = new SelectExpression( - alias: null, tables: _tables.ToList(), groupBy: _groupBy.ToList(), projections: [], orderings: _orderings.ToList(), annotations: Annotations, sqlAliasManager: _sqlAliasManager) + alias: null, tables: _tables.ToList(), groupBy: _groupBy.ToList(), projections: [], orderings: _orderings.ToList(), + annotations: Annotations, sqlAliasManager: _sqlAliasManager) { IsDistinct = IsDistinct, Predicate = Predicate, @@ -2654,6 +2681,7 @@ public static StructuralTypeShaperExpression GenerateComplexPropertyShaperExpres complexTypeTable = complexProperty.ComplexType.GetDefaultMappings().Single().Table; tableAlias = containerProjection.TableMap[complexTypeTable]; } + var isComplexTypeNullable = containerProjection.IsNullable || complexProperty.IsNullable; // If the complex property is declared on a type that's derived relative to the type being projected, the projected column is @@ -2694,11 +2722,20 @@ public static StructuralTypeShaperExpression GenerateComplexPropertyShaperExpres /// based on its alias. /// public TableExpressionBase GetTable(ColumnExpression column) + => GetTable(column, out _); + + /// + /// Retrieves the referenced by the given column, looking it up on this + /// based on its alias. + /// + public TableExpressionBase GetTable(ColumnExpression column, out int tableIndex) { - foreach (var table in Tables) + for (var i = 0; i < _tables.Count; i++) { + var table = _tables[i]; if (table.UnwrapJoin().Alias == column.TableAlias) { + tableIndex = i; return table; } } @@ -3216,7 +3253,8 @@ static bool IsContainedSql(SelectExpression selectExpression, SqlExpression sqlE WhenClauses: [{ Result: ColumnExpression resultColumn } whenClause], ElseResult: null } - => IsContainedCondition(selectExpression, whenClause.Test) && selectExpression.ContainsReferencedTable(resultColumn), + => IsContainedCondition(selectExpression, whenClause.Test) + && selectExpression.ContainsReferencedTable(resultColumn), _ => false }; @@ -3827,8 +3865,7 @@ private TableExpressionBase Clone(string? alias, ExpressionVisitor cloningExpres alias, newTables, predicate, newGroupBy, havingExpression, newProjections, IsDistinct, newOrderings, offset, limit, Tags, Annotations, _sqlAliasManager, IsMutable) { - _projectionMapping = newProjectionMappings, - _clientProjections = newClientProjections, + _projectionMapping = newProjectionMappings, _clientProjections = newClientProjections, }; foreach (var (column, comparer) in _identifier) @@ -3939,7 +3976,8 @@ private static ColumnExpression CreateColumnExpression( IColumnBase column, string tableAlias, bool nullable) - => new(column.Name, + => new( + column.Name, tableAlias, property.ClrType.UnwrapNullableType(), column.PropertyMappings.First(m => m.Property == property).TypeMapping, @@ -4123,8 +4161,7 @@ protected override Expression VisitChildren(ExpressionVisitor visitor) Alias, newTables, predicate, newGroupBy, havingExpression, newProjections, IsDistinct, newOrderings, offset, limit, (IReadOnlySet)Tags, Annotations) { - _clientProjections = _clientProjections, - _projectionMapping = _projectionMapping + _clientProjections = _clientProjections, _projectionMapping = _projectionMapping }; newSelectExpression._identifier.AddRange(identifier.Zip(_identifier).Select(e => (e.First, e.Second.Comparer))); @@ -4220,6 +4257,16 @@ public SelectExpression Update( return this; } + if (predicate is SqlConstantExpression { Value: true }) + { + predicate = null; + } + + if (having is SqlConstantExpression { Value: true }) + { + having = null; + } + var projectionMapping = new Dictionary(); foreach (var (projectionMember, expression) in _projectionMapping) { @@ -4230,8 +4277,7 @@ public SelectExpression Update( Alias, tables, predicate, groupBy, having, projections, IsDistinct, orderings, offset, limit, (IReadOnlySet)Tags, Annotations) { - _projectionMapping = projectionMapping, - _clientProjections = _clientProjections.ToList() + _projectionMapping = projectionMapping, _clientProjections = _clientProjections.ToList() }; // We don't copy identifiers because when we are doing reconstruction so projection is already applied. @@ -4529,7 +4575,6 @@ public override int GetHashCode() } return hash.ToHashCode(); - } // ReSharper restore NonReadonlyMemberInGetHashCode } diff --git a/src/EFCore.Relational/Query/SqlExpressions/SetOperationBase.cs b/src/EFCore.Relational/Query/SqlExpressions/SetOperationBase.cs index 96ed42285ac..5ef9517c09b 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/SetOperationBase.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/SetOperationBase.cs @@ -1,8 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; - namespace Microsoft.EntityFrameworkCore.Query.SqlExpressions; /// diff --git a/src/EFCore.Relational/Query/SqlExpressions/SqlFragmentExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/SqlFragmentExpression.cs index b939517ac79..d5e2fae4d10 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/SqlFragmentExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/SqlFragmentExpression.cs @@ -22,9 +22,7 @@ public class SqlFragmentExpression : SqlExpression /// A string token to print in SQL tree. public SqlFragmentExpression(string sql) : base(typeof(string), null) - { - Sql = sql; - } + => Sql = sql; /// /// The string token to print in SQL tree. diff --git a/src/EFCore.Relational/Query/SqlExpressions/SqlFunctionExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/SqlFunctionExpression.cs index 0f9e2343055..534738fd96d 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/SqlFunctionExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/SqlFunctionExpression.cs @@ -220,7 +220,8 @@ public SqlFunctionExpression( /// A bool value indicating if the function is niladic. /// [MemberNotNullWhen(false, nameof(Arguments), nameof(ArgumentsPropagateNullability))] - public virtual bool IsNiladic => Arguments is null; + public virtual bool IsNiladic + => Arguments is null; /// /// A bool value indicating if the function is built-in. @@ -319,8 +320,10 @@ public virtual SqlFunctionExpression Update(SqlExpression? instance, IReadOnlyLi /// /// The property of the result. /// The property of the result. - /// The property of the result. If omitted, - /// the current ArgumentsPropagateNullability will be used. + /// + /// The property of the result. If omitted, + /// the current ArgumentsPropagateNullability will be used. + /// /// This expression if no children changed, or an expression with the updated children. public virtual SqlFunctionExpression Update( SqlExpression? instance, @@ -332,18 +335,18 @@ public virtual SqlFunctionExpression Update( || (argumentsPropagateNullability != null && ArgumentsPropagateNullability != null && argumentsPropagateNullability.SequenceEqual(ArgumentsPropagateNullability))) - ? this - : new SqlFunctionExpression( - instance, - Schema, - Name, - arguments, - IsNullable, - InstancePropagatesNullability, - argumentsPropagateNullability, - IsBuiltIn, - Type, - TypeMapping); + ? this + : new SqlFunctionExpression( + instance, + Schema, + Name, + arguments, + IsNullable, + InstancePropagatesNullability, + argumentsPropagateNullability, + IsBuiltIn, + Type, + TypeMapping); /// public override Expression Quote() diff --git a/src/EFCore.Relational/Query/SqlExpressions/SqlParameterExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/SqlParameterExpression.cs index 5e5ba92a6c7..7c0c58e2b82 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/SqlParameterExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/SqlParameterExpression.cs @@ -61,7 +61,7 @@ protected override Expression VisitChildren(ExpressionVisitor visitor) public override Expression Quote() => New( _quotingConstructor ??= typeof(SqlParameterExpression).GetConstructor( - [typeof(string), typeof(Type), typeof(RelationalTypeMapping) ])!, // TODO: There's a dead IsNullable there... + [typeof(string), typeof(Type), typeof(RelationalTypeMapping)])!, // TODO: There's a dead IsNullable there... Constant(Name, typeof(string)), Constant(Type), RelationalExpressionQuotingUtilities.QuoteTypeMapping(TypeMapping)); diff --git a/src/EFCore.Relational/Query/SqlExpressions/TableExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/TableExpression.cs index 828af3f201d..e9ed7bc3f85 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/TableExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/TableExpression.cs @@ -1,8 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; - namespace Microsoft.EntityFrameworkCore.Query.SqlExpressions; /// diff --git a/src/EFCore.Relational/Query/SqlExpressions/TableExpressionBase.cs b/src/EFCore.Relational/Query/SqlExpressions/TableExpressionBase.cs index f2ba6f94510..0a0a3f5eb69 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/TableExpressionBase.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/TableExpressionBase.cs @@ -1,8 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Collections.Immutable; - namespace Microsoft.EntityFrameworkCore.Query.SqlExpressions; /// @@ -143,7 +141,6 @@ public virtual TableExpressionBase AddAnnotation(string name, object? value) : throw new InvalidOperationException(CoreStrings.DuplicateAnnotation(name, this.Print())); } - var annotations = new SortedDictionary(); if (Annotations is not null) diff --git a/src/EFCore.Relational/Query/SqlExpressions/TableValuedFunctionExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/TableValuedFunctionExpression.cs index 784e00ac2a4..8e1044ca60a 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/TableValuedFunctionExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/TableValuedFunctionExpression.cs @@ -1,8 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; - namespace Microsoft.EntityFrameworkCore.Query.SqlExpressions; /// @@ -32,9 +30,7 @@ public TableValuedFunctionExpression(string alias, IStoreFunction storeFunction, storeFunction.IsBuiltIn, arguments, annotations: null) - { - StoreFunction = storeFunction; - } + => StoreFunction = storeFunction; /// /// Creates a new instance of the class. diff --git a/src/EFCore.Relational/Query/SqlExpressions/UnionExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/UnionExpression.cs index 70b83072cdb..02e8a4c581b 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/UnionExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/UnionExpression.cs @@ -90,7 +90,10 @@ public override UnionExpression WithAlias(string newAlias) public override Expression Quote() => New( _quotingConstructor ??= typeof(UnionExpression).GetConstructor( - [typeof(string), typeof(SelectExpression), typeof(SelectExpression), typeof(bool), typeof(IReadOnlyDictionary)])!, + [ + typeof(string), typeof(SelectExpression), typeof(SelectExpression), typeof(bool), + typeof(IReadOnlyDictionary) + ])!, Constant(Alias, typeof(string)), Source1.Quote(), Source2.Quote(), diff --git a/src/EFCore.Relational/Query/SqlExpressions/UpdateExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/UpdateExpression.cs index ec116006b05..994380a3e5d 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/UpdateExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/UpdateExpression.cs @@ -12,6 +12,7 @@ namespace Microsoft.EntityFrameworkCore.Query.SqlExpressions; /// not used in application code. /// /// +[DebuggerDisplay("{Microsoft.EntityFrameworkCore.Query.ExpressionPrinter.Print(this), nq}")] public sealed class UpdateExpression : Expression, IRelationalQuotableExpression, IPrintableExpression { private static ConstructorInfo? _quotingConstructor; @@ -79,7 +80,7 @@ public UpdateExpression ApplyTags(ISet tags) /// public override Type Type - => typeof(object); + => typeof(void); /// public override ExpressionType NodeType @@ -154,12 +155,16 @@ public Expression Quote() /// public void Print(ExpressionPrinter expressionPrinter) { - foreach (var tag in Tags) + if (Tags.Count > 0) { - expressionPrinter.Append($"-- {tag}"); + foreach (var tag in Tags) + { + expressionPrinter.Append($"-- {tag}"); + } + + expressionPrinter.AppendLine(); } - expressionPrinter.AppendLine(); expressionPrinter.AppendLine($"UPDATE {Table.Name} AS {Table.Alias}"); expressionPrinter.AppendLine("SET "); expressionPrinter.Visit(ColumnValueSetters[0].Column); diff --git a/src/EFCore.Relational/Query/SqlExpressions/ValuesExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/ValuesExpression.cs index 50b006b9c3c..5c79b84f3bb 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/ValuesExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/ValuesExpression.cs @@ -88,6 +88,7 @@ public ValuesExpression( columnNames.Count is 1 or 2, $"Column names do not match usage of {nameof(ValuesParameter)}"); } + if (!(rowValues is null ^ valuesParameter is null)) { throw new ArgumentException( @@ -141,8 +142,8 @@ public virtual ValuesExpression Update( && rowValues.Zip(RowValues, (x, y) => (x, y)).All(tup => tup.x == tup.y)) || (rowValues is null && RowValues is null)) && valuesParameter == ValuesParameter - ? this - : new ValuesExpression(Alias, rowValues, valuesParameter, ColumnNames, Annotations); + ? this + : new ValuesExpression(Alias, rowValues, valuesParameter, ColumnNames, Annotations); /// protected override ValuesExpression WithAnnotations(IReadOnlyDictionary annotations) @@ -164,7 +165,9 @@ public override Expression Quote() typeof(IReadOnlyDictionary) ])!, Constant(Alias, typeof(string)), - RowValues is not null ? NewArrayInit(typeof(RowValueExpression), RowValues.Select(rv => rv.Quote())) : Constant(null, typeof(RowValueExpression)), + RowValues is not null + ? NewArrayInit(typeof(RowValueExpression), RowValues.Select(rv => rv.Quote())) + : Constant(null, typeof(RowValueExpression)), RelationalExpressionQuotingUtilities.QuoteOrNull(ValuesParameter), NewArrayInit(typeof(string), ColumnNames.Select(Constant)), RelationalExpressionQuotingUtilities.QuoteAnnotations(Annotations)); @@ -180,6 +183,7 @@ public override TableExpressionBase Clone(string? alias, ExpressionVisitor cloni { newRowValues[i] = (RowValueExpression)cloningExpressionVisitor.Visit(RowValues[i]); } + return new ValuesExpression(alias, newRowValues, null, ColumnNames, Annotations); case { ValuesParameter: not null }: @@ -209,6 +213,7 @@ protected override void Print(ExpressionPrinter expressionPrinter) expressionPrinter.Append(", "); } } + break; case { ValuesParameter: not null }: @@ -233,7 +238,9 @@ private bool Equals(ValuesExpression? valuesExpression) => base.Equals(valuesExpression) && (ValuesParameter?.Equals(valuesExpression.ValuesParameter) ?? valuesExpression.ValuesParameter == null) && (ReferenceEquals(RowValues, valuesExpression.RowValues) - || (RowValues is not null && valuesExpression.RowValues is not null && RowValues.SequenceEqual(valuesExpression.RowValues))); + || (RowValues is not null + && valuesExpression.RowValues is not null + && RowValues.SequenceEqual(valuesExpression.RowValues))); /// public override int GetHashCode() diff --git a/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs b/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs index 3b740ca419e..be395e188a3 100644 --- a/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs +++ b/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs @@ -17,7 +17,7 @@ namespace Microsoft.EntityFrameworkCore.Query; /// not used in application code. /// /// -public class SqlNullabilityProcessor +public class SqlNullabilityProcessor : ExpressionVisitor { private readonly List _nonNullableColumns; private readonly List _nullValueColumns; @@ -56,7 +56,7 @@ public SqlNullabilityProcessor( /// /// A collection of parameter names to constantize. /// - protected virtual HashSet ParametersToConstantize { get; } + protected virtual IReadOnlySet ParametersToConstantize { get; } /// /// Dictionary of current parameter values in use. @@ -80,49 +80,13 @@ public virtual Expression Process( _nullValueColumns.Clear(); ParameterValues = parameterValues; - var result = queryExpression switch - { - SelectExpression selectExpression => (Expression)Visit(selectExpression), - DeleteExpression deleteExpression => deleteExpression.Update(deleteExpression.Table, Visit(deleteExpression.SelectExpression)), - UpdateExpression updateExpression => VisitUpdate(updateExpression), - _ => throw new InvalidOperationException(), - }; + var result = Visit(queryExpression); canCache = _canCache; return result; } - private UpdateExpression VisitUpdate(UpdateExpression updateExpression) - { - var selectExpression = Visit(updateExpression.SelectExpression); - List? columnValueSetters = null; - for (var (i, n) = (0, updateExpression.ColumnValueSetters.Count); i < n; i++) - { - var columnValueSetter = updateExpression.ColumnValueSetters[i]; - var newValue = Visit(columnValueSetter.Value, out _); - if (columnValueSetters != null) - { - columnValueSetters.Add(new ColumnValueSetter(columnValueSetter.Column, newValue)); - } - else if (!ReferenceEquals(newValue, columnValueSetter.Value)) - { - columnValueSetters = new List(n); - for (var j = 0; j < i; j++) - { - columnValueSetters.Add(updateExpression.ColumnValueSetters[j]); - } - - columnValueSetters.Add(new ColumnValueSetter(columnValueSetter.Column, newValue)); - } - } - - return selectExpression != updateExpression.SelectExpression - || columnValueSetters != null - ? updateExpression.Update(selectExpression, columnValueSetters ?? updateExpression.ColumnValueSetters) - : updateExpression; - } - /// /// Marks the select expression being processed as cannot be cached. /// @@ -136,35 +100,20 @@ protected virtual void DoNotCache() protected virtual void AddNonNullableColumn(ColumnExpression columnExpression) => _nonNullableColumns.Add(columnExpression); - /// - /// Visits a . - /// - /// A table expression base to visit. - /// An optimized table expression base. - protected virtual TableExpressionBase Visit(TableExpressionBase tableExpressionBase) + /// + protected override Expression VisitExtension(Expression node) { - switch (tableExpressionBase) + switch (node) { - case CrossApplyExpression crossApplyExpression: - return crossApplyExpression.Update(Visit(crossApplyExpression.Table)); - - case CrossJoinExpression crossJoinExpression: - return crossJoinExpression.Update(Visit(crossJoinExpression.Table)); - - case ExceptExpression exceptExpression: - { - var source1 = Visit(exceptExpression.Source1); - var source2 = Visit(exceptExpression.Source2); - - return exceptExpression.Update(source1, source2); - } + case SqlExpression sqlExpression: + return Visit(sqlExpression, allowOptimizedExpansion: false, out _); - case FromSqlExpression fromSqlExpression: - return fromSqlExpression; + case SelectExpression select: + return Visit(select); case InnerJoinExpression innerJoinExpression: { - var newTable = Visit(innerJoinExpression.Table); + var newTable = VisitAndConvert(innerJoinExpression.Table, nameof(VisitExtension)); var newJoinPredicate = ProcessJoinPredicate(innerJoinExpression.JoinPredicate); return IsTrue(newJoinPredicate) @@ -172,230 +121,92 @@ protected virtual TableExpressionBase Visit(TableExpressionBase tableExpressionB : innerJoinExpression.Update(newTable, newJoinPredicate); } - case IntersectExpression intersectExpression: - { - var source1 = Visit(intersectExpression.Source1); - var source2 = Visit(intersectExpression.Source2); - - return intersectExpression.Update(source1, source2); - } - case LeftJoinExpression leftJoinExpression: { - var newTable = Visit(leftJoinExpression.Table); + var newTable = VisitAndConvert(leftJoinExpression.Table, nameof(VisitExtension)); var newJoinPredicate = ProcessJoinPredicate(leftJoinExpression.JoinPredicate); return leftJoinExpression.Update(newTable, newJoinPredicate); } - case OuterApplyExpression outerApplyExpression: - return outerApplyExpression.Update(Visit(outerApplyExpression.Table)); - - case ValuesExpression valuesExpression: + case ValuesExpression { ValuesParameter: SqlParameterExpression valuesParameter } valuesExpression: { - switch (valuesExpression) - { - case { RowValues: not null }: - RowValueExpression[]? newRowValues = null; - for (var i = 0; i < valuesExpression.RowValues.Count; i++) - { - var rowValue = valuesExpression.RowValues[i]; - var newRowValue = (RowValueExpression)VisitRowValue(rowValue, allowOptimizedExpansion: false, out _); - - if (newRowValue != rowValue && newRowValues is null) - { - newRowValues = new RowValueExpression[valuesExpression.RowValues.Count]; - for (var j = 0; j < i; j++) - { - newRowValues[j] = valuesExpression.RowValues[j]; - } - } - - if (newRowValues is not null) - { - newRowValues[i] = newRowValue; - } - } - return newRowValues is not null - ? valuesExpression.Update(newRowValues) - : valuesExpression; - - case { ValuesParameter: SqlParameterExpression valuesParameter }: - DoNotCache(); - Check.DebugAssert(valuesParameter.TypeMapping is not null, "valuesParameter.TypeMapping is not null"); - Check.DebugAssert(valuesParameter.TypeMapping.ElementTypeMapping is not null, "valuesParameter.TypeMapping.ElementTypeMapping is not null"); - var typeMapping = (RelationalTypeMapping)valuesParameter.TypeMapping.ElementTypeMapping; - var values = (IEnumerable?)ParameterValues[valuesParameter.Name] ?? Array.Empty(); - - var processedValues = new List(); - foreach (var value in values) - { - processedValues.Add( - new RowValueExpression([ - _sqlExpressionFactory.Constant(value, value?.GetType() ?? typeof(object), typeMapping)])); - } - return processedValues is not [] - ? valuesExpression.Update(processedValues) - : valuesExpression; - - default: - throw new UnreachableException(); - } - } - - case SelectExpression selectExpression: - return Visit(selectExpression); + DoNotCache(); + Check.DebugAssert(valuesParameter.TypeMapping is not null, "valuesParameter.TypeMapping is not null"); + Check.DebugAssert( + valuesParameter.TypeMapping.ElementTypeMapping is not null, + "valuesParameter.TypeMapping.ElementTypeMapping is not null"); + var typeMapping = (RelationalTypeMapping)valuesParameter.TypeMapping.ElementTypeMapping; + var values = (IEnumerable?)ParameterValues[valuesParameter.Name] ?? Array.Empty(); - case TableValuedFunctionExpression tableValuedFunctionExpression: - { - var arguments = new List(); - foreach (var argument in tableValuedFunctionExpression.Arguments) + var processedValues = new List(); + foreach (var value in values) { - arguments.Add(Visit(argument, out _)); + processedValues.Add( + new RowValueExpression( + [ + _sqlExpressionFactory.Constant(value, value?.GetType() ?? typeof(object), typeMapping) + ])); } - return tableValuedFunctionExpression.Update(arguments); + return processedValues is not [] + ? valuesExpression.Update(processedValues) + : valuesExpression; } - case TableExpression tableExpression: - return tableExpression; + default: + return base.VisitExtension(node); + } - case UnionExpression unionExpression: + SqlExpression ProcessJoinPredicate(SqlExpression predicate) + { + switch (predicate) { - var source1 = Visit(unionExpression.Source1); - var source2 = Visit(unionExpression.Source2); + case SqlBinaryExpression { OperatorType: ExpressionType.Equal } binary: + var left = Visit(binary.Left, allowOptimizedExpansion: true, out var leftNullable); + var right = Visit(binary.Right, allowOptimizedExpansion: true, out var rightNullable); + + var result = OptimizeComparison( + binary.Update(left, right), + left, + right, + leftNullable, + rightNullable, + out _); - return unionExpression.Update(source1, source2); - } + return result; - default: - throw new InvalidOperationException( - RelationalStrings.UnhandledExpressionInVisitor( - tableExpressionBase, tableExpressionBase.GetType(), nameof(SqlNullabilityProcessor))); + case SqlBinaryExpression { OperatorType: + ExpressionType.AndAlso + or ExpressionType.NotEqual + or ExpressionType.GreaterThan + or ExpressionType.GreaterThanOrEqual + or ExpressionType.LessThan + or ExpressionType.LessThanOrEqual } binary: + return Visit(binary, allowOptimizedExpansion: true, out _); + + default: + throw new InvalidOperationException( + RelationalStrings.UnhandledExpressionInVisitor(predicate, predicate.GetType(), nameof(SqlNullabilityProcessor))); + } } } - /// - /// Visits a . - /// - /// A select expression to visit. - /// An optimized select expression. - protected virtual SelectExpression Visit(SelectExpression selectExpression) - => Visit(selectExpression, visitProjection: true); - /// /// Visits a . /// /// A select expression to visit. /// Allows skipping visiting the projection, for when it will be visited outside. /// An optimized select expression. - protected virtual SelectExpression Visit(SelectExpression selectExpression, bool visitProjection) + protected virtual SelectExpression Visit(SelectExpression selectExpression, bool visitProjection = true) { - var projections = (List)selectExpression.Projection; - if (visitProjection) - { - for (var i = 0; i < selectExpression.Projection.Count; i++) - { - var item = selectExpression.Projection[i]; - var projection = item.Update(Visit(item.Expression, out _)); - if (projection != item - && projections == selectExpression.Projection) - { - projections = []; - for (var j = 0; j < i; j++) - { - projections.Add(selectExpression.Projection[j]); - } - - - } - - if (projections != selectExpression.Projection) - { - projections.Add(projection); - } - } - } - - var tables = (List)selectExpression.Tables; - for (var i = 0; i < selectExpression.Tables.Count; i++) - { - var item = selectExpression.Tables[i]; - var table = Visit(item); - if (table != item - && tables == selectExpression.Tables) - { - tables = []; - for (var j = 0; j < i; j++) - { - tables.Add(selectExpression.Tables[j]); - } - } - - if (tables != selectExpression.Tables) - { - tables.Add(table); - } - } - + var tables = this.VisitAndConvert(selectExpression.Tables); var predicate = Visit(selectExpression.Predicate, allowOptimizedExpansion: true, out _); - - if (IsTrue(predicate)) - { - predicate = null; - } - - var groupBy = (List)selectExpression.GroupBy; - for (var i = 0; i < selectExpression.GroupBy.Count; i++) - { - var item = selectExpression.GroupBy[i]; - var groupingKey = Visit(item, out _); - if (groupingKey != item - && groupBy == selectExpression.GroupBy) - { - groupBy = []; - for (var j = 0; j < i; j++) - { - groupBy.Add(selectExpression.GroupBy[j]); - } - } - - if (groupBy != selectExpression.GroupBy) - { - groupBy.Add(groupingKey); - } - } - + var groupBy = this.VisitAndConvert(selectExpression.GroupBy); var having = Visit(selectExpression.Having, allowOptimizedExpansion: true, out _); - - if (IsTrue(having)) - { - having = null; - } - - var orderings = (List)selectExpression.Orderings; - for (var i = 0; i < selectExpression.Orderings.Count; i++) - { - var item = selectExpression.Orderings[i]; - var ordering = item.Update(Visit(item.Expression, out _)); - if (ordering != item - && orderings == selectExpression.Orderings) - { - orderings = []; - for (var j = 0; j < i; j++) - { - orderings.Add(selectExpression.Orderings[j]); - } - } - - if (orderings != selectExpression.Orderings) - { - orderings.Add(ordering); - } - } - + var projections = visitProjection ? this.VisitAndConvert(selectExpression.Projection) : selectExpression.Projection; + var orderings = this.VisitAndConvert(selectExpression.Orderings); var offset = Visit(selectExpression.Offset, out _); - var limit = Visit(selectExpression.Limit, out _); return selectExpression.Update(tables, predicate, groupBy, having, projections, orderings, offset, limit); @@ -546,7 +357,8 @@ protected virtual SqlExpression VisitCase(CaseExpression caseExpression, bool al var testCondition = testIsCondition ? test - : Visit(_sqlExpressionFactory.Equal(operand!, test), + : Visit( + _sqlExpressionFactory.Equal(operand!, test), allowOptimizedExpansion: testIsCondition, preserveColumnNullabilityInformation: true, out _); if (IsTrue(testCondition)) @@ -1151,33 +963,13 @@ protected virtual SqlExpression VisitRowValue( bool allowOptimizedExpansion, out bool nullable) { - SqlExpression[]? newValues = null; - - for (var i = 0; i < rowValueExpression.Values.Count; i++) - { - var value = rowValueExpression.Values[i]; - - // Note that we disallow optimized expansion, since the null vs. false distinction does matter inside the row's values - var newValue = Visit(value, allowOptimizedExpansion: false, out _); - if (newValue != value && newValues is null) - { - newValues = new SqlExpression[rowValueExpression.Values.Count]; - for (var j = 0; j < i; j++) - { - newValues[j] = rowValueExpression.Values[j]; - } - } - - if (newValues is not null) - { - newValues[i] = newValue; - } - } + // Note that we disallow optimized expansion, since the null vs. false distinction does matter inside the row's values + var newValues = this.VisitAndConvert(rowValueExpression.Values); // The row value expression itself can never be null nullable = false; - return rowValueExpression.Update(newValues ?? rowValueExpression.Values); + return rowValueExpression.Update(newValues); } /// @@ -1229,7 +1021,8 @@ protected virtual SqlExpression VisitSqlBinary( { return Visit(sqlBinaryExpression.Right, allowOptimizedExpansion, out nullable); } - else if (IsTrue(sqlBinaryExpression.Right) && sqlBinaryExpression.Right.TypeMapping!.Converter == null) + + if (IsTrue(sqlBinaryExpression.Right) && sqlBinaryExpression.Right.TypeMapping!.Converter == null) { return Visit(sqlBinaryExpression.Left, allowOptimizedExpansion, out nullable); } @@ -1365,11 +1158,13 @@ protected virtual SqlExpression VisitSqlBinary( nullable = leftNullable || rightNullable; var result = sqlBinaryExpression.Update(left, right); - if (nullable && !optimize && result.OperatorType - is ExpressionType.GreaterThan - or ExpressionType.GreaterThanOrEqual - or ExpressionType.LessThan - or ExpressionType.LessThanOrEqual) + if (nullable + && !optimize + && result.OperatorType + is ExpressionType.GreaterThan + or ExpressionType.GreaterThanOrEqual + or ExpressionType.LessThan + or ExpressionType.LessThanOrEqual) { // https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/nullable-value-types#lifted-operators // For the comparison operators <, >, <=, and >=, if one or both @@ -1382,7 +1177,7 @@ or ExpressionType.LessThan nullable = false; return _sqlExpressionFactory.Case( - [new(result, _sqlExpressionFactory.Constant(true, result.TypeMapping))], + [new CaseWhenClause(result, _sqlExpressionFactory.Constant(true, result.TypeMapping))], _sqlExpressionFactory.Constant(false, result.TypeMapping) ); } @@ -1655,41 +1450,6 @@ private void RestoreNullValueColumnsList(int counter) } } - private SqlExpression ProcessJoinPredicate(SqlExpression predicate) - { - if (predicate is SqlBinaryExpression sqlBinaryExpression) - { - if (sqlBinaryExpression.OperatorType == ExpressionType.Equal) - { - var left = Visit(sqlBinaryExpression.Left, allowOptimizedExpansion: true, out var leftNullable); - var right = Visit(sqlBinaryExpression.Right, allowOptimizedExpansion: true, out var rightNullable); - - var result = OptimizeComparison( - sqlBinaryExpression.Update(left, right), - left, - right, - leftNullable, - rightNullable, - out _); - - return result; - } - - if (sqlBinaryExpression.OperatorType is ExpressionType.AndAlso - or ExpressionType.NotEqual - or ExpressionType.GreaterThan - or ExpressionType.GreaterThanOrEqual - or ExpressionType.LessThan - or ExpressionType.LessThanOrEqual) - { - return Visit(sqlBinaryExpression, allowOptimizedExpansion: true, out _); - } - } - - throw new InvalidOperationException( - RelationalStrings.UnhandledExpressionInVisitor(predicate, predicate.GetType(), nameof(SqlNullabilityProcessor))); - } - private SqlExpression OptimizeComparison( SqlBinaryExpression sqlBinaryExpression, SqlExpression left, @@ -2284,7 +2044,7 @@ private SqlExpression ProcessNullNotNull(SqlExpression sqlExpression, bool opera return result; } } - break; + break; } return sqlUnaryExpression; diff --git a/src/EFCore.Relational/Query/SqlTreePruner.cs b/src/EFCore.Relational/Query/SqlTreePruner.cs index 18746cfc999..bc80eac58b3 100644 --- a/src/EFCore.Relational/Query/SqlTreePruner.cs +++ b/src/EFCore.Relational/Query/SqlTreePruner.cs @@ -21,7 +21,8 @@ public class SqlTreePruner : ExpressionVisitor /// /// Maps table aliases to the list of column aliases found referenced on them. /// - protected virtual IReadOnlyDictionary> ReferencedColumnMap => _referencedColumnMap; + protected virtual IReadOnlyDictionary> ReferencedColumnMap + => _referencedColumnMap; /// /// When visiting a nested (e.g. a select within a set operation), this holds the table alias @@ -187,7 +188,7 @@ protected virtual SelectExpression PruneSelect(SelectExpression select, bool pre if (visitedProjection != projection && projections is null) { - projections = new(select.Projection.Count); + projections = new List(select.Projection.Count); for (var j = 0; j < i; j++) { projections.Add(select.Projection[j]); diff --git a/src/EFCore.Relational/Query/StructuralTypeProjectionExpression.cs b/src/EFCore.Relational/Query/StructuralTypeProjectionExpression.cs index 1561af692fe..0a643036eab 100644 --- a/src/EFCore.Relational/Query/StructuralTypeProjectionExpression.cs +++ b/src/EFCore.Relational/Query/StructuralTypeProjectionExpression.cs @@ -116,22 +116,22 @@ private StructuralTypeProjectionExpression( public virtual SqlExpression? DiscriminatorExpression { get; } /// - /// The of the . + /// The of the . /// public sealed override ExpressionType NodeType => ExpressionType.Extension; /// - /// The of the value represented by this . + /// The of the value represented by this . /// public override Type Type => StructuralType.ClrType; /// - /// Reduces the node and then calls the method passing the reduced expression. + /// Reduces the node and then calls the method passing the reduced expression. /// Throws an exception if the node isn't reducible. /// - /// An instance of . + /// An instance of . /// The expression being visited, or an expression which should replace it in the tree. /// /// Override this method to provide logic to walk the node's children. @@ -154,7 +154,7 @@ protected override Expression VisitChildren(ExpressionVisitor visitor) var complexPropertyCache = default(Dictionary); if (_complexPropertyCache != null) { - complexPropertyCache = new(); + complexPropertyCache = new Dictionary(); foreach (var (complexProperty, complexShaper) in _complexPropertyCache) { var newComplexShaper = (StructuralTypeShaperExpression)visitor.Visit(complexShaper); @@ -176,7 +176,8 @@ protected override Expression VisitChildren(ExpressionVisitor visitor) return changed ? new StructuralTypeProjectionExpression( - StructuralType, propertyExpressionMap, ownedNavigationMap, complexPropertyCache, TableMap, IsNullable, discriminatorExpression) + StructuralType, propertyExpressionMap, ownedNavigationMap, complexPropertyCache, TableMap, IsNullable, + discriminatorExpression) : this; } @@ -195,7 +196,7 @@ public virtual StructuralTypeProjectionExpression MakeNullable() var complexPropertyCache = default(Dictionary); if (_complexPropertyCache != null) { - complexPropertyCache = new(); + complexPropertyCache = new Dictionary(); foreach (var (complexProperty, complexShaper) in _complexPropertyCache) { complexPropertyCache[complexProperty] = complexShaper.MakeNullable(); @@ -266,7 +267,7 @@ public virtual StructuralTypeProjectionExpression UpdateEntityType(IEntityType d var complexPropertyCache = default(Dictionary); if (_complexPropertyCache != null) { - complexPropertyCache = new(); + complexPropertyCache = new Dictionary(); foreach (var (complexProperty, complexShaper) in _complexPropertyCache) { if (derivedType.IsAssignableFrom(complexProperty.DeclaringType) @@ -328,7 +329,8 @@ public virtual StructuralTypeProjectionExpression UpdateEntityType(IEntityType d } return new StructuralTypeProjectionExpression( - derivedType, propertyExpressionMap, ownedNavigationMap, complexPropertyCache, newTableMap ?? TableMap, IsNullable, discriminatorExpression); + derivedType, propertyExpressionMap, ownedNavigationMap, complexPropertyCache, newTableMap ?? TableMap, IsNullable, + discriminatorExpression); } /// @@ -339,8 +341,9 @@ public virtual StructuralTypeProjectionExpression UpdateEntityType(IEntityType d /// [EntityFrameworkInternal] public virtual StructuralTypeProjectionExpression UpdateTableMap(IReadOnlyDictionary newTableMap) - => new StructuralTypeProjectionExpression( - StructuralType, _propertyExpressionMap, _ownedNavigationMap, _complexPropertyCache, newTableMap, IsNullable, DiscriminatorExpression); + => new( + StructuralType, _propertyExpressionMap, _ownedNavigationMap, _complexPropertyCache, newTableMap, IsNullable, + DiscriminatorExpression); /// /// Binds a property with this structural type projection to get the SQL representation. @@ -418,9 +421,7 @@ public virtual void AddNavigationBinding(INavigation navigation, StructuralTypeS RelationalStrings.UnableToBindMemberToEntityProjection("navigation", navigation.Name, entityType.DisplayName())); } - return _ownedNavigationMap.TryGetValue(navigation, out var expression) - ? expression - : null; + return _ownedNavigationMap.GetValueOrDefault(navigation); } /// diff --git a/src/EFCore.Relational/Scaffolding/ProviderCodeGenerator.cs b/src/EFCore.Relational/Scaffolding/ProviderCodeGenerator.cs index c5936400ce5..2658f6f98a7 100644 --- a/src/EFCore.Relational/Scaffolding/ProviderCodeGenerator.cs +++ b/src/EFCore.Relational/Scaffolding/ProviderCodeGenerator.cs @@ -24,9 +24,7 @@ public abstract class ProviderCodeGenerator : IProviderConfigurationCodeGenerato /// /// The dependencies. protected ProviderCodeGenerator(ProviderCodeGeneratorDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Relational provider-specific dependencies for this service. diff --git a/src/EFCore.Relational/Scaffolding/ProviderCodeGeneratorDependencies.cs b/src/EFCore.Relational/Scaffolding/ProviderCodeGeneratorDependencies.cs index beb6d9049f1..bfb77a9e842 100644 --- a/src/EFCore.Relational/Scaffolding/ProviderCodeGeneratorDependencies.cs +++ b/src/EFCore.Relational/Scaffolding/ProviderCodeGeneratorDependencies.cs @@ -38,9 +38,7 @@ public sealed record ProviderCodeGeneratorDependencies /// [EntityFrameworkInternal] public ProviderCodeGeneratorDependencies(IEnumerable plugins) - { - Plugins = plugins; - } + => Plugins = plugins; /// /// Gets the plugins. diff --git a/src/EFCore.Relational/Storage/Internal/CompositeRelationalParameter.cs b/src/EFCore.Relational/Storage/Internal/CompositeRelationalParameter.cs index 9e743c73c05..6216d4a04b2 100644 --- a/src/EFCore.Relational/Storage/Internal/CompositeRelationalParameter.cs +++ b/src/EFCore.Relational/Storage/Internal/CompositeRelationalParameter.cs @@ -21,9 +21,7 @@ public CompositeRelationalParameter( string invariantName, IReadOnlyList relationalParameters) : base(invariantName) - { - RelationalParameters = relationalParameters; - } + => RelationalParameters = relationalParameters; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Relational/Storage/Internal/NamedConnectionStringResolver.cs b/src/EFCore.Relational/Storage/Internal/NamedConnectionStringResolver.cs index ab6cd8153e1..eb73389d26f 100644 --- a/src/EFCore.Relational/Storage/Internal/NamedConnectionStringResolver.cs +++ b/src/EFCore.Relational/Storage/Internal/NamedConnectionStringResolver.cs @@ -20,9 +20,7 @@ public class NamedConnectionStringResolver : NamedConnectionStringResolverBase, /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public NamedConnectionStringResolver(IDbContextOptions options) - { - _options = options; - } + => _options = options; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Relational/Storage/Internal/RawRelationalParameter.cs b/src/EFCore.Relational/Storage/Internal/RawRelationalParameter.cs index a63a0270d1e..d6b90807313 100644 --- a/src/EFCore.Relational/Storage/Internal/RawRelationalParameter.cs +++ b/src/EFCore.Relational/Storage/Internal/RawRelationalParameter.cs @@ -25,9 +25,7 @@ public RawRelationalParameter( string invariantName, DbParameter parameter) : base(invariantName) - { - _parameter = parameter; - } + => _parameter = parameter; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Relational/Storage/Internal/RelationalParameterBase.cs b/src/EFCore.Relational/Storage/Internal/RelationalParameterBase.cs index f36da036aea..53c31de4db7 100644 --- a/src/EFCore.Relational/Storage/Internal/RelationalParameterBase.cs +++ b/src/EFCore.Relational/Storage/Internal/RelationalParameterBase.cs @@ -18,9 +18,7 @@ public abstract class RelationalParameterBase : IRelationalParameter /// doing so can result in application failures when updating to a new Entity Framework Core release. /// protected RelationalParameterBase(string invariantName) - { - InvariantName = invariantName; - } + => InvariantName = invariantName; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Relational/Storage/ParameterNameGeneratorFactory.cs b/src/EFCore.Relational/Storage/ParameterNameGeneratorFactory.cs index fddf8a7f631..dd0a0f3fcfa 100644 --- a/src/EFCore.Relational/Storage/ParameterNameGeneratorFactory.cs +++ b/src/EFCore.Relational/Storage/ParameterNameGeneratorFactory.cs @@ -30,9 +30,7 @@ public class ParameterNameGeneratorFactory : IParameterNameGeneratorFactory /// /// Parameter object containing dependencies for this service. public ParameterNameGeneratorFactory(ParameterNameGeneratorDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Relational provider-specific dependencies for this service. diff --git a/src/EFCore.Relational/Storage/ReaderColumn`.cs b/src/EFCore.Relational/Storage/ReaderColumn`.cs index 58af0f86816..fa473db99ea 100644 --- a/src/EFCore.Relational/Storage/ReaderColumn`.cs +++ b/src/EFCore.Relational/Storage/ReaderColumn`.cs @@ -34,9 +34,7 @@ public ReaderColumn( IPropertyBase? property, Expression> getFieldValueExpression) : base(typeof(T), nullable, name, property, getFieldValueExpression) - { - GetFieldValue = getFieldValueExpression.Compile(); - } + => GetFieldValue = getFieldValueExpression.Compile(); /// /// The function to get field value for the column from the reader. diff --git a/src/EFCore.Relational/Storage/RelationalCommandBuilder.cs b/src/EFCore.Relational/Storage/RelationalCommandBuilder.cs index 8ecbdba5eea..04313967eb6 100644 --- a/src/EFCore.Relational/Storage/RelationalCommandBuilder.cs +++ b/src/EFCore.Relational/Storage/RelationalCommandBuilder.cs @@ -21,9 +21,7 @@ public class RelationalCommandBuilder : IRelationalCommandBuilder /// Parameter object containing dependencies for this service. public RelationalCommandBuilder( RelationalCommandBuilderDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Relational provider-specific dependencies for this service. diff --git a/src/EFCore.Relational/Storage/RelationalCommandBuilderFactory.cs b/src/EFCore.Relational/Storage/RelationalCommandBuilderFactory.cs index e85f5122bc5..3ea3aa3c34a 100644 --- a/src/EFCore.Relational/Storage/RelationalCommandBuilderFactory.cs +++ b/src/EFCore.Relational/Storage/RelationalCommandBuilderFactory.cs @@ -37,9 +37,7 @@ public class RelationalCommandBuilderFactory : IRelationalCommandBuilderFactory /// Parameter object containing dependencies for this service. public RelationalCommandBuilderFactory( RelationalCommandBuilderDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Relational provider-specific dependencies for this service. diff --git a/src/EFCore.Relational/Storage/RelationalDatabase.cs b/src/EFCore.Relational/Storage/RelationalDatabase.cs index bef2f7acaf1..bf7f13c4041 100644 --- a/src/EFCore.Relational/Storage/RelationalDatabase.cs +++ b/src/EFCore.Relational/Storage/RelationalDatabase.cs @@ -1,8 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Threading; - namespace Microsoft.EntityFrameworkCore.Storage; /// @@ -39,9 +37,7 @@ public RelationalDatabase( DatabaseDependencies dependencies, RelationalDatabaseDependencies relationalDependencies) : base(dependencies) - { - RelationalDependencies = relationalDependencies; - } + => RelationalDependencies = relationalDependencies; private IUpdateAdapter UpdateAdapter => _updateAdapter ??= Dependencies.UpdateAdapterFactory.Create(); @@ -59,8 +55,8 @@ private IUpdateAdapter UpdateAdapter public override int SaveChanges(IList entries) { var result = RelationalDependencies.BatchExecutor.Execute( - RelationalDependencies.BatchPreparer.BatchCommands(entries, UpdateAdapter), - RelationalDependencies.Connection); + RelationalDependencies.BatchPreparer.BatchCommands(entries, UpdateAdapter), + RelationalDependencies.Connection); RelationalDependencies.BatchPreparer.ResetState(); @@ -82,9 +78,9 @@ public override async Task SaveChangesAsync( CancellationToken cancellationToken = default) { var result = await RelationalDependencies.BatchExecutor.ExecuteAsync( - RelationalDependencies.BatchPreparer.BatchCommands(entries, UpdateAdapter), - RelationalDependencies.Connection, - cancellationToken).ConfigureAwait(false); + RelationalDependencies.BatchPreparer.BatchCommands(entries, UpdateAdapter), + RelationalDependencies.Connection, + cancellationToken).ConfigureAwait(false); await RelationalDependencies.BatchPreparer.ResetStateAsync(cancellationToken).ConfigureAwait(false); diff --git a/src/EFCore.Relational/Storage/RelationalDatabaseCreator.cs b/src/EFCore.Relational/Storage/RelationalDatabaseCreator.cs index dbbd3b083fb..96f5ca0f76a 100644 --- a/src/EFCore.Relational/Storage/RelationalDatabaseCreator.cs +++ b/src/EFCore.Relational/Storage/RelationalDatabaseCreator.cs @@ -34,9 +34,7 @@ public abstract class RelationalDatabaseCreator : IRelationalDatabaseCreator /// /// Parameter object containing dependencies for this service. protected RelationalDatabaseCreator(RelationalDatabaseCreatorDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Relational provider-specific dependencies for this service. @@ -118,7 +116,7 @@ public virtual Task DeleteAsync(CancellationToken cancellationToken = default) /// to incrementally update the schema. It is assumed that none of the tables exist in the database. /// public virtual void CreateTables() - => Dependencies.MigrationCommandExecutor.ExecuteNonQuery(GetCreateTablesCommands(), Dependencies.Connection); + => Dependencies.MigrationCommandExecutor.ExecuteNonQuery(GetCreateTablesCommands(), Dependencies.Connection, new MigrationExecutionState(), commitTransaction: true); /// /// Asynchronously creates all tables for the current model in the database. No attempt is made @@ -131,7 +129,7 @@ public virtual void CreateTables() /// If the is canceled. public virtual Task CreateTablesAsync(CancellationToken cancellationToken = default) => Dependencies.MigrationCommandExecutor.ExecuteNonQueryAsync( - GetCreateTablesCommands(), Dependencies.Connection, cancellationToken); + GetCreateTablesCommands(), Dependencies.Connection, new MigrationExecutionState(), commitTransaction: true, cancellationToken: cancellationToken); /// /// Gets the commands that will create all tables from the model. @@ -234,23 +232,40 @@ public virtual async Task EnsureDeletedAsync(CancellationToken cancellatio /// public virtual bool EnsureCreated() { - using (new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled)) + using var transactionScope = new TransactionScope( + TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled); + + var operationsPerformed = false; + if (!Exists()) + { + Create(); + CreateTables(); + operationsPerformed = true; + } + else if (!HasTables()) { - if (!Exists()) - { - Create(); - CreateTables(); - return true; - } - - if (!HasTables()) - { - CreateTables(); - return true; - } + CreateTables(); + operationsPerformed = true; } - return false; + var coreOptionsExtension = + Dependencies.ContextOptions.FindExtension() + ?? new CoreOptionsExtension(); + + var seed = coreOptionsExtension.Seeder; + if (seed != null) + { + var context = Dependencies.CurrentContext.Context; + using var transaction = context.Database.BeginTransaction(); + seed(context, operationsPerformed); + transaction.Commit(); + } + else if (coreOptionsExtension.AsyncSeeder != null) + { + throw new InvalidOperationException(CoreStrings.MissingSeeder); + } + + return operationsPerformed; } /// @@ -266,30 +281,42 @@ public virtual bool EnsureCreated() /// If the is canceled. public virtual async Task EnsureCreatedAsync(CancellationToken cancellationToken = default) { - var transactionScope = new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled); - try + using var transactionScope = new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled); + + var operationsPerformed = false; + if (!await ExistsAsync(cancellationToken).ConfigureAwait(false)) + { + await CreateAsync(cancellationToken).ConfigureAwait(false); + await CreateTablesAsync(cancellationToken).ConfigureAwait(false); + + operationsPerformed = true; + } + else if (!await HasTablesAsync(cancellationToken).ConfigureAwait(false)) { - if (!await ExistsAsync(cancellationToken).ConfigureAwait(false)) - { - await CreateAsync(cancellationToken).ConfigureAwait(false); - await CreateTablesAsync(cancellationToken).ConfigureAwait(false); + await CreateTablesAsync(cancellationToken).ConfigureAwait(false); - return true; - } + operationsPerformed = true; + } - if (!await HasTablesAsync(cancellationToken).ConfigureAwait(false)) - { - await CreateTablesAsync(cancellationToken).ConfigureAwait(false); + var coreOptionsExtension = + Dependencies.ContextOptions.FindExtension() + ?? new CoreOptionsExtension(); - return true; - } + var seedAsync = coreOptionsExtension.AsyncSeeder; + if (seedAsync != null) + { + var context = Dependencies.CurrentContext.Context; + var transaction = await context.Database.BeginTransactionAsync(cancellationToken).ConfigureAwait(false); + await using var _ = transaction.ConfigureAwait(false); + await seedAsync(context, operationsPerformed, cancellationToken).ConfigureAwait(false); + await transaction.CommitAsync(cancellationToken).ConfigureAwait(false); } - finally + else if (coreOptionsExtension.Seeder != null) { - await transactionScope.DisposeAsyncIfAvailable().ConfigureAwait(false); + throw new InvalidOperationException(CoreStrings.MissingSeeder); } - return false; + return operationsPerformed; } /// diff --git a/src/EFCore.Relational/Storage/RelationalDatabaseCreatorDependencies.cs b/src/EFCore.Relational/Storage/RelationalDatabaseCreatorDependencies.cs index 0b14d27ec79..8343a802486 100644 --- a/src/EFCore.Relational/Storage/RelationalDatabaseCreatorDependencies.cs +++ b/src/EFCore.Relational/Storage/RelationalDatabaseCreatorDependencies.cs @@ -53,6 +53,7 @@ public RelationalDatabaseCreatorDependencies( ISqlGenerationHelper sqlGenerationHelper, IExecutionStrategy executionStrategy, ICurrentDbContext currentContext, + IDbContextOptions contextOptions, IRelationalCommandDiagnosticsLogger commandLogger) { Connection = connection; @@ -62,6 +63,7 @@ public RelationalDatabaseCreatorDependencies( SqlGenerationHelper = sqlGenerationHelper; ExecutionStrategy = executionStrategy; CurrentContext = currentContext; + ContextOptions = contextOptions; CommandLogger = commandLogger; } @@ -100,6 +102,11 @@ public RelationalDatabaseCreatorDependencies( /// public IRelationalCommandDiagnosticsLogger CommandLogger { get; init; } + /// + /// Gets the context options. + /// + public IDbContextOptions ContextOptions { get; init; } + /// /// Contains the currently in use. /// diff --git a/src/EFCore.Relational/Storage/RelationalGeometryTypeMapping.cs b/src/EFCore.Relational/Storage/RelationalGeometryTypeMapping.cs index 6efad3625cc..efc7fea9d3b 100644 --- a/src/EFCore.Relational/Storage/RelationalGeometryTypeMapping.cs +++ b/src/EFCore.Relational/Storage/RelationalGeometryTypeMapping.cs @@ -29,9 +29,7 @@ protected RelationalGeometryTypeMapping( string storeType, JsonValueReaderWriter? jsonValueReaderWriter = null) : base(CreateRelationalTypeMappingParameters(storeType, jsonValueReaderWriter)) - { - SpatialConverter = converter; - } + => SpatialConverter = converter; /// /// Initializes a new instance of the class. @@ -51,9 +49,7 @@ parameters.CoreParameters with parameters.CoreParameters.Converter?.ProviderClrType ?? parameters.CoreParameters.ClrType) : throw new InvalidOperationException(CoreStrings.NativeAotNoCompiledModel)) })) - { - SpatialConverter = converter; - } + => SpatialConverter = converter; private static ValueComparer? CreateProviderValueComparer(Type providerType) => providerType.IsAssignableTo(typeof(TGeometry)) diff --git a/src/EFCore.Relational/Storage/RelationalSqlGenerationHelper.cs b/src/EFCore.Relational/Storage/RelationalSqlGenerationHelper.cs index 75877959252..30773f67e16 100644 --- a/src/EFCore.Relational/Storage/RelationalSqlGenerationHelper.cs +++ b/src/EFCore.Relational/Storage/RelationalSqlGenerationHelper.cs @@ -33,9 +33,7 @@ public class RelationalSqlGenerationHelper : ISqlGenerationHelper /// /// Parameter object containing dependencies for this service. public RelationalSqlGenerationHelper(RelationalSqlGenerationHelperDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Relational provider-specific dependencies for this service. @@ -76,9 +74,7 @@ public virtual string SingleLineCommentToken /// A valid name based on the candidate name. /// public virtual string GenerateParameterName(string name) - => name.StartsWith("@", StringComparison.Ordinal) - ? name - : "@" + name; + => name.StartsWith('@') ? name : "@" + name; /// /// Writes a valid parameter name for the given candidate name. diff --git a/src/EFCore.Relational/Storage/RelationalTransactionFactory.cs b/src/EFCore.Relational/Storage/RelationalTransactionFactory.cs index e12e94e2c18..71056182f20 100644 --- a/src/EFCore.Relational/Storage/RelationalTransactionFactory.cs +++ b/src/EFCore.Relational/Storage/RelationalTransactionFactory.cs @@ -29,9 +29,7 @@ public class RelationalTransactionFactory : IRelationalTransactionFactory /// /// Parameter object containing dependencies for this service. public RelationalTransactionFactory(RelationalTransactionFactoryDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Relational provider-specific dependencies for this service. diff --git a/src/EFCore.Relational/Storage/RelationalTransactionFactoryDependencies.cs b/src/EFCore.Relational/Storage/RelationalTransactionFactoryDependencies.cs index 2ab1f1a8b38..a01f3eafbed 100644 --- a/src/EFCore.Relational/Storage/RelationalTransactionFactoryDependencies.cs +++ b/src/EFCore.Relational/Storage/RelationalTransactionFactoryDependencies.cs @@ -46,9 +46,7 @@ public sealed record RelationalTransactionFactoryDependencies /// [EntityFrameworkInternal] public RelationalTransactionFactoryDependencies(ISqlGenerationHelper sqlGenerationHelper) - { - SqlGenerationHelper = sqlGenerationHelper; - } + => SqlGenerationHelper = sqlGenerationHelper; /// /// Helpers for SQL generation. diff --git a/src/EFCore.Relational/Storage/RelationalTypeMappingInfo.cs b/src/EFCore.Relational/Storage/RelationalTypeMappingInfo.cs index 5b780ce1aa9..6f806ec8567 100644 --- a/src/EFCore.Relational/Storage/RelationalTypeMappingInfo.cs +++ b/src/EFCore.Relational/Storage/RelationalTypeMappingInfo.cs @@ -151,7 +151,7 @@ public RelationalTypeMappingInfo( int? scale) { // Note: Empty string is allowed for store type name because SQLite - _coreTypeMappingInfo = new TypeMappingInfo(null, null, false, unicode, size, null, precision, scale, false); + _coreTypeMappingInfo = new TypeMappingInfo(null, null, false, unicode, size, null, precision, scale); StoreTypeName = storeTypeName; StoreTypeNameBase = storeTypeNameBase; IsFixedLength = null; diff --git a/src/EFCore.Relational/Storage/RelationalTypeMappingSource.cs b/src/EFCore.Relational/Storage/RelationalTypeMappingSource.cs index 3f9b3d9b268..27785402a9d 100644 --- a/src/EFCore.Relational/Storage/RelationalTypeMappingSource.cs +++ b/src/EFCore.Relational/Storage/RelationalTypeMappingSource.cs @@ -42,9 +42,7 @@ protected RelationalTypeMappingSource( TypeMappingSourceDependencies dependencies, RelationalTypeMappingSourceDependencies relationalDependencies) : base(dependencies) - { - RelationalDependencies = relationalDependencies; - } + => RelationalDependencies = relationalDependencies; /// /// Overridden by relational database providers to find a type mapping for the given info. @@ -360,7 +358,8 @@ protected override CoreTypeMapping FindMapping(in TypeMappingInfo mappingInfo) storeTypeNameBase = ParseStoreTypeName(storeTypeName, ref unicode, ref size, ref precision, ref scale); } - var mappingInfo = new RelationalTypeMappingInfo(type, typeConfiguration, (RelationalTypeMapping?)elementMapping, + var mappingInfo = new RelationalTypeMappingInfo( + type, typeConfiguration, (RelationalTypeMapping?)elementMapping, storeTypeName, storeTypeNameBase, unicode, size, precision, scale); var providerClrType = typeConfiguration.GetProviderClrType()?.UnwrapNullableType(); return FindMappingWithConversion(mappingInfo, providerClrType, customConverter: typeConfiguration.GetValueConverter()); @@ -372,7 +371,7 @@ protected override CoreTypeMapping FindMapping(in TypeMappingInfo mappingInfo) customConverter: null); } - /// + /// public override RelationalTypeMapping? FindMapping(MemberInfo member) { if (member.GetCustomAttribute(true) is ColumnAttribute attribute) @@ -392,7 +391,7 @@ protected override CoreTypeMapping FindMapping(in TypeMappingInfo mappingInfo) return FindMappingWithConversion(new RelationalTypeMappingInfo(member), null, null); } - /// + /// public override RelationalTypeMapping? FindMapping(MemberInfo member, IModel model, bool useAttributes) { if (useAttributes diff --git a/src/EFCore.Relational/Storage/RelationalTypeMappingSourceDependencies.cs b/src/EFCore.Relational/Storage/RelationalTypeMappingSourceDependencies.cs index 702c4e9dc2c..476470ca378 100644 --- a/src/EFCore.Relational/Storage/RelationalTypeMappingSourceDependencies.cs +++ b/src/EFCore.Relational/Storage/RelationalTypeMappingSourceDependencies.cs @@ -47,9 +47,7 @@ public sealed record RelationalTypeMappingSourceDependencies [EntityFrameworkInternal] public RelationalTypeMappingSourceDependencies( IEnumerable plugins) - { - Plugins = plugins; - } + => Plugins = plugins; /// /// Gets the plugins. diff --git a/src/EFCore.Relational/Storage/RelationalTypeMappingSourceExtensions.cs b/src/EFCore.Relational/Storage/RelationalTypeMappingSourceExtensions.cs index db280bf3495..7d9abe01f66 100644 --- a/src/EFCore.Relational/Storage/RelationalTypeMappingSourceExtensions.cs +++ b/src/EFCore.Relational/Storage/RelationalTypeMappingSourceExtensions.cs @@ -56,10 +56,12 @@ public static RelationalTypeMapping GetMapping( var mapping = typeMappingSource.FindMapping(property); - return mapping ?? throw new InvalidOperationException(RelationalStrings.UnsupportedPropertyType( - property.DeclaringType.DisplayName(), - property.Name, - property.ClrType.ShortDisplayName())); + return mapping + ?? throw new InvalidOperationException( + RelationalStrings.UnsupportedPropertyType( + property.DeclaringType.DisplayName(), + property.Name, + property.ClrType.ShortDisplayName())); } /// diff --git a/src/EFCore.Relational/Storage/ValueConversion/RelationalConverterMappingHints.cs b/src/EFCore.Relational/Storage/ValueConversion/RelationalConverterMappingHints.cs index 7122fc9b05a..cd53cc19e4e 100644 --- a/src/EFCore.Relational/Storage/ValueConversion/RelationalConverterMappingHints.cs +++ b/src/EFCore.Relational/Storage/ValueConversion/RelationalConverterMappingHints.cs @@ -57,9 +57,7 @@ public RelationalConverterMappingHints( bool? fixedLength, Func? valueGeneratorFactory) : base(size, precision, scale, unicode, valueGeneratorFactory) - { - IsFixedLength = fixedLength; - } + => IsFixedLength = fixedLength; /// public override ConverterMappingHints With(ConverterMappingHints? hints) diff --git a/src/EFCore.Relational/Update/Internal/CommandBatchPreparer.cs b/src/EFCore.Relational/Update/Internal/CommandBatchPreparer.cs index f02d4dc9fa0..fdf3c302b19 100644 --- a/src/EFCore.Relational/Update/Internal/CommandBatchPreparer.cs +++ b/src/EFCore.Relational/Update/Internal/CommandBatchPreparer.cs @@ -217,7 +217,7 @@ protected virtual IEnumerable CreateModificationCo using var sharedIdentityTableMappings = entry.SharedIdentityEntry != null - && entry.SharedIdentityEntry.EntityState == EntityState.Deleted + && entry.SharedIdentityEntry.EntityState == EntityState.Deleted ? entry.SharedIdentityEntry.EntityType.GetTableMappings().GetEnumerator() : null; @@ -228,7 +228,9 @@ protected virtual IEnumerable CreateModificationCo && sharedIdentityTableMappings.MoveNext() && sharedIdentityTableMappings.Current.Table != tableMapping.Table) { - ProcessEntry(entry.SharedIdentityEntry!, sharedIdentityTableMappings.Current, commands, updateAdapter, generateParameterName, ref sharedTablesCommandsMap); + ProcessEntry( + entry.SharedIdentityEntry!, sharedIdentityTableMappings.Current, commands, updateAdapter, generateParameterName, + ref sharedTablesCommandsMap); } ProcessEntry(entry, tableMapping, commands, updateAdapter, generateParameterName, ref sharedTablesCommandsMap); @@ -237,9 +239,11 @@ protected virtual IEnumerable CreateModificationCo } while (sharedIdentityTableMappings != null - && sharedIdentityTableMappings.MoveNext()) + && sharedIdentityTableMappings.MoveNext()) { - ProcessEntry(entry.SharedIdentityEntry!, sharedIdentityTableMappings.Current, commands, updateAdapter, generateParameterName, ref sharedTablesCommandsMap); + ProcessEntry( + entry.SharedIdentityEntry!, sharedIdentityTableMappings.Current, commands, updateAdapter, generateParameterName, + ref sharedTablesCommandsMap); } if (!foundMapping) @@ -989,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)) @@ -1334,10 +1350,11 @@ private void AddSameTableEdges() } } - /// - void IResettableService.ResetState() => _modificationCommandGraph.Clear(); + /// + void IResettableService.ResetState() + => _modificationCommandGraph.Clear(); - /// + /// Task IResettableService.ResetStateAsync(CancellationToken cancellationToken) { ((IResettableService)this).ResetState(); diff --git a/src/EFCore.Relational/Update/Internal/CompositeRowForeignKeyValueFactory.cs b/src/EFCore.Relational/Update/Internal/CompositeRowForeignKeyValueFactory.cs index d91d033341a..6a66508855d 100644 --- a/src/EFCore.Relational/Update/Internal/CompositeRowForeignKeyValueFactory.cs +++ b/src/EFCore.Relational/Update/Internal/CompositeRowForeignKeyValueFactory.cs @@ -39,8 +39,8 @@ public CompositeRowForeignKeyValueFactory(IForeignKeyConstraint foreignKey) /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - protected override List? ValueConverters => - NonCapturingLazyInitializer.EnsureInitialized( + protected override List? ValueConverters + => NonCapturingLazyInitializer.EnsureInitialized( ref _valueConverters, this, static factory => { var foreignKey = factory._foreignKey; @@ -83,7 +83,7 @@ public CompositeRowForeignKeyValueFactory(IForeignKeyConstraint foreignKey) public override IEqualityComparer EqualityComparer { get => NonCapturingLazyInitializer.EnsureInitialized( - ref _equalityComparer, this, static factory => CreateEqualityComparer(factory.Columns, factory.ValueConverters)); + ref _equalityComparer, this, static factory => CreateEqualityComparer(factory.Columns, factory.ValueConverters)); protected set => _equalityComparer = value; } diff --git a/src/EFCore.Relational/Update/Internal/RowForeignKeyValueFactory.cs b/src/EFCore.Relational/Update/Internal/RowForeignKeyValueFactory.cs index 4cbe3e473f5..e6b2a75a878 100644 --- a/src/EFCore.Relational/Update/Internal/RowForeignKeyValueFactory.cs +++ b/src/EFCore.Relational/Update/Internal/RowForeignKeyValueFactory.cs @@ -59,9 +59,10 @@ protected RowForeignKeyValueFactory( /// doing so can result in application failures when updating to a new Entity Framework Core release. /// #pragma warning disable EF1001 // Internal EF Core API usage. - public virtual IEqualityComparer EqualityComparer => NonCapturingLazyInitializer.EnsureInitialized( - ref _equalityComparer, this, static factory - => NullableComparerAdapter.Wrap(factory.Column.ProviderValueComparer, factory.ValueConverter)); + public virtual IEqualityComparer EqualityComparer + => NonCapturingLazyInitializer.EnsureInitialized( + ref _equalityComparer, this, static factory + => NullableComparerAdapter.Wrap(factory.Column.ProviderValueComparer, factory.ValueConverter)); #pragma warning restore EF1001 // Internal EF Core API usage. /// @@ -86,25 +87,26 @@ protected RowForeignKeyValueFactory( /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public virtual ValueConverter? ValueConverter => typeof(TKey) == typeof(TForeignKey) - ? null - : NonCapturingLazyInitializer.EnsureInitialized( - ref _valueConverter, this, static factory => - { - var foreignKey = factory._foreignKey; - var column = factory.Column; - var valueConverterSelector = foreignKey.Table.Model.Model.GetRelationalDependencies().ValueConverterSelector; - var converterInfos = valueConverterSelector.Select(typeof(TKey), typeof(TForeignKey)).ToList(); - if (converterInfos.Count == 0) + public virtual ValueConverter? ValueConverter + => typeof(TKey) == typeof(TForeignKey) + ? null + : NonCapturingLazyInitializer.EnsureInitialized( + ref _valueConverter, this, static factory => { - var pkColumn = foreignKey.PrincipalColumns[0]; - throw new InvalidOperationException( - RelationalStrings.StoredKeyTypesNotConvertable( - column.Name, column.StoreType, pkColumn.StoreType, pkColumn.Name)); - } - - return converterInfos.First().Create(); - }); + var foreignKey = factory._foreignKey; + var column = factory.Column; + var valueConverterSelector = foreignKey.Table.Model.Model.GetRelationalDependencies().ValueConverterSelector; + var converterInfos = valueConverterSelector.Select(typeof(TKey), typeof(TForeignKey)).ToList(); + if (converterInfos.Count == 0) + { + var pkColumn = foreignKey.PrincipalColumns[0]; + throw new InvalidOperationException( + RelationalStrings.StoredKeyTypesNotConvertable( + column.Name, column.StoreType, pkColumn.StoreType, pkColumn.Name)); + } + + return converterInfos.First().Create(); + }); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Relational/Update/Internal/RowForeignKeyValueFactoryFactory.cs b/src/EFCore.Relational/Update/Internal/RowForeignKeyValueFactoryFactory.cs index 91581bf897a..ecb14200b7e 100644 --- a/src/EFCore.Relational/Update/Internal/RowForeignKeyValueFactoryFactory.cs +++ b/src/EFCore.Relational/Update/Internal/RowForeignKeyValueFactoryFactory.cs @@ -57,10 +57,10 @@ public static IRowForeignKeyValueFactory CreateSimpleNullableFactory( - foreignKey, dependentColumn, columnAccessors) - : new SimpleNullablePrincipalRowForeignKeyValueFactory( - foreignKey, dependentColumn, columnAccessors); + ? new SimpleFullyNullableRowForeignKeyValueFactory( + foreignKey, dependentColumn, columnAccessors) + : new SimpleNullablePrincipalRowForeignKeyValueFactory( + foreignKey, dependentColumn, columnAccessors); } private static readonly MethodInfo CreateNonNullableMethod = typeof(RowForeignKeyValueFactoryFactory).GetTypeInfo() diff --git a/src/EFCore.Relational/Update/Internal/SimpleFullyNullableRowForeignKeyValueFactory.cs b/src/EFCore.Relational/Update/Internal/SimpleFullyNullableRowForeignKeyValueFactory.cs index 16610bf092b..25953e8f9c4 100644 --- a/src/EFCore.Relational/Update/Internal/SimpleFullyNullableRowForeignKeyValueFactory.cs +++ b/src/EFCore.Relational/Update/Internal/SimpleFullyNullableRowForeignKeyValueFactory.cs @@ -12,7 +12,9 @@ namespace Microsoft.EntityFrameworkCore.Update.Internal; /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public class SimpleFullyNullableRowForeignKeyValueFactory( - IForeignKeyConstraint foreignKey, IColumn column, ColumnAccessors columnAccessors) + IForeignKeyConstraint foreignKey, + IColumn column, + ColumnAccessors columnAccessors) : RowForeignKeyValueFactory(foreignKey, column, columnAccessors) { /// diff --git a/src/EFCore.Relational/Update/Internal/SimpleNonNullableRowForeignKeyValueFactory.cs b/src/EFCore.Relational/Update/Internal/SimpleNonNullableRowForeignKeyValueFactory.cs index 3acc779f171..59ffba99a07 100644 --- a/src/EFCore.Relational/Update/Internal/SimpleNonNullableRowForeignKeyValueFactory.cs +++ b/src/EFCore.Relational/Update/Internal/SimpleNonNullableRowForeignKeyValueFactory.cs @@ -20,7 +20,9 @@ public class SimpleNonNullableRowForeignKeyValueFactory : Row /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SimpleNonNullableRowForeignKeyValueFactory( - IForeignKeyConstraint foreignKey, IColumn column, ColumnAccessors columnAccessors) + IForeignKeyConstraint foreignKey, + IColumn column, + ColumnAccessors columnAccessors) : base(foreignKey, column, columnAccessors) { } diff --git a/src/EFCore.Relational/Update/Internal/SimpleNullablePrincipalRowForeignKeyValueFactory.cs b/src/EFCore.Relational/Update/Internal/SimpleNullablePrincipalRowForeignKeyValueFactory.cs index f8c9eb34d63..575964b28fd 100644 --- a/src/EFCore.Relational/Update/Internal/SimpleNullablePrincipalRowForeignKeyValueFactory.cs +++ b/src/EFCore.Relational/Update/Internal/SimpleNullablePrincipalRowForeignKeyValueFactory.cs @@ -12,7 +12,9 @@ namespace Microsoft.EntityFrameworkCore.Update.Internal; /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public class SimpleNullablePrincipalRowForeignKeyValueFactory( - IForeignKeyConstraint foreignKey, IColumn column, ColumnAccessors columnAccessors) + IForeignKeyConstraint foreignKey, + IColumn column, + ColumnAccessors columnAccessors) : RowForeignKeyValueFactory(foreignKey, column, columnAccessors) where TKey : notnull { diff --git a/src/EFCore.Relational/Update/Internal/SimpleNullableRowForeignKeyValueFactory.cs b/src/EFCore.Relational/Update/Internal/SimpleNullableRowForeignKeyValueFactory.cs index 61118512e73..c3917bc5c59 100644 --- a/src/EFCore.Relational/Update/Internal/SimpleNullableRowForeignKeyValueFactory.cs +++ b/src/EFCore.Relational/Update/Internal/SimpleNullableRowForeignKeyValueFactory.cs @@ -12,7 +12,9 @@ namespace Microsoft.EntityFrameworkCore.Update.Internal; /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public class SimpleNullableRowForeignKeyValueFactory( - IForeignKeyConstraint foreignKey, IColumn column, ColumnAccessors columnAccessors) + IForeignKeyConstraint foreignKey, + IColumn column, + ColumnAccessors columnAccessors) : RowForeignKeyValueFactory(foreignKey, column, columnAccessors) where TKey : struct { diff --git a/src/EFCore.Relational/Update/ModificationCommand.cs b/src/EFCore.Relational/Update/ModificationCommand.cs index f6166992c89..d24e3c6357f 100644 --- a/src/EFCore.Relational/Update/ModificationCommand.cs +++ b/src/EFCore.Relational/Update/ModificationCommand.cs @@ -673,7 +673,13 @@ void HandleJson(List columnModifications) var processedEntries = new List(); foreach (var entry in _entries.Where(e => e.EntityType.IsMappedToJson())) { - var jsonColumn = GetTableMapping(entry.EntityType)!.Table.FindColumn(entry.EntityType.GetContainerColumnName()!)!; + var jsonColumn = GetTableMapping(entry.EntityType)!.Table.FindColumn(entry.EntityType.GetContainerColumnName()!); + + if (jsonColumn == null) + { + continue; + } + var jsonPartialUpdateInfo = FindJsonPartialUpdateInfo(entry, processedEntries); if (jsonPartialUpdateInfo == null) @@ -694,9 +700,10 @@ void HandleJson(List columnModifications) foreach (var entry in _entries.Where(e => !e.EntityType.IsMappedToJson())) { foreach (var jsonCollectionNavigation in entry.EntityType.GetNavigations() - .Where(n => n.IsCollection - && n.TargetEntityType.IsMappedToJson() - && (entry.GetCurrentValue(n) as IEnumerable)?.Any() == false)) + .Where( + n => n.IsCollection + && n.TargetEntityType.IsMappedToJson() + && (entry.GetCurrentValue(n) as IEnumerable)?.Any() == false)) { var jsonCollectionEntityType = jsonCollectionNavigation.TargetEntityType; var jsonCollectionColumn = diff --git a/src/EFCore.Relational/Update/UpdateSqlGenerator.cs b/src/EFCore.Relational/Update/UpdateSqlGenerator.cs index a490f4a7632..a1b5ac922da 100644 --- a/src/EFCore.Relational/Update/UpdateSqlGenerator.cs +++ b/src/EFCore.Relational/Update/UpdateSqlGenerator.cs @@ -33,9 +33,7 @@ public abstract class UpdateSqlGenerator : IUpdateSqlGenerator /// /// Parameter object containing dependencies for this service. protected UpdateSqlGenerator(UpdateSqlGeneratorDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Relational provider-specific dependencies for this service. 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.Abstractions/HierarchyId.cs b/src/EFCore.SqlServer.Abstractions/HierarchyId.cs index 04dc58d058d..f73f9401938 100644 --- a/src/EFCore.SqlServer.Abstractions/HierarchyId.cs +++ b/src/EFCore.SqlServer.Abstractions/HierarchyId.cs @@ -65,12 +65,15 @@ public static HierarchyId GetRoot() => (HierarchyId?)SqlHierarchyId.Parse(input); /// - /// Converts the and of a node to a value. + /// Converts the and of a node to a value. /// /// The parent HierarchyId of node. - /// The parent Id of current node. It can be more than one element if want have path like: "/1/2/3.1/", otherwise one element for have path like: "/1/2/3/". + /// + /// The parent Id of current node. It can be more than one element if want have path like: "/1/2/3.1/", otherwise one + /// element for have path like: "/1/2/3/". + /// /// A value. - public static HierarchyId Parse(HierarchyId parentHierarchyId , params int[] parentId) + public static HierarchyId Parse(HierarchyId parentHierarchyId, params int[] parentId) => GenerateHierarchyIdBasedOnParent(parentHierarchyId, parentId); //This Method can move to "SqlHierarchyId in Microsoft.SqlServer.Types", if we don't want put it in this abstraction. @@ -78,7 +81,7 @@ private static HierarchyId GenerateHierarchyIdBasedOnParent(HierarchyId parent, { if (parent is null) { - return HierarchyId.GetRoot(); + return GetRoot(); } if (parentId.Length < 1) @@ -90,7 +93,7 @@ private static HierarchyId GenerateHierarchyIdBasedOnParent(HierarchyId parent, specificPath.Append(string.Join(".", parentId)); specificPath.Append('/'); - return HierarchyId.Parse(specificPath.ToString()); + return Parse(specificPath.ToString()); } /// diff --git a/src/EFCore.SqlServer.HierarchyId/Design/Internal/SqlServerHierarchyIdDesignTimeServices.cs b/src/EFCore.SqlServer.HierarchyId/Design/Internal/SqlServerHierarchyIdDesignTimeServices.cs index 9266daa2962..37127a221e5 100644 --- a/src/EFCore.SqlServer.HierarchyId/Design/Internal/SqlServerHierarchyIdDesignTimeServices.cs +++ b/src/EFCore.SqlServer.HierarchyId/Design/Internal/SqlServerHierarchyIdDesignTimeServices.cs @@ -1,12 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.EntityFrameworkCore.Design; -using Microsoft.EntityFrameworkCore.Scaffolding; using Microsoft.EntityFrameworkCore.SqlServer.Scaffolding.Internal; using Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal; -using Microsoft.EntityFrameworkCore.Storage; -using Microsoft.Extensions.DependencyInjection; namespace Microsoft.EntityFrameworkCore.SqlServer.Design.Internal; diff --git a/src/EFCore.SqlServer.HierarchyId/Extensions/SqlServerHierarchyIdServiceCollectionExtensions.cs b/src/EFCore.SqlServer.HierarchyId/Extensions/SqlServerHierarchyIdServiceCollectionExtensions.cs index 5d4b3e2dc9a..c9a715c876d 100644 --- a/src/EFCore.SqlServer.HierarchyId/Extensions/SqlServerHierarchyIdServiceCollectionExtensions.cs +++ b/src/EFCore.SqlServer.HierarchyId/Extensions/SqlServerHierarchyIdServiceCollectionExtensions.cs @@ -5,7 +5,6 @@ using Microsoft.EntityFrameworkCore.Query; using Microsoft.EntityFrameworkCore.SqlServer.Query.Internal; using Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal; -using Microsoft.EntityFrameworkCore.Storage; namespace Microsoft.Extensions.DependencyInjection; diff --git a/src/EFCore.SqlServer.HierarchyId/Infrastructure/Internal/SqlServerHierarchyIdOptionsExtension.cs b/src/EFCore.SqlServer.HierarchyId/Infrastructure/Internal/SqlServerHierarchyIdOptionsExtension.cs index 8cc4541c552..dc83a909c5b 100644 --- a/src/EFCore.SqlServer.HierarchyId/Infrastructure/Internal/SqlServerHierarchyIdOptionsExtension.cs +++ b/src/EFCore.SqlServer.HierarchyId/Infrastructure/Internal/SqlServerHierarchyIdOptionsExtension.cs @@ -6,8 +6,6 @@ using Microsoft.EntityFrameworkCore.SqlServer.Internal; using Microsoft.EntityFrameworkCore.SqlServer.Query.Internal; using Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal; -using Microsoft.EntityFrameworkCore.Storage; -using Microsoft.Extensions.DependencyInjection; namespace Microsoft.EntityFrameworkCore.SqlServer.Infrastructure.Internal; diff --git a/src/EFCore.SqlServer.HierarchyId/Query/Internal/SqlServerHierarchyIdMethodCallTranslatorPlugin.cs b/src/EFCore.SqlServer.HierarchyId/Query/Internal/SqlServerHierarchyIdMethodCallTranslatorPlugin.cs index 712bb58671d..c60b5ee8b22 100644 --- a/src/EFCore.SqlServer.HierarchyId/Query/Internal/SqlServerHierarchyIdMethodCallTranslatorPlugin.cs +++ b/src/EFCore.SqlServer.HierarchyId/Query/Internal/SqlServerHierarchyIdMethodCallTranslatorPlugin.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.EntityFrameworkCore.Query; -using Microsoft.EntityFrameworkCore.Storage; namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal; @@ -23,9 +22,7 @@ public class SqlServerHierarchyIdMethodCallTranslatorPlugin : IMethodCallTransla public SqlServerHierarchyIdMethodCallTranslatorPlugin( IRelationalTypeMappingSource typeMappingSource, ISqlExpressionFactory sqlExpressionFactory) - { - Translators = new IMethodCallTranslator[] { new SqlServerHierarchyIdMethodTranslator(typeMappingSource, sqlExpressionFactory) }; - } + => Translators = new IMethodCallTranslator[] { new SqlServerHierarchyIdMethodTranslator(typeMappingSource, sqlExpressionFactory) }; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer.HierarchyId/Query/Internal/SqlServerHierarchyIdMethodTranslator.cs b/src/EFCore.SqlServer.HierarchyId/Query/Internal/SqlServerHierarchyIdMethodTranslator.cs index 3211a3bfede..5e12bf80c8c 100644 --- a/src/EFCore.SqlServer.HierarchyId/Query/Internal/SqlServerHierarchyIdMethodTranslator.cs +++ b/src/EFCore.SqlServer.HierarchyId/Query/Internal/SqlServerHierarchyIdMethodTranslator.cs @@ -3,6 +3,7 @@ using Microsoft.EntityFrameworkCore.Query; using Microsoft.EntityFrameworkCore.Query.SqlExpressions; +using ExpressionExtensions = Microsoft.EntityFrameworkCore.Query.ExpressionExtensions; namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal; @@ -75,7 +76,7 @@ public SqlServerHierarchyIdMethodTranslator( candidates = candidates.Prepend(instance); } - var typeMapping = Microsoft.EntityFrameworkCore.Query.ExpressionExtensions.InferTypeMapping(candidates.ToArray()) + var typeMapping = ExpressionExtensions.InferTypeMapping(candidates.ToArray()) ?? _typeMappingSource.FindMapping(typeof(HierarchyId))!; var newArguments = new List(); diff --git a/src/EFCore.SqlServer.HierarchyId/Scaffolding/Internal/SqlServerHierarchyIdCodeGeneratorPlugin.cs b/src/EFCore.SqlServer.HierarchyId/Scaffolding/Internal/SqlServerHierarchyIdCodeGeneratorPlugin.cs index c4271414b45..28097fe1132 100644 --- a/src/EFCore.SqlServer.HierarchyId/Scaffolding/Internal/SqlServerHierarchyIdCodeGeneratorPlugin.cs +++ b/src/EFCore.SqlServer.HierarchyId/Scaffolding/Internal/SqlServerHierarchyIdCodeGeneratorPlugin.cs @@ -1,9 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.EntityFrameworkCore.Design; using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Scaffolding; namespace Microsoft.EntityFrameworkCore.SqlServer.Scaffolding.Internal; diff --git a/src/EFCore.SqlServer.HierarchyId/Storage/Internal/SqlServerHierarchyIdTypeMapping.cs b/src/EFCore.SqlServer.HierarchyId/Storage/Internal/SqlServerHierarchyIdTypeMapping.cs index e2240bd7973..c53b4c11b62 100644 --- a/src/EFCore.SqlServer.HierarchyId/Storage/Internal/SqlServerHierarchyIdTypeMapping.cs +++ b/src/EFCore.SqlServer.HierarchyId/Storage/Internal/SqlServerHierarchyIdTypeMapping.cs @@ -3,11 +3,9 @@ using System.Data; using System.Data.Common; -using System.Linq.Expressions; using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore.SqlServer.Storage.Json; using Microsoft.EntityFrameworkCore.SqlServer.Storage.ValueConversion.Internal; -using Microsoft.EntityFrameworkCore.Storage; namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal; diff --git a/src/EFCore.SqlServer.HierarchyId/Storage/Internal/SqlServerHierarchyIdTypeMappingSourcePlugin.cs b/src/EFCore.SqlServer.HierarchyId/Storage/Internal/SqlServerHierarchyIdTypeMappingSourcePlugin.cs index 3905e2ff3d4..9cc779a43be 100644 --- a/src/EFCore.SqlServer.HierarchyId/Storage/Internal/SqlServerHierarchyIdTypeMappingSourcePlugin.cs +++ b/src/EFCore.SqlServer.HierarchyId/Storage/Internal/SqlServerHierarchyIdTypeMappingSourcePlugin.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.EntityFrameworkCore.Storage; using Microsoft.SqlServer.Types; namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal; diff --git a/src/EFCore.SqlServer.HierarchyId/Storage/Internal/SqlServerSqlHierarchyIdTypeMapping.cs b/src/EFCore.SqlServer.HierarchyId/Storage/Internal/SqlServerSqlHierarchyIdTypeMapping.cs index 7972da8c451..519d717e247 100644 --- a/src/EFCore.SqlServer.HierarchyId/Storage/Internal/SqlServerSqlHierarchyIdTypeMapping.cs +++ b/src/EFCore.SqlServer.HierarchyId/Storage/Internal/SqlServerSqlHierarchyIdTypeMapping.cs @@ -2,9 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Data.SqlTypes; -using System.Linq.Expressions; using Microsoft.EntityFrameworkCore.SqlServer.Storage.Json; -using Microsoft.EntityFrameworkCore.Storage; using Microsoft.SqlServer.Types; namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal; diff --git a/src/EFCore.SqlServer.HierarchyId/Storage/Json/SqlServerJsonHierarchyIdReaderWriter.cs b/src/EFCore.SqlServer.HierarchyId/Storage/Json/SqlServerJsonHierarchyIdReaderWriter.cs index e0cdc5757f6..9ecf28fb2b9 100644 --- a/src/EFCore.SqlServer.HierarchyId/Storage/Json/SqlServerJsonHierarchyIdReaderWriter.cs +++ b/src/EFCore.SqlServer.HierarchyId/Storage/Json/SqlServerJsonHierarchyIdReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Text.Json; using Microsoft.EntityFrameworkCore.Storage.Json; @@ -32,5 +31,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, HierarchyId value) => writer.WriteStringValue(value.ToString()); /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore.SqlServer.HierarchyId/Storage/Json/SqlServerJsonSqlHierarchyIdReaderWriter.cs b/src/EFCore.SqlServer.HierarchyId/Storage/Json/SqlServerJsonSqlHierarchyIdReaderWriter.cs index 286b9bbded6..7207995b29a 100644 --- a/src/EFCore.SqlServer.HierarchyId/Storage/Json/SqlServerJsonSqlHierarchyIdReaderWriter.cs +++ b/src/EFCore.SqlServer.HierarchyId/Storage/Json/SqlServerJsonSqlHierarchyIdReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Text.Json; using Microsoft.EntityFrameworkCore.Storage.Json; using Microsoft.SqlServer.Types; @@ -33,5 +32,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, SqlHierarchyId value) => writer.WriteStringValue(value.ToString()); /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore.SqlServer.HierarchyId/Storage/ValueConversion/Internal/SqlServerHierarchyIdValueConverter.cs b/src/EFCore.SqlServer.HierarchyId/Storage/ValueConversion/Internal/SqlServerHierarchyIdValueConverter.cs index 73b3b9154c6..767226f48d6 100644 --- a/src/EFCore.SqlServer.HierarchyId/Storage/ValueConversion/Internal/SqlServerHierarchyIdValueConverter.cs +++ b/src/EFCore.SqlServer.HierarchyId/Storage/ValueConversion/Internal/SqlServerHierarchyIdValueConverter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.SqlServer.Types; namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.ValueConversion.Internal; 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.NTS/Query/Internal/SqlServerGeometryCollectionMemberTranslator.cs b/src/EFCore.SqlServer.NTS/Query/Internal/SqlServerGeometryCollectionMemberTranslator.cs index d1fad65172f..1ecdeb03db4 100644 --- a/src/EFCore.SqlServer.NTS/Query/Internal/SqlServerGeometryCollectionMemberTranslator.cs +++ b/src/EFCore.SqlServer.NTS/Query/Internal/SqlServerGeometryCollectionMemberTranslator.cs @@ -26,9 +26,7 @@ private static readonly MemberInfo Count /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqlServerGeometryCollectionMemberTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer.NTS/Query/Internal/SqlServerMultiLineStringMemberTranslator.cs b/src/EFCore.SqlServer.NTS/Query/Internal/SqlServerMultiLineStringMemberTranslator.cs index 68a7767a5d1..046f5d53258 100644 --- a/src/EFCore.SqlServer.NTS/Query/Internal/SqlServerMultiLineStringMemberTranslator.cs +++ b/src/EFCore.SqlServer.NTS/Query/Internal/SqlServerMultiLineStringMemberTranslator.cs @@ -26,9 +26,7 @@ private static readonly MemberInfo IsClosed /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqlServerMultiLineStringMemberTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer.NTS/Query/Internal/SqlServerNetTopologySuiteAggregateMethodCallTranslatorPlugin.cs b/src/EFCore.SqlServer.NTS/Query/Internal/SqlServerNetTopologySuiteAggregateMethodCallTranslatorPlugin.cs index 7447c7f2bdd..99866bd6eef 100644 --- a/src/EFCore.SqlServer.NTS/Query/Internal/SqlServerNetTopologySuiteAggregateMethodCallTranslatorPlugin.cs +++ b/src/EFCore.SqlServer.NTS/Query/Internal/SqlServerNetTopologySuiteAggregateMethodCallTranslatorPlugin.cs @@ -20,12 +20,10 @@ public class SqlServerNetTopologySuiteAggregateMethodCallTranslatorPlugin : IAgg public SqlServerNetTopologySuiteAggregateMethodCallTranslatorPlugin( IRelationalTypeMappingSource typeMappingSource, ISqlExpressionFactory sqlExpressionFactory) - { - Translators = new IAggregateMethodCallTranslator[] + => Translators = new IAggregateMethodCallTranslator[] { new SqlServerNetTopologySuiteAggregateMethodTranslator(sqlExpressionFactory, typeMappingSource) }; - } /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer.NTS/Query/Internal/SqlServerNetTopologySuiteMemberTranslatorPlugin.cs b/src/EFCore.SqlServer.NTS/Query/Internal/SqlServerNetTopologySuiteMemberTranslatorPlugin.cs index e20ceec34d1..2b1d8e388f4 100644 --- a/src/EFCore.SqlServer.NTS/Query/Internal/SqlServerNetTopologySuiteMemberTranslatorPlugin.cs +++ b/src/EFCore.SqlServer.NTS/Query/Internal/SqlServerNetTopologySuiteMemberTranslatorPlugin.cs @@ -20,8 +20,7 @@ public class SqlServerNetTopologySuiteMemberTranslatorPlugin : IMemberTranslator public SqlServerNetTopologySuiteMemberTranslatorPlugin( IRelationalTypeMappingSource typeMappingSource, ISqlExpressionFactory sqlExpressionFactory) - { - Translators = new IMemberTranslator[] + => Translators = new IMemberTranslator[] { new SqlServerGeometryMemberTranslator(typeMappingSource, sqlExpressionFactory), new SqlServerGeometryCollectionMemberTranslator(sqlExpressionFactory), @@ -30,7 +29,6 @@ public SqlServerNetTopologySuiteMemberTranslatorPlugin( new SqlServerPointMemberTranslator(sqlExpressionFactory), new SqlServerPolygonMemberTranslator(typeMappingSource, sqlExpressionFactory) }; - } /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer.NTS/Query/Internal/SqlServerNetTopologySuiteMethodCallTranslatorPlugin.cs b/src/EFCore.SqlServer.NTS/Query/Internal/SqlServerNetTopologySuiteMethodCallTranslatorPlugin.cs index 4ea128a6706..57701851fac 100644 --- a/src/EFCore.SqlServer.NTS/Query/Internal/SqlServerNetTopologySuiteMethodCallTranslatorPlugin.cs +++ b/src/EFCore.SqlServer.NTS/Query/Internal/SqlServerNetTopologySuiteMethodCallTranslatorPlugin.cs @@ -20,8 +20,7 @@ public class SqlServerNetTopologySuiteMethodCallTranslatorPlugin : IMethodCallTr public SqlServerNetTopologySuiteMethodCallTranslatorPlugin( IRelationalTypeMappingSource typeMappingSource, ISqlExpressionFactory sqlExpressionFactory) - { - Translators = new IMethodCallTranslator[] + => Translators = new IMethodCallTranslator[] { new SqlServerGeometryMethodTranslator(typeMappingSource, sqlExpressionFactory), new SqlServerGeometryCollectionMethodTranslator(typeMappingSource, sqlExpressionFactory), @@ -29,7 +28,6 @@ public SqlServerNetTopologySuiteMethodCallTranslatorPlugin( new SqlServerNetTopologySuiteDbFunctionsMethodCallTranslator(typeMappingSource, sqlExpressionFactory), new SqlServerPolygonMethodTranslator(typeMappingSource, sqlExpressionFactory) }; - } /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer.NTS/Query/Internal/SqlServerPointMemberTranslator.cs b/src/EFCore.SqlServer.NTS/Query/Internal/SqlServerPointMemberTranslator.cs index 21451f426a8..7a0680e2031 100644 --- a/src/EFCore.SqlServer.NTS/Query/Internal/SqlServerPointMemberTranslator.cs +++ b/src/EFCore.SqlServer.NTS/Query/Internal/SqlServerPointMemberTranslator.cs @@ -41,9 +41,7 @@ public class SqlServerPointMemberTranslator : IMemberTranslator /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqlServerPointMemberTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer.NTS/Storage/Internal/SqlServerGeometryTypeMapping.cs b/src/EFCore.SqlServer.NTS/Storage/Internal/SqlServerGeometryTypeMapping.cs index c59569ef137..8fd3aa803bd 100644 --- a/src/EFCore.SqlServer.NTS/Storage/Internal/SqlServerGeometryTypeMapping.cs +++ b/src/EFCore.SqlServer.NTS/Storage/Internal/SqlServerGeometryTypeMapping.cs @@ -44,9 +44,7 @@ public SqlServerGeometryTypeMapping(NtsGeometryServices geometryServices, string CreateWriter(IsGeography(storeType))), storeType, SqlServerJsonGeometryWktReaderWriter.Instance) - { - _isGeography = IsGeography(storeType); - } + => _isGeography = IsGeography(storeType); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -58,9 +56,7 @@ protected SqlServerGeometryTypeMapping( RelationalTypeMappingParameters parameters, ValueConverter? converter) : base(parameters, converter) - { - _isGeography = IsGeography(StoreType); - } + => _isGeography = IsGeography(StoreType); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer.NTS/Storage/Internal/SqlServerNetTopologySuiteTypeMappingSourcePlugin.cs b/src/EFCore.SqlServer.NTS/Storage/Internal/SqlServerNetTopologySuiteTypeMappingSourcePlugin.cs index f7238b020ea..63894619347 100644 --- a/src/EFCore.SqlServer.NTS/Storage/Internal/SqlServerNetTopologySuiteTypeMappingSourcePlugin.cs +++ b/src/EFCore.SqlServer.NTS/Storage/Internal/SqlServerNetTopologySuiteTypeMappingSourcePlugin.cs @@ -25,9 +25,7 @@ public class SqlServerNetTopologySuiteTypeMappingSourcePlugin : IRelationalTypeM /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqlServerNetTopologySuiteTypeMappingSourcePlugin(NtsGeometryServices geometryServices) - { - _geometryServices = geometryServices; - } + => _geometryServices = geometryServices; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer.NTS/Storage/Json/SqlServerJsonGeometryWktReaderWriter.cs b/src/EFCore.SqlServer.NTS/Storage/Json/SqlServerJsonGeometryWktReaderWriter.cs index fb29eaf1b8f..0b8e432ccaa 100644 --- a/src/EFCore.SqlServer.NTS/Storage/Json/SqlServerJsonGeometryWktReaderWriter.cs +++ b/src/EFCore.SqlServer.NTS/Storage/Json/SqlServerJsonGeometryWktReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Text.Json; using Microsoft.EntityFrameworkCore.Storage.Json; using NetTopologySuite.Geometries; @@ -36,5 +35,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, Geometry value) => writer.WriteStringValue(value.ToText()); /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore.SqlServer/Design/Internal/SqlServerAnnotationCodeGenerator.cs b/src/EFCore.SqlServer/Design/Internal/SqlServerAnnotationCodeGenerator.cs index 2c0bebd2ab1..01e6918c559 100644 --- a/src/EFCore.SqlServer/Design/Internal/SqlServerAnnotationCodeGenerator.cs +++ b/src/EFCore.SqlServer/Design/Internal/SqlServerAnnotationCodeGenerator.cs @@ -55,18 +55,42 @@ private static readonly MethodInfo PropertyIsSparseMethodInfo = typeof(SqlServerPropertyBuilderExtensions).GetRuntimeMethod( nameof(SqlServerPropertyBuilderExtensions.IsSparse), [typeof(PropertyBuilder), typeof(bool)])!; + private static readonly MethodInfo PrimitiveCollectionIsSparseMethodInfo + = typeof(SqlServerPrimitiveCollectionBuilderExtensions).GetRuntimeMethod( + nameof(SqlServerPrimitiveCollectionBuilderExtensions.IsSparse), [typeof(PrimitiveCollectionBuilder), typeof(bool)])!; + + private static readonly MethodInfo ComplexTypePropertyIsSparseMethodInfo + = typeof(SqlServerComplexTypePropertyBuilderExtensions).GetRuntimeMethod( + nameof(SqlServerComplexTypePropertyBuilderExtensions.IsSparse), [typeof(ComplexTypePropertyBuilder), typeof(bool)])!; + + private static readonly MethodInfo ComplexTypePrimitiveCollectionIsSparseMethodInfo + = typeof(SqlServerComplexTypePrimitiveCollectionBuilderExtensions).GetRuntimeMethod( + nameof(SqlServerComplexTypePrimitiveCollectionBuilderExtensions.IsSparse), [typeof(ComplexTypePrimitiveCollectionBuilder), typeof(bool)])!; + private static readonly MethodInfo PropertyUseIdentityColumnsMethodInfo = typeof(SqlServerPropertyBuilderExtensions).GetRuntimeMethod( nameof(SqlServerPropertyBuilderExtensions.UseIdentityColumn), [typeof(PropertyBuilder), typeof(long), typeof(int)])!; + private static readonly MethodInfo ComplexTypePropertyUseIdentityColumnsMethodInfo + = typeof(SqlServerComplexTypePropertyBuilderExtensions).GetRuntimeMethod( + nameof(SqlServerComplexTypePropertyBuilderExtensions.UseIdentityColumn), [typeof(ComplexTypePropertyBuilder), typeof(long), typeof(int)])!; + private static readonly MethodInfo PropertyUseHiLoMethodInfo = typeof(SqlServerPropertyBuilderExtensions).GetRuntimeMethod( nameof(SqlServerPropertyBuilderExtensions.UseHiLo), [typeof(PropertyBuilder), typeof(string), typeof(string)])!; + private static readonly MethodInfo ComplexTypePropertyUseHiLoMethodInfo + = typeof(SqlServerComplexTypePropertyBuilderExtensions).GetRuntimeMethod( + nameof(SqlServerComplexTypePropertyBuilderExtensions.UseHiLo), [typeof(ComplexTypePropertyBuilder), typeof(string), typeof(string)])!; + private static readonly MethodInfo PropertyUseSequenceMethodInfo = typeof(SqlServerPropertyBuilderExtensions).GetRuntimeMethod( nameof(SqlServerPropertyBuilderExtensions.UseSequence), [typeof(PropertyBuilder), typeof(string), typeof(string)])!; + private static readonly MethodInfo ComplexTypePropertyUseSequenceMethodInfo + = typeof(SqlServerComplexTypePropertyBuilderExtensions).GetRuntimeMethod( + nameof(SqlServerComplexTypePropertyBuilderExtensions.UseSequence), [typeof(ComplexTypePropertyBuilder), typeof(string), typeof(string)])!; + private static readonly MethodInfo IndexIsClusteredMethodInfo = typeof(SqlServerIndexBuilderExtensions).GetRuntimeMethod( nameof(SqlServerIndexBuilderExtensions.IsClustered), [typeof(IndexBuilder), typeof(bool)])!; @@ -144,7 +168,7 @@ public override IReadOnlyList GenerateFluentApiCalls( { var fragments = new List(base.GenerateFluentApiCalls(model, annotations)); - if (GenerateValueGenerationStrategy(annotations, model, onModel: true) is MethodCallCodeFragment valueGenerationStrategy) + if (GenerateValueGenerationStrategy(annotations, model, onModel: true, complexType: false) is MethodCallCodeFragment valueGenerationStrategy) { fragments.Add(valueGenerationStrategy); } @@ -179,7 +203,9 @@ public override IReadOnlyList GenerateFluentApiCalls( { var fragments = new List(base.GenerateFluentApiCalls(property, annotations)); - if (GenerateValueGenerationStrategy(annotations, property.DeclaringType.Model, onModel: false) is MethodCallCodeFragment + var isPrimitiveCollection = property.IsPrimitiveCollection; + + if (GenerateValueGenerationStrategy(annotations, property.DeclaringType.Model, onModel: false, complexType: property.DeclaringType is IComplexType) is MethodCallCodeFragment valueGenerationStrategy) { fragments.Add(valueGenerationStrategy); @@ -187,10 +213,17 @@ public override IReadOnlyList GenerateFluentApiCalls( if (GetAndRemove(annotations, SqlServerAnnotationNames.Sparse) is bool isSparse) { + var methodInfo = isPrimitiveCollection + ? property.DeclaringType is IComplexType + ? ComplexTypePrimitiveCollectionIsSparseMethodInfo + : PrimitiveCollectionIsSparseMethodInfo + : property.DeclaringType is IComplexType + ? ComplexTypePropertyIsSparseMethodInfo + : PropertyIsSparseMethodInfo; fragments.Add( isSparse - ? new MethodCallCodeFragment(PropertyIsSparseMethodInfo) - : new MethodCallCodeFragment(PropertyIsSparseMethodInfo, false)); + ? new MethodCallCodeFragment(methodInfo) + : new MethodCallCodeFragment(methodInfo, false)); } return fragments; @@ -367,7 +400,8 @@ protected override bool IsHandledByConvention(IProperty property, IAnnotation an private static MethodCallCodeFragment? GenerateValueGenerationStrategy( IDictionary annotations, IModel model, - bool onModel) + bool onModel, + bool complexType) { SqlServerValueGenerationStrategy strategy; if (annotations.TryGetValue(SqlServerAnnotationNames.ValueGenerationStrategy, out var strategyAnnotation) @@ -405,7 +439,11 @@ protected override bool IsHandledByConvention(IProperty property, IAnnotation an ?? model.FindAnnotation(SqlServerAnnotationNames.IdentityIncrement)?.Value as int? ?? 1; return new MethodCallCodeFragment( - onModel ? ModelUseIdentityColumnsMethodInfo : PropertyUseIdentityColumnsMethodInfo, + onModel + ? ModelUseIdentityColumnsMethodInfo + : complexType + ? ComplexTypePropertyUseIdentityColumnsMethodInfo + : PropertyUseIdentityColumnsMethodInfo, (seed, increment) switch { (1L, 1) => [], @@ -418,7 +456,11 @@ protected override bool IsHandledByConvention(IProperty property, IAnnotation an var name = GetAndRemove(annotations, SqlServerAnnotationNames.HiLoSequenceName); var schema = GetAndRemove(annotations, SqlServerAnnotationNames.HiLoSequenceSchema); return new MethodCallCodeFragment( - onModel ? ModelUseHiLoMethodInfo : PropertyUseHiLoMethodInfo, + onModel + ? ModelUseHiLoMethodInfo + : complexType + ? ComplexTypePropertyUseHiLoMethodInfo + : PropertyUseHiLoMethodInfo, (name, schema) switch { (null, null) => [], @@ -435,7 +477,11 @@ protected override bool IsHandledByConvention(IProperty property, IAnnotation an var schema = GetAndRemove(annotations, SqlServerAnnotationNames.SequenceSchema); return new MethodCallCodeFragment( - onModel ? ModelUseKeySequencesMethodInfo : PropertyUseSequenceMethodInfo, + onModel + ? ModelUseKeySequencesMethodInfo + : complexType + ? ComplexTypePropertyUseSequenceMethodInfo + : PropertyUseSequenceMethodInfo, (name: nameOrSuffix, schema) switch { (null, null) => [], @@ -473,9 +519,8 @@ private static void GenerateSimpleFluentApiCall( MethodInfo methodInfo, List methodCallCodeFragments) { - if (annotations.TryGetValue(annotationName, out var annotation)) + if (annotations.Remove(annotationName, out var annotation)) { - annotations.Remove(annotationName); if (annotation.Value is object annotationValue) { methodCallCodeFragments.Add( diff --git a/src/EFCore.SqlServer/Diagnostics/Internal/SqlServerLoggingDefinitions.cs b/src/EFCore.SqlServer/Diagnostics/Internal/SqlServerLoggingDefinitions.cs index 39aeb7ee552..a81a6df2ebd 100644 --- a/src/EFCore.SqlServer/Diagnostics/Internal/SqlServerLoggingDefinitions.cs +++ b/src/EFCore.SqlServer/Diagnostics/Internal/SqlServerLoggingDefinitions.cs @@ -194,4 +194,12 @@ public class SqlServerLoggingDefinitions : RelationalLoggingDefinitions /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public EventDefinitionBase? LogMissingViewDefinitionRights; + + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + public EventDefinitionBase? LogJsonTypeExperimental; } diff --git a/src/EFCore.SqlServer/Diagnostics/SqlServerEventId.cs b/src/EFCore.SqlServer/Diagnostics/SqlServerEventId.cs index 2fd40c196ef..5940679dcf3 100644 --- a/src/EFCore.SqlServer/Diagnostics/SqlServerEventId.cs +++ b/src/EFCore.SqlServer/Diagnostics/SqlServerEventId.cs @@ -25,14 +25,14 @@ public static class SqlServerEventId // Try to use naming and be consistent with existing names. private enum Id { - // Model validation events + // All events + // Don't insert or delete anything in the middle of this section! DecimalTypeDefaultWarning = CoreEventId.ProviderBaseId, ByteIdentityColumnWarning, ConflictingValueGenerationStrategiesWarning, DecimalTypeKeyWarning, - - // Transaction events SavepointsDisabledBecauseOfMARS, + JsonTypeExperimental, // Scaffolding events ColumnFound = CoreEventId.ProviderDesignBaseId, @@ -115,6 +115,20 @@ private static EventId MakeValidationId(Id id) /// public static readonly EventId ByteIdentityColumnWarning = MakeValidationId(Id.ByteIdentityColumnWarning); + /// + /// An entity type makes use of the SQL Server native 'json' type. Please note that support for this type in EF Core 9 is + /// experimental and may change in future releases. + /// + /// + /// + /// This event is in the category. + /// + /// + /// This event uses the payload when used with a . + /// + /// + public static readonly EventId JsonTypeExperimental = MakeValidationId(Id.JsonTypeExperimental); + /// /// There are conflicting value generation methods for a property. /// diff --git a/src/EFCore.SqlServer/EFCore.SqlServer.csproj b/src/EFCore.SqlServer/EFCore.SqlServer.csproj index 2709d8d7fcc..fff89e95202 100644 --- a/src/EFCore.SqlServer/EFCore.SqlServer.csproj +++ b/src/EFCore.SqlServer/EFCore.SqlServer.csproj @@ -9,7 +9,7 @@ true $(PackageTags);SQL Server true - EF9100 + $(NoWarn);EF9100 @@ -49,7 +49,7 @@ - + diff --git a/src/EFCore.SqlServer/Extensions/Internal/SqlServerLoggerExtensions.cs b/src/EFCore.SqlServer/Extensions/Internal/SqlServerLoggerExtensions.cs index 64642e4a680..bfa21d25d66 100644 --- a/src/EFCore.SqlServer/Extensions/Internal/SqlServerLoggerExtensions.cs +++ b/src/EFCore.SqlServer/Extensions/Internal/SqlServerLoggerExtensions.cs @@ -124,6 +124,33 @@ private static string ByteIdentityColumnWarning(EventDefinitionBase definition, p.Property.DeclaringType.DisplayName()); } + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + public static void JsonTypeExperimental( + this IDiagnosticsLogger diagnostics, + IEntityType entityType) + { + var definition = SqlServerResources.LogJsonTypeExperimental(diagnostics); + + if (diagnostics.ShouldLog(definition)) + { + definition.Log(diagnostics, entityType.DisplayName()); + } + + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) + { + var eventData = new EntityTypeEventData( + definition, (d, p) + => ((EventDefinition)d).GenerateMessage(((EntityTypeEventData)p).EntityType.DisplayName()), entityType); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); + } + } + /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in diff --git a/src/EFCore.SqlServer/Extensions/SqlServerDbContextOptionsBuilderExtensions.cs b/src/EFCore.SqlServer/Extensions/SqlServerDbContextOptionsBuilderExtensions.cs index 20dce04c435..44b9fe3b3e4 100644 --- a/src/EFCore.SqlServer/Extensions/SqlServerDbContextOptionsBuilderExtensions.cs +++ b/src/EFCore.SqlServer/Extensions/SqlServerDbContextOptionsBuilderExtensions.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.EntityFrameworkCore.SqlServer.Infrastructure.Internal; -using Microsoft.EntityFrameworkCore.SqlServer.Internal; // ReSharper disable once CheckNamespace namespace Microsoft.EntityFrameworkCore; @@ -709,7 +708,8 @@ public static DbContextOptionsBuilder ConfigureSqlEngine( this DbContextOptionsBuilder optionsBuilder, Action? sqlEngineOptionsAction = null) { - ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(GetOrCreateExtension(optionsBuilder)); + ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension( + GetOrCreateExtension(optionsBuilder)); return ApplyConfiguration(optionsBuilder, sqlEngineOptionsAction); } @@ -757,6 +757,7 @@ private static DbContextOptionsBuilder ApplyConfiguration( return optionsBuilder; } + private static DbContextOptionsBuilder ApplyConfiguration( DbContextOptionsBuilder optionsBuilder, Action? azureSqlOptionsAction) @@ -770,6 +771,7 @@ private static DbContextOptionsBuilder ApplyConfiguration( return optionsBuilder; } + private static DbContextOptionsBuilder ApplyConfiguration( DbContextOptionsBuilder optionsBuilder, Action? azureSynapseOptionsAction) @@ -783,6 +785,7 @@ private static DbContextOptionsBuilder ApplyConfiguration( return optionsBuilder; } + private static DbContextOptionsBuilder ApplyConfiguration( DbContextOptionsBuilder optionsBuilder, Action? sqlEngineOptionsAction) diff --git a/src/EFCore.SqlServer/Extensions/SqlServerDbFunctionsExtensions.cs b/src/EFCore.SqlServer/Extensions/SqlServerDbFunctionsExtensions.cs index 6fa35be3742..94b3b3aca77 100644 --- a/src/EFCore.SqlServer/Extensions/SqlServerDbFunctionsExtensions.cs +++ b/src/EFCore.SqlServer/Extensions/SqlServerDbFunctionsExtensions.cs @@ -2138,7 +2138,8 @@ public static DateTimeOffset AtTimeZone( => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(AtTimeZone))); /// - /// Returns the starting position of the first occurrence of a pattern in a specified expression, or zero if the pattern is not found, on all valid text and character data types. + /// Returns the starting position of the first occurrence of a pattern in a specified expression, or zero if the pattern is not found, on + /// all valid text and character data types. /// /// /// See Database functions, and diff --git a/src/EFCore.SqlServer/Extensions/SqlServerEntityTypeBuilderExtensions.cs b/src/EFCore.SqlServer/Extensions/SqlServerEntityTypeBuilderExtensions.cs index c5ce3eac1fc..0ed61f44e41 100644 --- a/src/EFCore.SqlServer/Extensions/SqlServerEntityTypeBuilderExtensions.cs +++ b/src/EFCore.SqlServer/Extensions/SqlServerEntityTypeBuilderExtensions.cs @@ -140,6 +140,111 @@ public static bool CanSetIsMemoryOptimized( bool fromDataAnnotation = false) => entityTypeBuilder.CanSetAnnotation(SqlServerAnnotationNames.MemoryOptimized, memoryOptimized, fromDataAnnotation); + /// + /// Sets a value indicating whether to use the SQL OUTPUT clause when saving changes to the table. + /// The OUTPUT clause is incompatible with certain SQL Server features, such as tables with triggers. + /// + /// + /// See Modeling entity types and relationships for more information and examples. + /// + /// The builder for the entity type being configured. + /// The value to set. + /// Indicates whether the configuration was specified using a data annotation. + /// + /// The same builder instance if the configuration was applied, + /// otherwise. + /// + public static IConventionEntityTypeBuilder? UseSqlOutputClause( + this IConventionEntityTypeBuilder entityTypeBuilder, + bool? useSqlOutputClause, + bool fromDataAnnotation = false) + { + if (!entityTypeBuilder.CanUseSqlOutputClause(useSqlOutputClause, fromDataAnnotation)) + { + return null; + } + + entityTypeBuilder.Metadata.UseSqlOutputClause(useSqlOutputClause, fromDataAnnotation); + return entityTypeBuilder; + } + + /// + /// Sets a value indicating whether to use the SQL OUTPUT clause when saving changes to the table. + /// The OUTPUT clause is incompatible with certain SQL Server features, such as tables with triggers. + /// + /// + /// See Modeling entity types and relationships for more information and examples. + /// + /// The builder for the entity type being configured. + /// The value to set. + /// The identifier of the table-like store object. + /// Indicates whether the configuration was specified using a data annotation. + /// + /// The same builder instance if the configuration was applied, + /// otherwise. + /// + public static IConventionEntityTypeBuilder? UseSqlOutputClause( + this IConventionEntityTypeBuilder entityTypeBuilder, + bool? useSqlOutputClause, + in StoreObjectIdentifier storeObject, + bool fromDataAnnotation = false) + { + if (!entityTypeBuilder.CanUseSqlOutputClause(useSqlOutputClause, storeObject, fromDataAnnotation)) + { + return null; + } + + entityTypeBuilder.Metadata.UseSqlOutputClause(useSqlOutputClause, storeObject, fromDataAnnotation); + return entityTypeBuilder; + } + + /// + /// Returns a value indicating whether this entity type can be configured to use the SQL OUTPUT clause + /// using the specified configuration source. + /// + /// + /// See Modeling entity types and relationships for more information and examples. + /// + /// The builder for the entity type being configured. + /// The value to set. + /// Indicates whether the configuration was specified using a data annotation. + /// if the configuration can be applied. + public static bool CanUseSqlOutputClause( + this IConventionEntityTypeBuilder entityTypeBuilder, + bool? useSqlOutputClause, + bool fromDataAnnotation = false) + => entityTypeBuilder.CanSetAnnotation( + SqlServerAnnotationNames.UseSqlOutputClause, + useSqlOutputClause, + fromDataAnnotation); + + /// + /// Returns a value indicating whether this entity type can be configured to use the SQL OUTPUT clause + /// using the specified configuration source. + /// + /// + /// See Modeling entity types and relationships for more information and examples. + /// + /// The builder for the entity type being configured. + /// The value to set. + /// The identifier of the table-like store object. + /// Indicates whether the configuration was specified using a data annotation. + /// if the configuration can be applied. + public static bool CanUseSqlOutputClause( + this IConventionEntityTypeBuilder entityTypeBuilder, + bool? useSqlOutputClause, + in StoreObjectIdentifier storeObject, + bool fromDataAnnotation = false) + => StoreObjectIdentifier.Create(entityTypeBuilder.Metadata, storeObject.StoreObjectType) == storeObject + ? entityTypeBuilder.CanSetAnnotation( + SqlServerAnnotationNames.UseSqlOutputClause, + useSqlOutputClause, + fromDataAnnotation) + : entityTypeBuilder.Metadata.GetOrCreateMappingFragment(storeObject, fromDataAnnotation).Builder.CanSetAnnotation( + SqlServerAnnotationNames.UseSqlOutputClause, + useSqlOutputClause, + fromDataAnnotation); + /// /// Configures the table as temporal. /// diff --git a/src/EFCore.SqlServer/Extensions/SqlServerEntityTypeExtensions.cs b/src/EFCore.SqlServer/Extensions/SqlServerEntityTypeExtensions.cs index 1f69486cb80..31d8109195d 100644 --- a/src/EFCore.SqlServer/Extensions/SqlServerEntityTypeExtensions.cs +++ b/src/EFCore.SqlServer/Extensions/SqlServerEntityTypeExtensions.cs @@ -344,6 +344,19 @@ public static void UseSqlOutputClause(this IMutableEntityType entityType, bool? public static ConfigurationSource? GetUseSqlOutputClauseConfigurationSource(this IConventionEntityType entityType) => entityType.FindAnnotation(SqlServerAnnotationNames.UseSqlOutputClause)?.GetConfigurationSource(); + /// + /// Gets the configuration source for whether to use the SQL OUTPUT clause when saving changes to the table. + /// + /// The entity type. + /// The identifier of the table-like store object. + /// The configuration source for the memory-optimized setting. + public static ConfigurationSource? GetUseSqlOutputClauseConfigurationSource( + this IConventionEntityType entityType, + in StoreObjectIdentifier storeObject) + => StoreObjectIdentifier.Create(entityType, storeObject.StoreObjectType) == storeObject + ? entityType.GetUseSqlOutputClauseConfigurationSource() + : (entityType.FindMappingFragment(storeObject)?.GetUseSqlOutputClauseConfigurationSource()); + /// /// Returns a value indicating whether to use the SQL OUTPUT clause when saving changes to the specified table. /// The OUTPUT clause is incompatible with certain SQL Server features, such as tables with triggers. diff --git a/src/EFCore.SqlServer/Extensions/SqlServerEntityTypeMappingFragmentExtensions.cs b/src/EFCore.SqlServer/Extensions/SqlServerEntityTypeMappingFragmentExtensions.cs index 828d0123a3d..02aded42de4 100644 --- a/src/EFCore.SqlServer/Extensions/SqlServerEntityTypeMappingFragmentExtensions.cs +++ b/src/EFCore.SqlServer/Extensions/SqlServerEntityTypeMappingFragmentExtensions.cs @@ -27,7 +27,7 @@ public static bool IsSqlOutputClauseUsed(this IReadOnlyEntityTypeMappingFragment /// The entity type mapping fragment. /// The value to set. public static void UseSqlOutputClause(this IMutableEntityTypeMappingFragment fragment, bool? useSqlOutputClause) - => fragment.SetAnnotation(SqlServerAnnotationNames.UseSqlOutputClause, useSqlOutputClause); + => fragment.SetOrRemoveAnnotation(SqlServerAnnotationNames.UseSqlOutputClause, useSqlOutputClause); /// /// Sets whether to use the SQL OUTPUT clause when saving changes to the associated table. @@ -41,7 +41,8 @@ public static void UseSqlOutputClause(this IMutableEntityTypeMappingFragment fra this IConventionEntityTypeMappingFragment fragment, bool? useSqlOutputClause, bool fromDataAnnotation = false) - => (bool?)fragment.SetAnnotation(SqlServerAnnotationNames.UseSqlOutputClause, useSqlOutputClause, fromDataAnnotation)?.Value; + => (bool?)fragment.SetOrRemoveAnnotation(SqlServerAnnotationNames.UseSqlOutputClause, useSqlOutputClause, fromDataAnnotation) + ?.Value; /// /// Gets the configuration source for the setting whether to use the SQL OUTPUT clause when saving changes to the associated table. diff --git a/src/EFCore.SqlServer/Extensions/SqlServerPropertyExtensions.cs b/src/EFCore.SqlServer/Extensions/SqlServerPropertyExtensions.cs index 75cea6b8c53..d423e0f5b03 100644 --- a/src/EFCore.SqlServer/Extensions/SqlServerPropertyExtensions.cs +++ b/src/EFCore.SqlServer/Extensions/SqlServerPropertyExtensions.cs @@ -920,7 +920,6 @@ public static void SetValueGenerationStrategy( => (SqlServerValueGenerationStrategy?)overrides.SetOrRemoveAnnotation( SqlServerAnnotationNames.ValueGenerationStrategy, value, fromDataAnnotation)?.Value; - /// /// Returns the for the . /// diff --git a/src/EFCore.SqlServer/Infrastructure/AzureSqlDbContextOptionsBuilder.cs b/src/EFCore.SqlServer/Infrastructure/AzureSqlDbContextOptionsBuilder.cs index 45f2204d354..16a56ee9c14 100644 --- a/src/EFCore.SqlServer/Infrastructure/AzureSqlDbContextOptionsBuilder.cs +++ b/src/EFCore.SqlServer/Infrastructure/AzureSqlDbContextOptionsBuilder.cs @@ -9,8 +9,8 @@ namespace Microsoft.EntityFrameworkCore.Infrastructure; /// Allows Azure SQL specific configuration to be performed on . /// /// -/// Instances of this class are returned from a call to -/// +/// Instances of this class are returned from a call to +/// /// and it is not designed to be directly constructed in your application code. /// public class AzureSqlDbContextOptionsBuilder diff --git a/src/EFCore.SqlServer/Infrastructure/AzureSynapseDbContextOptionsBuilder.cs b/src/EFCore.SqlServer/Infrastructure/AzureSynapseDbContextOptionsBuilder.cs index d3d822e824b..ae23ab4a2fb 100644 --- a/src/EFCore.SqlServer/Infrastructure/AzureSynapseDbContextOptionsBuilder.cs +++ b/src/EFCore.SqlServer/Infrastructure/AzureSynapseDbContextOptionsBuilder.cs @@ -9,8 +9,8 @@ namespace Microsoft.EntityFrameworkCore.Infrastructure; /// Allows Azure Synapse specific configuration to be performed on . /// /// -/// Instances of this class are returned from a call to -/// +/// Instances of this class are returned from a call to +/// /// and it is not designed to be directly constructed in your application code. /// public class AzureSynapseDbContextOptionsBuilder diff --git a/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerEngineType.cs b/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerEngineType.cs index 63f9c9816f4..3317ffddd30 100644 --- a/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerEngineType.cs +++ b/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerEngineType.cs @@ -12,22 +12,22 @@ namespace Microsoft.EntityFrameworkCore.SqlServer.Infrastructure.Internal; public enum SqlServerEngineType { /// - /// Unknown SQL engine type. + /// Unknown SQL engine type. /// Unknown = 0, /// - /// SQL Server. + /// SQL Server. /// SqlServer = 1, /// - /// Azure SQL. + /// Azure SQL. /// AzureSql = 2, /// - /// Azure Synapse. + /// Azure Synapse. /// AzureSynapse = 3, } diff --git a/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerModelValidator.cs b/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerModelValidator.cs index 68cc2d344c5..02e49289a8e 100644 --- a/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerModelValidator.cs +++ b/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerModelValidator.cs @@ -45,6 +45,27 @@ public override void Validate(IModel model, IDiagnosticsLogger + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + protected virtual void ValidateUseOfJsonType( + IModel model, + IDiagnosticsLogger logger) + { + foreach (var entityType in model.GetEntityTypes()) + { + if (string.Equals(entityType.GetContainerColumnType(), "json", StringComparison.OrdinalIgnoreCase) + || entityType.GetProperties().Any(p => string.Equals(p.GetColumnType(), "json", StringComparison.OrdinalIgnoreCase))) + { + logger.JsonTypeExperimental(entityType); + } + } } /// @@ -135,7 +156,7 @@ protected override void ValidateValueGeneration( } } - /// + /// protected override void ValidateTypeMappings( IModel model, IDiagnosticsLogger logger) diff --git a/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerOptionsExtension.cs b/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerOptionsExtension.cs index 31d6162d857..96937e06cf8 100644 --- a/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerOptionsExtension.cs +++ b/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerOptionsExtension.cs @@ -252,9 +252,9 @@ public virtual IDbContextOptionsExtension ApplyDefaults(IDbContextOptions option && (EngineType == SqlServerEngineType.AzureSql || EngineType == SqlServerEngineType.AzureSynapse || UseRetryingStrategyByDefault)) - { - return WithExecutionStrategyFactory(c => new SqlServerRetryingExecutionStrategy(c)); - } + { + return WithExecutionStrategyFactory(c => new SqlServerRetryingExecutionStrategy(c)); + } return this; } @@ -292,7 +292,9 @@ public override void Validate(IDbContextOptions options) base.Validate(options); if (EngineType == SqlServerEngineType.Unknown) { - throw new InvalidOperationException(SqlServerStrings.InvalidEngineType($"{nameof(SqlServerDbContextOptionsExtensions.UseSqlServer)}/{nameof(SqlServerDbContextOptionsExtensions.UseAzureSql)}/{nameof(SqlServerDbContextOptionsExtensions.UseAzureSynapse)}")); + throw new InvalidOperationException( + SqlServerStrings.InvalidEngineType( + $"{nameof(SqlServerDbContextOptionsExtensions.UseSqlServer)}/{nameof(SqlServerDbContextOptionsExtensions.UseAzureSql)}/{nameof(SqlServerDbContextOptionsExtensions.UseAzureSynapse)}")); } } @@ -340,6 +342,7 @@ public override string LogFragment .Append(Extension._sqlServerCompatibilityLevel) .Append(' '); } + if (Extension._azureSqlCompatibilityLevel != null) { builder @@ -347,6 +350,7 @@ public override string LogFragment .Append(Extension._azureSqlCompatibilityLevel) .Append(' '); } + if (Extension._azureSynapseCompatibilityLevel != null) { builder @@ -371,10 +375,12 @@ public override void PopulateDebugInfo(IDictionary debugInfo) { debugInfo["SqlServerCompatibilityLevel"] = sqlServerCompatibilityLevel.ToString(); } + if (Extension.AzureSqlCompatibilityLevel is int azureSqlCompatibilityLevel) { debugInfo["AzureSqlCompatibilityLevel"] = azureSqlCompatibilityLevel.ToString(); } + if (Extension.AzureSynapseCompatibilityLevel is int azureSynapseCompatibilityLevel) { debugInfo["AzureSynapseCompatibilityLevel"] = azureSynapseCompatibilityLevel.ToString(); diff --git a/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerSingletonOptions.cs b/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerSingletonOptions.cs index 3af5096042c..fdfc97a3697 100644 --- a/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerSingletonOptions.cs +++ b/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerSingletonOptions.cs @@ -41,7 +41,8 @@ public class SqlServerSingletonOptions : ISqlServerSingletonOptions /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public virtual int AzureSynapseCompatibilityLevel { get; private set; } = SqlServerOptionsExtension.AzureSynapseDefaultCompatibilityLevel; + public virtual int AzureSynapseCompatibilityLevel { get; private set; } = + SqlServerOptionsExtension.AzureSynapseDefaultCompatibilityLevel; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -74,13 +75,15 @@ public virtual void Validate(IDbContextOptions options) if (sqlServerOptions != null) { if (EngineType == SqlServerEngineType.SqlServer - && (EngineType != sqlServerOptions.EngineType || SqlServerCompatibilityLevel != sqlServerOptions.SqlServerCompatibilityLevel)) + && (EngineType != sqlServerOptions.EngineType + || SqlServerCompatibilityLevel != sqlServerOptions.SqlServerCompatibilityLevel)) { throw new InvalidOperationException( CoreStrings.SingletonOptionChanged( $"{nameof(SqlServerDbContextOptionsExtensions.UseSqlServer)}", nameof(DbContextOptionsBuilder.UseInternalServiceProvider))); } + if (EngineType == SqlServerEngineType.AzureSql && (EngineType != sqlServerOptions.EngineType || AzureSqlCompatibilityLevel != sqlServerOptions.AzureSqlCompatibilityLevel)) { @@ -89,8 +92,10 @@ public virtual void Validate(IDbContextOptions options) $"{nameof(SqlServerDbContextOptionsExtensions.UseAzureSql)}", nameof(DbContextOptionsBuilder.UseInternalServiceProvider))); } + if (EngineType == SqlServerEngineType.AzureSynapse - && (EngineType != sqlServerOptions.EngineType || AzureSynapseCompatibilityLevel != sqlServerOptions.AzureSynapseCompatibilityLevel)) + && (EngineType != sqlServerOptions.EngineType + || AzureSynapseCompatibilityLevel != sqlServerOptions.AzureSynapseCompatibilityLevel)) { throw new InvalidOperationException( CoreStrings.SingletonOptionChanged( diff --git a/src/EFCore.SqlServer/Infrastructure/SqlEngineDbContextOptionsBuilder.cs b/src/EFCore.SqlServer/Infrastructure/SqlEngineDbContextOptionsBuilder.cs index 510375b83b2..3a324ab8a4d 100644 --- a/src/EFCore.SqlServer/Infrastructure/SqlEngineDbContextOptionsBuilder.cs +++ b/src/EFCore.SqlServer/Infrastructure/SqlEngineDbContextOptionsBuilder.cs @@ -9,7 +9,7 @@ namespace Microsoft.EntityFrameworkCore.Infrastructure; /// Allows SQL Server, Azure SQL, Azure Synapse specific configuration to be performed on . /// /// -/// Instances of this class are returned from a call to +/// Instances of this class are returned from a call to /// /// and it is not designed to be directly constructed in your application code. /// diff --git a/src/EFCore.SqlServer/Infrastructure/SqlServerDbContextOptionsBuilder.cs b/src/EFCore.SqlServer/Infrastructure/SqlServerDbContextOptionsBuilder.cs index 143ac91bc0f..3e6560ce581 100644 --- a/src/EFCore.SqlServer/Infrastructure/SqlServerDbContextOptionsBuilder.cs +++ b/src/EFCore.SqlServer/Infrastructure/SqlServerDbContextOptionsBuilder.cs @@ -9,7 +9,7 @@ namespace Microsoft.EntityFrameworkCore.Infrastructure; /// Allows SQL Server specific configuration to be performed on . /// /// -/// Instances of this class are returned from a call to +/// Instances of this class are returned from a call to /// /// and it is not designed to be directly constructed in your application code. /// diff --git a/src/EFCore.SqlServer/Metadata/Builders/OwnedNavigationTemporalPeriodPropertyBuilder.cs b/src/EFCore.SqlServer/Metadata/Builders/OwnedNavigationTemporalPeriodPropertyBuilder.cs index 109b86334db..893c6cb1a5d 100644 --- a/src/EFCore.SqlServer/Metadata/Builders/OwnedNavigationTemporalPeriodPropertyBuilder.cs +++ b/src/EFCore.SqlServer/Metadata/Builders/OwnedNavigationTemporalPeriodPropertyBuilder.cs @@ -22,9 +22,7 @@ public class OwnedNavigationTemporalPeriodPropertyBuilder [EntityFrameworkInternal] public OwnedNavigationTemporalPeriodPropertyBuilder( PropertyBuilder propertyBuilder) - { - _propertyBuilder = propertyBuilder; - } + => _propertyBuilder = propertyBuilder; /// /// Configures the column name the period property maps to. diff --git a/src/EFCore.SqlServer/Metadata/Builders/OwnedNavigationTemporalTableBuilder.cs b/src/EFCore.SqlServer/Metadata/Builders/OwnedNavigationTemporalTableBuilder.cs index f3b5835b7bd..56bd7ed1570 100644 --- a/src/EFCore.SqlServer/Metadata/Builders/OwnedNavigationTemporalTableBuilder.cs +++ b/src/EFCore.SqlServer/Metadata/Builders/OwnedNavigationTemporalTableBuilder.cs @@ -21,9 +21,7 @@ public class OwnedNavigationTemporalTableBuilder /// [EntityFrameworkInternal] public OwnedNavigationTemporalTableBuilder(OwnedNavigationBuilder referenceOwnershipBuilder) - { - _referenceOwnershipBuilder = referenceOwnershipBuilder; - } + => _referenceOwnershipBuilder = referenceOwnershipBuilder; /// /// Configures a history table for the entity mapped to a temporal table. diff --git a/src/EFCore.SqlServer/Metadata/Builders/TemporalPeriodPropertyBuilder.cs b/src/EFCore.SqlServer/Metadata/Builders/TemporalPeriodPropertyBuilder.cs index c2cbeb28dc9..d258accabf3 100644 --- a/src/EFCore.SqlServer/Metadata/Builders/TemporalPeriodPropertyBuilder.cs +++ b/src/EFCore.SqlServer/Metadata/Builders/TemporalPeriodPropertyBuilder.cs @@ -21,9 +21,7 @@ public class TemporalPeriodPropertyBuilder : IInfrastructure /// [EntityFrameworkInternal] public TemporalPeriodPropertyBuilder(PropertyBuilder propertyBuilder) - { - _propertyBuilder = propertyBuilder; - } + => _propertyBuilder = propertyBuilder; /// /// Configures the column name the period property maps to. diff --git a/src/EFCore.SqlServer/Metadata/Builders/TemporalTableBuilder.cs b/src/EFCore.SqlServer/Metadata/Builders/TemporalTableBuilder.cs index a62bfc54250..bf465982f67 100644 --- a/src/EFCore.SqlServer/Metadata/Builders/TemporalTableBuilder.cs +++ b/src/EFCore.SqlServer/Metadata/Builders/TemporalTableBuilder.cs @@ -21,9 +21,7 @@ public class TemporalTableBuilder /// [EntityFrameworkInternal] public TemporalTableBuilder(EntityTypeBuilder entityTypeBuilder) - { - _entityTypeBuilder = entityTypeBuilder; - } + => _entityTypeBuilder = entityTypeBuilder; /// /// Configures a history table for the entity mapped to a temporal table. diff --git a/src/EFCore.SqlServer/Metadata/Conventions/SqlServerConventionSetBuilder.cs b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerConventionSetBuilder.cs index 2ad3a9237be..c259704a30a 100644 --- a/src/EFCore.SqlServer/Metadata/Conventions/SqlServerConventionSetBuilder.cs +++ b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerConventionSetBuilder.cs @@ -37,9 +37,7 @@ public SqlServerConventionSetBuilder( RelationalConventionSetBuilderDependencies relationalDependencies, ISqlGenerationHelper sqlGenerationHelper) : base(dependencies, relationalDependencies) - { - _sqlGenerationHelper = sqlGenerationHelper; - } + => _sqlGenerationHelper = sqlGenerationHelper; /// /// Builds and returns the convention set for the current database provider. diff --git a/src/EFCore.SqlServer/Metadata/Conventions/SqlServerOnDeleteConvention.cs b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerOnDeleteConvention.cs index 3f78c87158c..d4d7f076c31 100644 --- a/src/EFCore.SqlServer/Metadata/Conventions/SqlServerOnDeleteConvention.cs +++ b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerOnDeleteConvention.cs @@ -27,9 +27,7 @@ public SqlServerOnDeleteConvention( ProviderConventionSetBuilderDependencies dependencies, RelationalConventionSetBuilderDependencies relationalDependencies) : base(dependencies) - { - RelationalDependencies = relationalDependencies; - } + => RelationalDependencies = relationalDependencies; /// /// Relational provider-specific dependencies for this service. diff --git a/src/EFCore.SqlServer/Migrations/Internal/SqlServerHistoryRepository.cs b/src/EFCore.SqlServer/Migrations/Internal/SqlServerHistoryRepository.cs index cf365bcc2cb..202c7a2c131 100644 --- a/src/EFCore.SqlServer/Migrations/Internal/SqlServerHistoryRepository.cs +++ b/src/EFCore.SqlServer/Migrations/Internal/SqlServerHistoryRepository.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Text; -using Microsoft.Data.SqlClient; namespace Microsoft.EntityFrameworkCore.SqlServer.Migrations.Internal; @@ -60,13 +59,23 @@ protected override bool InterpretExistsResult(object? value) /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public override IDisposable GetDatabaseLock(TimeSpan timeout) + public override LockReleaseBehavior LockReleaseBehavior => LockReleaseBehavior.Connection; + + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + public override IMigrationsDatabaseLock AcquireDatabaseLock() { + Dependencies.MigrationsLogger.AcquiringMigrationLock(); + var dbLock = CreateMigrationDatabaseLock(); int result; try { - result = (int)CreateGetLockCommand(timeout).ExecuteScalar(CreateRelationalCommandParameters())!; + result = (int)CreateGetLockCommand().ExecuteScalar(CreateRelationalCommandParameters())!; } catch { @@ -92,13 +101,15 @@ public override IDisposable GetDatabaseLock(TimeSpan timeout) /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public override async Task GetDatabaseLockAsync(TimeSpan timeout, CancellationToken cancellationToken = default) + public override async Task AcquireDatabaseLockAsync(CancellationToken cancellationToken = default) { + Dependencies.MigrationsLogger.AcquiringMigrationLock(); + var dbLock = CreateMigrationDatabaseLock(); int result; try { - result = (int)(await CreateGetLockCommand(timeout).ExecuteScalarAsync(CreateRelationalCommandParameters(), cancellationToken) + result = (int)(await CreateGetLockCommand().ExecuteScalarAsync(CreateRelationalCommandParameters(), cancellationToken) .ConfigureAwait(false))!; } catch @@ -119,22 +130,25 @@ public override async Task GetDatabaseLockAsync(TimeSpan timeo : dbLock; } - private IRelationalCommand CreateGetLockCommand(TimeSpan timeout) - => Dependencies.RawSqlCommandBuilder.Build(""" + private IRelationalCommand CreateGetLockCommand() + => Dependencies.RawSqlCommandBuilder.Build( + """ DECLARE @result int; -EXEC @result = sp_getapplock @Resource = '__EFMigrationsLock', @LockOwner = 'Session', @LockMode = 'Exclusive', @LockTimeout = @LockTimeout; +EXEC @result = sp_getapplock @Resource = '__EFMigrationsLock', @LockOwner = 'Session', @LockMode = 'Exclusive'; SELECT @result """, - [new SqlParameter("@LockTimeout", timeout.TotalMilliseconds)]).RelationalCommand; + []).RelationalCommand; private SqlServerMigrationDatabaseLock CreateMigrationDatabaseLock() => new( - Dependencies.RawSqlCommandBuilder.Build(""" + Dependencies.RawSqlCommandBuilder.Build( + """ DECLARE @result int; EXEC @result = sp_releaseapplock @Resource = '__EFMigrationsLock', @LockOwner = 'Session'; SELECT @result """), - CreateRelationalCommandParameters()); + CreateRelationalCommandParameters(), + this); private RelationalCommandParameterObject CreateRelationalCommandParameters() => new( diff --git a/src/EFCore.SqlServer/Migrations/Internal/SqlServerMigrationDatabaseLock.cs b/src/EFCore.SqlServer/Migrations/Internal/SqlServerMigrationDatabaseLock.cs index 110dd267fcc..b31ff900625 100644 --- a/src/EFCore.SqlServer/Migrations/Internal/SqlServerMigrationDatabaseLock.cs +++ b/src/EFCore.SqlServer/Migrations/Internal/SqlServerMigrationDatabaseLock.cs @@ -16,11 +16,19 @@ namespace Microsoft.EntityFrameworkCore.SqlServer.Migrations.Internal; /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public class SqlServerMigrationDatabaseLock( - IRelationalCommand relationalCommand, + IRelationalCommand releaseLockCommand, RelationalCommandParameterObject relationalCommandParameters, + IHistoryRepository historyRepository, CancellationToken cancellationToken = default) - : IDisposable, IAsyncDisposable + : IMigrationsDatabaseLock { + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + public virtual IHistoryRepository HistoryRepository => historyRepository; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -29,7 +37,7 @@ public class SqlServerMigrationDatabaseLock( /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public void Dispose() - => relationalCommand.ExecuteScalar(relationalCommandParameters); + => releaseLockCommand.ExecuteScalar(relationalCommandParameters); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -38,5 +46,5 @@ public void Dispose() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public async ValueTask DisposeAsync() - => await relationalCommand.ExecuteScalarAsync(relationalCommandParameters, cancellationToken).ConfigureAwait(false); + => await releaseLockCommand.ExecuteScalarAsync(relationalCommandParameters, cancellationToken).ConfigureAwait(false); } diff --git a/src/EFCore.SqlServer/Migrations/SqlServerMigrationsSqlGenerator.cs b/src/EFCore.SqlServer/Migrations/SqlServerMigrationsSqlGenerator.cs index 91e616f17cb..c25cdcc7eeb 100644 --- a/src/EFCore.SqlServer/Migrations/SqlServerMigrationsSqlGenerator.cs +++ b/src/EFCore.SqlServer/Migrations/SqlServerMigrationsSqlGenerator.cs @@ -42,9 +42,7 @@ public SqlServerMigrationsSqlGenerator( MigrationsSqlGeneratorDependencies dependencies, ICommandBatchPreparer commandBatchPreparer) : base(dependencies) - { - _commandBatchPreparer = commandBatchPreparer; - } + => _commandBatchPreparer = commandBatchPreparer; /// /// Generates commands from a list of operations. @@ -2384,6 +2382,7 @@ private IReadOnlyList RewriteOperations( var temporalTableInformation = BuildTemporalInformationFromMigrationOperation(schema, createTableOperation); temporalTableInformationMap[(tableName, rawSchema)] = temporalTableInformation; } + // no need to remove from missingTemporalTableInformation - CreateTable should be first operation for this table // so there can't be entry for it in missingTemporalTableInformation (they are added by other/earlier operations on that table) // the only possibility is that we had a table before, dropped it and now creating a new table with the same name @@ -2457,6 +2456,7 @@ private IReadOnlyList RewriteOperations( missingTemporalTableInformation.Add((tableName, rawSchema)); } } + break; } } @@ -2565,7 +2565,8 @@ private IReadOnlyList RewriteOperations( operations.Add(operation); var historyTableName = dropTableOperation[SqlServerAnnotationNames.TemporalHistoryTableName] as string; - var historyTableSchema = dropTableOperation[SqlServerAnnotationNames.TemporalHistoryTableSchema] as string ?? schema; + var historyTableSchema = + dropTableOperation[SqlServerAnnotationNames.TemporalHistoryTableSchema] as string ?? schema; var dropHistoryTableOperation = new DropTableOperation { Name = historyTableName!, Schema = historyTableSchema }; operations.Add(dropHistoryTableOperation); } @@ -2742,7 +2743,8 @@ alterTableOperation.OldTable[SqlServerAnnotationNames.TemporalHistoryTableSchema // and de-compress the HistoryTable if (isSparse) { - DecompressTable(temporalInformation.HistoryTableName!, temporalInformation.HistoryTableSchema, suppressTransaction); + DecompressTable( + temporalInformation.HistoryTableName!, temporalInformation.HistoryTableSchema, suppressTransaction); } if (addColumnOperation.ComputedColumnSql != null) @@ -2817,18 +2819,20 @@ alterTableOperation.OldTable[SqlServerAnnotationNames.TemporalHistoryTableSchema if (!droppingPeriodColumn) { - operations.Add(new DropColumnOperation - { - Name = dropColumnOperation.Name, - Table = temporalInformation.HistoryTableName!, - Schema = temporalInformation.HistoryTableSchema - }); + operations.Add( + new DropColumnOperation + { + Name = dropColumnOperation.Name, + Table = temporalInformation.HistoryTableName!, + Schema = temporalInformation.HistoryTableSchema + }); } } else { operations.Add(operation); } + break; } @@ -2899,7 +2903,8 @@ alterTableOperation.OldTable[SqlServerAnnotationNames.TemporalHistoryTableSchema if (changeToSparse) { - DecompressTable(temporalInformation.HistoryTableName!, temporalInformation.HistoryTableSchema, suppressTransaction); + DecompressTable( + temporalInformation.HistoryTableName!, temporalInformation.HistoryTableSchema, suppressTransaction); } operations.Add(alterColumnOperation); @@ -2927,6 +2932,7 @@ alterTableOperation.OldTable[SqlServerAnnotationNames.TemporalHistoryTableSchema { operations.Add(alterColumnOperation); } + break; } @@ -3019,8 +3025,7 @@ void DisableVersioning( } void AddDisableVersioningOperation(string tableName, string? schema, bool suppressTransaction) - { - operations.Add( + => operations.Add( new SqlOperation { Sql = new StringBuilder() @@ -3030,7 +3035,6 @@ void AddDisableVersioningOperation(string tableName, string? schema, bool suppre .ToString(), SuppressTransaction = suppressTransaction }); - } void EnableVersioning(string table, string? schema, string historyTableName, string? historyTableSchema, bool suppressTransaction) { @@ -3153,19 +3157,17 @@ void DecompressTable(string tableName, string? schema, bool suppressTransaction) decompressTableCommand.AppendLine("AND data_compression <> 0)") .Append("EXEC(") - .Append(stringTypeMapping.GenerateSqlLiteral("ALTER TABLE " + - Dependencies.SqlGenerationHelper.DelimitIdentifier(tableName, schema) + - " REBUILD PARTITION = ALL WITH (DATA_COMPRESSION = NONE)" + - Dependencies.SqlGenerationHelper.StatementTerminator)) + .Append( + stringTypeMapping.GenerateSqlLiteral( + "ALTER TABLE " + + Dependencies.SqlGenerationHelper.DelimitIdentifier(tableName, schema) + + " REBUILD PARTITION = ALL WITH (DATA_COMPRESSION = NONE)" + + Dependencies.SqlGenerationHelper.StatementTerminator)) .Append(")") .AppendLine(Dependencies.SqlGenerationHelper.StatementTerminator); operations.Add( - new SqlOperation - { - Sql = decompressTableCommand.ToString(), - SuppressTransaction = suppressTransaction - }); + new SqlOperation { Sql = decompressTableCommand.ToString(), SuppressTransaction = suppressTransaction }); } static TOperation CopyColumnOperation(ColumnOperation source) @@ -3211,11 +3213,11 @@ private sealed class TemporalOperationInformation public string? PeriodStartColumnName { get; set; } public string? PeriodEndColumnName { get; set; } - public bool DisabledVersioning { get; set; } = false; - public bool DisabledPeriod { get; set; } = false; + public bool DisabledVersioning { get; set; } + public bool DisabledPeriod { get; set; } - public bool ShouldEnableVersioning { get; set; } = false; - public bool ShouldEnablePeriod { get; set; } = false; - public bool SuppressTransaction { get; set; } = false; + public bool ShouldEnableVersioning { get; set; } + public bool ShouldEnablePeriod { get; set; } + public bool SuppressTransaction { get; set; } } } diff --git a/src/EFCore.SqlServer/Properties/SqlServerStrings.Designer.cs b/src/EFCore.SqlServer/Properties/SqlServerStrings.Designer.cs index a2394614e7c..00b27a4de1a 100644 --- a/src/EFCore.SqlServer/Properties/SqlServerStrings.Designer.cs +++ b/src/EFCore.SqlServer/Properties/SqlServerStrings.Designer.cs @@ -818,6 +818,31 @@ public static EventDefinition LogFoundUniqueConstraint(IDiagnost return (EventDefinition)definition; } + /// + /// The entity type '{entityType}' makes use of the SQL Server native 'json' type. Please note that support for this type in EF Core 9 is experimental and may change in future releases. + /// + public static EventDefinition LogJsonTypeExperimental(IDiagnosticsLogger logger) + { + var definition = ((Diagnostics.Internal.SqlServerLoggingDefinitions)logger.Definitions).LogJsonTypeExperimental; + if (definition == null) + { + definition = NonCapturingLazyInitializer.EnsureInitialized( + ref ((Diagnostics.Internal.SqlServerLoggingDefinitions)logger.Definitions).LogJsonTypeExperimental, + logger, + static logger => new EventDefinition( + logger.Options, + SqlServerEventId.JsonTypeExperimental, + LogLevel.Warning, + "SqlServerEventId.JsonTypeExperimental", + level => LoggerMessage.Define( + level, + SqlServerEventId.JsonTypeExperimental, + _resourceManager.GetString("LogJsonTypeExperimental")!))); + } + + return (EventDefinition)definition; + } + /// /// Unable to find a schema in the database matching the selected schema '{schema}'. /// diff --git a/src/EFCore.SqlServer/Properties/SqlServerStrings.resx b/src/EFCore.SqlServer/Properties/SqlServerStrings.resx index 5b734aebd29..2f8726af548 100644 --- a/src/EFCore.SqlServer/Properties/SqlServerStrings.resx +++ b/src/EFCore.SqlServer/Properties/SqlServerStrings.resx @@ -1,17 +1,17 @@  - @@ -264,6 +264,10 @@ Found unique constraint on table '{tableName}' with name '{uniqueConstraintName}'. Debug SqlServerEventId.UniqueConstraintFound string string + + The entity type '{entityType}' makes use of the SQL Server native 'json' type. Please note that support for this type in EF Core 9 is experimental and may change in future releases. + Warning SqlServerEventId.JsonTypeExperimental string + Unable to find a schema in the database matching the selected schema '{schema}'. Warning SqlServerEventId.MissingSchemaWarning string? diff --git a/src/EFCore.SqlServer/Query/Internal/SearchConditionConvertingExpressionVisitor.cs b/src/EFCore.SqlServer/Query/Internal/SearchConditionConvertingExpressionVisitor.cs index 0aeca7c0527..16073c7e512 100644 --- a/src/EFCore.SqlServer/Query/Internal/SearchConditionConvertingExpressionVisitor.cs +++ b/src/EFCore.SqlServer/Query/Internal/SearchConditionConvertingExpressionVisitor.cs @@ -24,9 +24,7 @@ public class SearchConditionConvertingExpressionVisitor : SqlExpressionVisitor /// public SearchConditionConvertingExpressionVisitor( ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; private SqlExpression ApplyConversion(SqlExpression sqlExpression, bool condition) => _isSearchCondition @@ -850,6 +848,7 @@ protected override Expression VisitValues(ValuesExpression valuesExpression) { rowValues[i] = (RowValueExpression)Visit(valuesExpression.RowValues[i]); } + _isSearchCondition = parentSearchCondition; return valuesExpression.Update(rowValues); diff --git a/src/EFCore.SqlServer/Query/Internal/SqlExpressions/SqlServerOpenJsonExpression.cs b/src/EFCore.SqlServer/Query/Internal/SqlExpressions/SqlServerOpenJsonExpression.cs index 09c39858a56..cc213ae489c 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlExpressions/SqlServerOpenJsonExpression.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlExpressions/SqlServerOpenJsonExpression.cs @@ -152,6 +152,15 @@ public virtual SqlServerOpenJsonExpression Update( : new SqlServerOpenJsonExpression(Alias, jsonExpression, path, columnInfos); } + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + public virtual SqlServerOpenJsonExpression Update(SqlExpression sqlExpression) + => new(Alias, sqlExpression, Path, ColumnInfos); + /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in diff --git a/src/EFCore.SqlServer/Query/Internal/SqlExpressions/TemporalAllQueryRootExpression.cs b/src/EFCore.SqlServer/Query/Internal/SqlExpressions/TemporalAllQueryRootExpression.cs index 22d46c6989d..18a4726abbe 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlExpressions/TemporalAllQueryRootExpression.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlExpressions/TemporalAllQueryRootExpression.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal; /// diff --git a/src/EFCore.SqlServer/Query/Internal/SqlExpressions/TemporalAsOfQueryRootExpression.cs b/src/EFCore.SqlServer/Query/Internal/SqlExpressions/TemporalAsOfQueryRootExpression.cs index 9713452b311..94473f712a6 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlExpressions/TemporalAsOfQueryRootExpression.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlExpressions/TemporalAsOfQueryRootExpression.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal; /// @@ -20,9 +21,7 @@ public class TemporalAsOfQueryRootExpression : TemporalQueryRootExpression /// public TemporalAsOfQueryRootExpression(IEntityType entityType, DateTime pointInTime) : base(entityType) - { - PointInTime = pointInTime; - } + => PointInTime = pointInTime; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -35,9 +34,7 @@ public TemporalAsOfQueryRootExpression( IEntityType entityType, DateTime pointInTime) : base(queryProvider, entityType) - { - PointInTime = pointInTime; - } + => PointInTime = pointInTime; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer/Query/Internal/SqlExpressions/TemporalBetweenQueryRootExpression.cs b/src/EFCore.SqlServer/Query/Internal/SqlExpressions/TemporalBetweenQueryRootExpression.cs index 56dbe394733..e824a251e1d 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlExpressions/TemporalBetweenQueryRootExpression.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlExpressions/TemporalBetweenQueryRootExpression.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal; /// diff --git a/src/EFCore.SqlServer/Query/Internal/SqlExpressions/TemporalContainedInQueryRootExpression.cs b/src/EFCore.SqlServer/Query/Internal/SqlExpressions/TemporalContainedInQueryRootExpression.cs index 55e51c10c6e..c8ff1c391b8 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlExpressions/TemporalContainedInQueryRootExpression.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlExpressions/TemporalContainedInQueryRootExpression.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal; /// diff --git a/src/EFCore.SqlServer/Query/Internal/SqlExpressions/TemporalFromToQueryRootExpression.cs b/src/EFCore.SqlServer/Query/Internal/SqlExpressions/TemporalFromToQueryRootExpression.cs index eb156696f4e..522b8f46864 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlExpressions/TemporalFromToQueryRootExpression.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlExpressions/TemporalFromToQueryRootExpression.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal; /// diff --git a/src/EFCore.SqlServer/Query/Internal/SqlExpressions/TemporalQueryRootExpression.cs b/src/EFCore.SqlServer/Query/Internal/SqlExpressions/TemporalQueryRootExpression.cs index 1936eadda57..fa80b6e2ee8 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlExpressions/TemporalQueryRootExpression.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlExpressions/TemporalQueryRootExpression.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal; /// diff --git a/src/EFCore.SqlServer/Query/Internal/SqlExpressions/TemporalRangeQueryRootExpression.cs b/src/EFCore.SqlServer/Query/Internal/SqlExpressions/TemporalRangeQueryRootExpression.cs index 4de358fbf51..cba020aac35 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlExpressions/TemporalRangeQueryRootExpression.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlExpressions/TemporalRangeQueryRootExpression.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable once CheckNamespace + namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal; /// diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerAggregateOverSubqueryPostprocessor.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerAggregateOverSubqueryPostprocessor.cs index 9f9fc6288d4..1322647c8eb 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerAggregateOverSubqueryPostprocessor.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerAggregateOverSubqueryPostprocessor.cs @@ -84,7 +84,7 @@ when function.Name.ToLower(CultureInfo.InvariantCulture) is "sum" or "avg" or "m var parentAggregateArgumentContainsSubquery = _aggregateArgumentContainsSubquery; _inAggregateInvocation = true; _isCorrelatedSubquery = false; - _tableAliasesInScope = new(); + _tableAliasesInScope = new HashSet(); _aggregateArgumentContainsSubquery = false; var result = base.VisitExtension(function); @@ -151,7 +151,7 @@ when function.Name.ToLower(CultureInfo.InvariantCulture) is "sum" or "avg" or "m #pragma warning restore EF1001 } - _joinsToAdd ??= new(); + _joinsToAdd ??= new List(); _joinsToAdd.Add( _isCorrelatedSubquery ? new OuterApplyExpression(liftedSubquery) : new CrossJoinExpression(liftedSubquery)); diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerCompiledQueryCacheKeyGenerator.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerCompiledQueryCacheKeyGenerator.cs index ab3925adda2..8b8426e8060 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerCompiledQueryCacheKeyGenerator.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerCompiledQueryCacheKeyGenerator.cs @@ -26,9 +26,7 @@ public SqlServerCompiledQueryCacheKeyGenerator( RelationalCompiledQueryCacheKeyGeneratorDependencies relationalDependencies, ISqlServerConnection sqlServerConnection) : base(dependencies, relationalDependencies) - { - _sqlServerConnection = sqlServerConnection; - } + => _sqlServerConnection = sqlServerConnection; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerJsonPostprocessor.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerJsonPostprocessor.cs index 9d301e6deb3..f523032f5cd 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerJsonPostprocessor.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerJsonPostprocessor.cs @@ -12,12 +12,12 @@ namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal; /// /// Performs various post-processing rewriting to account for SQL Server JSON quirks. /// 1. Converts expressions with WITH (the default) to OPENJSON without WITH under the -/// following conditions: -/// * When an ordering still exists on the [key] column, i.e. when the ordering of the original JSON array needs to be preserved -/// (e.g. limit/offset). -/// * When the column type in the WITH clause is a SQL Server "CLR type" - these are incompatible with WITH (e.g. hierarchy id). +/// following conditions: +/// * When an ordering still exists on the [key] column, i.e. when the ordering of the original JSON array needs to be preserved +/// (e.g. limit/offset). +/// * When the column type in the WITH clause is a SQL Server "CLR type" - these are incompatible with WITH (e.g. hierarchy id). /// 2. Rewrite JsonScalarExpression (JSON_VALUE()) to OPENJSON for when JSON_VALUE() isn't compatible with the type (e.g. binary data -/// which needs to be base64-decoded). +/// which needs to be base64-decoded). /// /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -79,12 +79,12 @@ public Expression Process(Expression expression) if (table.UnwrapJoin() is SqlServerOpenJsonExpression { ColumnInfos: { } columnInfos } openJsonExpression // Condition 1: an ordering/projection still refers to the OPENJSON's [key] column - it needs to be preserved. && (selectExpression.Orderings.Select(o => o.Expression) - .Concat(selectExpression.Projection.Select(p => p.Expression)) - .Any(x => IsKeyColumn(x, openJsonExpression.Alias)) - || - // Condition 2: a column type in the WITH clause is a SQL Server "CLR type" (e.g. hierarchy id). - // These are not supported by OPENJSON with WITH. - columnInfos.Any(c => c.TypeMapping.StoreType is "hierarchyid"))) + .Concat(selectExpression.Projection.Select(p => p.Expression)) + .Any(x => IsKeyColumn(x, openJsonExpression.Alias)) + || + // Condition 2: a column type in the WITH clause is a SQL Server "CLR type" (e.g. hierarchy id). + // These are not supported by OPENJSON with WITH. + columnInfos.Any(c => c.TypeMapping.StoreType is "hierarchyid"))) { // Remove the WITH clause from the OPENJSON expression var newOpenJsonExpression = openJsonExpression.Update( @@ -101,7 +101,7 @@ public Expression Process(Expression expression) foreach (var columnInfo in columnInfos) { - columnsToRewrite ??= new(); + columnsToRewrite ??= new Dictionary<(string, string), ColumnInfo>(); columnsToRewrite.Add((newOpenJsonExpression.Alias, columnInfo.Name), columnInfo); } @@ -199,7 +199,11 @@ when _columnsToRewrite.TryGetValue((columnExpression.TableAlias, columnExpressio // The new OPENJSON (without WITH) always projects a `value` column, instead of a properly named column for individual // values inside; create a new ColumnExpression with that name. SqlExpression rewrittenColumn = new ColumnExpression( - "value", columnExpression.TableAlias, columnExpression.Type, _nvarcharMaxTypeMapping, columnExpression.IsNullable); + "value", + columnExpression.TableAlias, + columnExpression.Type, + _nvarcharMaxTypeMapping, + columnExpression.IsNullable); // Prepend the path from the OPENJSON/WITH to the path in the JsonScalarExpression var path = columnInfo.Path is null @@ -207,7 +211,10 @@ when _columnsToRewrite.TryGetValue((columnExpression.TableAlias, columnExpressio : columnInfo.Path.Concat(jsonScalarExpression.Path).ToList(); return new JsonScalarExpression( - rewrittenColumn, path, jsonScalarExpression.Type, jsonScalarExpression.TypeMapping, + rewrittenColumn, + path, + jsonScalarExpression.Type, + jsonScalarExpression.TypeMapping, jsonScalarExpression.IsNullable); } @@ -219,23 +226,45 @@ when _columnsToRewrite.TryGetValue((columnExpression.TableAlias, columnExpressio case JsonScalarExpression { TypeMapping.StoreTypeNameBase: "varbinary" or "binary" } jsonScalar: { var name = jsonScalar.Path.LastOrDefault(ps => ps.PropertyName is not null).PropertyName - ?? (jsonScalar.Json as ColumnExpression)?.Name - ?? "Json"; + ?? (jsonScalar.Json as ColumnExpression)?.Name + ?? "Json"; var tableAlias = sqlAliasManager.GenerateTableAlias(name); var join = new OuterApplyExpression( new SqlServerOpenJsonExpression( - tableAlias, jsonScalar.Json, path: null, - columnInfos: [new(name, jsonScalar.TypeMapping, jsonScalar.Path)])); + tableAlias, + jsonScalar.Json, + path: null, + columnInfos: [new ColumnInfo(name, jsonScalar.TypeMapping, jsonScalar.Path)])); // We record the new OUTER APPLY in _openWithOuterAppliesToAdd (it gets added after visiting the SelectExpression above), // and return a ColumnExpression referencing that new OUTER APPLY. _openjsonOuterAppliesToAdd.Add(join); - return new ColumnExpression(name, tableAlias, jsonScalar.Type, jsonScalar.TypeMapping, + return new ColumnExpression( + name, + tableAlias, + jsonScalar.Type, + jsonScalar.TypeMapping, jsonScalar.IsNullable); } + case SqlServerOpenJsonExpression openJsonExpression: + // Currently, OPENJSON does not accept a "json" type, so we must cast the value to a string. + // We do this for both the case where is a string type mapping for a top-level property with the store type + // of "json", and when there is an "element" type mapping to something in the document but is now being used + // with OPENJSON. + return openJsonExpression.JsonExpression.TypeMapping + is SqlServerStringTypeMapping { StoreType: "json" } + or SqlServerOwnedJsonTypeMapping { StoreType: "json" } + ? openJsonExpression.Update( + new SqlUnaryExpression( + ExpressionType.Convert, + (SqlExpression)Visit(openJsonExpression.JsonExpression), + typeof(string), + typeMappingSource.FindMapping(typeof(string))!)) + : base.Visit(expression); + default: return base.Visit(expression); } diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerMethodCallTranslatorProvider.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerMethodCallTranslatorProvider.cs index 9c960d29c1c..79a99b8c437 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerMethodCallTranslatorProvider.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerMethodCallTranslatorProvider.cs @@ -19,7 +19,9 @@ public class SqlServerMethodCallTranslatorProvider : RelationalMethodCallTransla /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public SqlServerMethodCallTranslatorProvider(RelationalMethodCallTranslatorProviderDependencies dependencies, ISqlServerSingletonOptions sqlServerSingletonOptions) + public SqlServerMethodCallTranslatorProvider( + RelationalMethodCallTranslatorProviderDependencies dependencies, + ISqlServerSingletonOptions sqlServerSingletonOptions) : base(dependencies) { var sqlExpressionFactory = dependencies.SqlExpressionFactory; diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerNavigationExpansionExtensibilityHelper.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerNavigationExpansionExtensibilityHelper.cs index 72ae2e2ca6f..58d46e1e71b 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerNavigationExpansionExtensibilityHelper.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerNavigationExpansionExtensibilityHelper.cs @@ -74,8 +74,8 @@ public override void ValidateQueryRootCreation(IEntityType entityType, EntityQue private bool OwnedEntityMappedToSameTableAsOwner(IEntityType entityType) => entityType.IsOwned() && entityType.FindOwnership()!.PrincipalEntityType.GetTableMappings().FirstOrDefault()?.Table is ITable ownerTable - && entityType.GetTableMappings().FirstOrDefault()?.Table is ITable entityTable - && ownerTable == entityTable; + && entityType.GetTableMappings().FirstOrDefault()?.Table is ITable entityTable + && ownerTable == entityTable; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerParameterBasedSqlProcessorFactory.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerParameterBasedSqlProcessorFactory.cs index 2f9a897ecf5..9d60b17dba7 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerParameterBasedSqlProcessorFactory.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerParameterBasedSqlProcessorFactory.cs @@ -19,9 +19,7 @@ public class SqlServerParameterBasedSqlProcessorFactory : IRelationalParameterBa /// public SqlServerParameterBasedSqlProcessorFactory( RelationalParameterBasedSqlProcessorDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Relational provider-specific dependencies for this service. diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerQueryCompilationContext.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerQueryCompilationContext.cs index a5ea2cdf6e5..1b5abdfcbe8 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerQueryCompilationContext.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerQueryCompilationContext.cs @@ -29,9 +29,7 @@ public SqlServerQueryCompilationContext( : this( dependencies, relationalDependencies, async, multipleActiveResultSetsEnabled, precompiling: false, nonNullableReferenceTypeParameters: null) - { - _multipleActiveResultSetsEnabled = multipleActiveResultSetsEnabled; - } + => _multipleActiveResultSetsEnabled = multipleActiveResultSetsEnabled; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -48,9 +46,7 @@ public SqlServerQueryCompilationContext( bool precompiling, IReadOnlySet? nonNullableReferenceTypeParameters) : base(dependencies, relationalDependencies, async, precompiling, nonNullableReferenceTypeParameters) - { - _multipleActiveResultSetsEnabled = multipleActiveResultSetsEnabled; - } + => _multipleActiveResultSetsEnabled = multipleActiveResultSetsEnabled; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -64,5 +60,6 @@ public override bool IsBuffering && !_multipleActiveResultSetsEnabled); /// - public override bool SupportsPrecompiledQuery => true; + public override bool SupportsPrecompiledQuery + => true; } diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGenerator.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGenerator.cs index 6e5693a4670..dfb054b097f 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGenerator.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGenerator.cs @@ -475,7 +475,7 @@ protected override Expression VisitJsonScalar(JsonScalarExpression jsonScalarExp return jsonScalarExpression; } - if (jsonScalarExpression.TypeMapping is SqlServerJsonTypeMapping + if (jsonScalarExpression.TypeMapping is SqlServerOwnedJsonTypeMapping || jsonScalarExpression.TypeMapping?.ElementTypeMapping is not null) { Sql.Append("JSON_QUERY("); @@ -494,7 +494,7 @@ protected override Expression VisitJsonScalar(JsonScalarExpression jsonScalarExp GenerateJsonPath(jsonScalarExpression.Path); Sql.Append(")"); - if (jsonScalarExpression.TypeMapping is not SqlServerJsonTypeMapping and not StringTypeMapping) + if (jsonScalarExpression.TypeMapping is not SqlServerOwnedJsonTypeMapping and not StringTypeMapping) { Sql.Append(" AS "); Sql.Append(jsonScalarExpression.TypeMapping!.StoreType); @@ -540,10 +540,12 @@ private void GenerateJsonPath(IReadOnlyList path) break; case SqlServerEngineType.SqlServer: throw new InvalidOperationException( - SqlServerStrings.JsonValuePathExpressionsNotSupported(_sqlServerSingletonOptions.SqlServerCompatibilityLevel)); + SqlServerStrings.JsonValuePathExpressionsNotSupported( + _sqlServerSingletonOptions.SqlServerCompatibilityLevel)); case SqlServerEngineType.AzureSql: throw new InvalidOperationException( - SqlServerStrings.JsonValuePathExpressionsNotSupported(_sqlServerSingletonOptions.AzureSqlCompatibilityLevel)); + SqlServerStrings.JsonValuePathExpressionsNotSupported( + _sqlServerSingletonOptions.AzureSqlCompatibilityLevel)); } } diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerQueryStringFactory.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerQueryStringFactory.cs index cd3c0f3fdd6..e9f025e35c4 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerQueryStringFactory.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerQueryStringFactory.cs @@ -27,9 +27,7 @@ public class SqlServerQueryStringFactory : IRelationalQueryStringFactory /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqlServerQueryStringFactory(IRelationalTypeMappingSource typeMapper) - { - _typeMapper = typeMapper; - } + => _typeMapper = typeMapper; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerQueryTranslationPostprocessor.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerQueryTranslationPostprocessor.cs index 86608b53dee..714a20e123b 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerQueryTranslationPostprocessor.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerQueryTranslationPostprocessor.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics.CodeAnalysis; -using Microsoft.EntityFrameworkCore.Query.Internal; using Microsoft.EntityFrameworkCore.Query.SqlExpressions; using Microsoft.EntityFrameworkCore.SqlServer.Internal; @@ -62,7 +61,8 @@ public override Expression Process(Expression query) /// doing so can result in application failures when updating to a new Entity Framework Core release. /// protected override Expression ProcessTypeMappings(Expression expression) - => new SqlServerTypeMappingPostprocessor(Dependencies, RelationalDependencies, RelationalQueryCompilationContext).Process(expression); + => new SqlServerTypeMappingPostprocessor(Dependencies, RelationalDependencies, RelationalQueryCompilationContext).Process( + expression); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -97,8 +97,8 @@ private sealed class SkipWithoutOrderByInSplitQueryVerifier : ExpressionVisitor case SelectExpression { Offset: not null, Orderings.Count: 0 }: throw new InvalidOperationException(SqlServerStrings.SplitQueryOffsetWithoutOrderBy); - case NonQueryExpression nonQueryExpression: - return nonQueryExpression; + case UpdateExpression or DeleteExpression: + return expression; default: return base.Visit(expression); diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerQueryTranslationPostprocessorFactory.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerQueryTranslationPostprocessorFactory.cs index e912edba794..a7b5e069d28 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerQueryTranslationPostprocessorFactory.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerQueryTranslationPostprocessorFactory.cs @@ -11,8 +11,6 @@ namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal; /// public class SqlServerQueryTranslationPostprocessorFactory : IQueryTranslationPostprocessorFactory { - private readonly IRelationalTypeMappingSource _typeMappingSource; - /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in @@ -21,12 +19,10 @@ public class SqlServerQueryTranslationPostprocessorFactory : IQueryTranslationPo /// public SqlServerQueryTranslationPostprocessorFactory( QueryTranslationPostprocessorDependencies dependencies, - RelationalQueryTranslationPostprocessorDependencies relationalDependencies, - IRelationalTypeMappingSource typeMappingSource) + RelationalQueryTranslationPostprocessorDependencies relationalDependencies) { Dependencies = dependencies; RelationalDependencies = relationalDependencies; - _typeMappingSource = typeMappingSource; } /// @@ -46,5 +42,6 @@ public SqlServerQueryTranslationPostprocessorFactory( /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual QueryTranslationPostprocessor Create(QueryCompilationContext queryCompilationContext) - => new SqlServerQueryTranslationPostprocessor(Dependencies, RelationalDependencies, (SqlServerQueryCompilationContext)queryCompilationContext); + => new SqlServerQueryTranslationPostprocessor( + Dependencies, RelationalDependencies, (SqlServerQueryCompilationContext)queryCompilationContext); } diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerQueryableMethodTranslatingExpressionVisitor.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerQueryableMethodTranslatingExpressionVisitor.cs index e82a7a614f7..ca8d8690824 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerQueryableMethodTranslatingExpressionVisitor.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerQueryableMethodTranslatingExpressionVisitor.cs @@ -129,15 +129,20 @@ protected override Expression VisitExtension(Expression extensionExpression) IProperty? property, string tableAlias) { - if (_sqlServerSingletonOptions.EngineType == SqlServerEngineType.SqlServer && _sqlServerSingletonOptions.SqlServerCompatibilityLevel < 130) + if (_sqlServerSingletonOptions.EngineType == SqlServerEngineType.SqlServer + && _sqlServerSingletonOptions.SqlServerCompatibilityLevel < 130) { - AddTranslationErrorDetails(SqlServerStrings.CompatibilityLevelTooLowForScalarCollections(_sqlServerSingletonOptions.SqlServerCompatibilityLevel)); + AddTranslationErrorDetails( + SqlServerStrings.CompatibilityLevelTooLowForScalarCollections(_sqlServerSingletonOptions.SqlServerCompatibilityLevel)); return null; } - if (_sqlServerSingletonOptions.EngineType == SqlServerEngineType.AzureSql && _sqlServerSingletonOptions.AzureSqlCompatibilityLevel < 130) + + if (_sqlServerSingletonOptions.EngineType == SqlServerEngineType.AzureSql + && _sqlServerSingletonOptions.AzureSqlCompatibilityLevel < 130) { - AddTranslationErrorDetails(SqlServerStrings.CompatibilityLevelTooLowForScalarCollections(_sqlServerSingletonOptions.AzureSqlCompatibilityLevel)); + AddTranslationErrorDetails( + SqlServerStrings.CompatibilityLevelTooLowForScalarCollections(_sqlServerSingletonOptions.AzureSqlCompatibilityLevel)); return null; } @@ -182,7 +187,11 @@ protected override Expression VisitExtension(Expression extensionExpression) elementClrType.UnwrapNullableType(), elementTypeMapping, isElementNullable ?? elementClrType.IsNullableType()), - identifier: [(new ColumnExpression("key", tableAlias, typeof(string), keyColumnTypeMapping, nullable: false), keyColumnTypeMapping.Comparer)], + identifier: + [ + (new ColumnExpression("key", tableAlias, typeof(string), keyColumnTypeMapping, nullable: false), + keyColumnTypeMapping.Comparer) + ], _queryCompilationContext.SqlAliasManager); #pragma warning restore EF1001 // Internal EF Core API usage. @@ -433,39 +442,11 @@ protected override bool IsNaturallyOrdered(SelectExpression selectExpression) /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - protected override bool IsValidSelectExpressionForExecuteDelete( - SelectExpression selectExpression, - StructuralTypeShaperExpression shaper, - [NotNullWhen(true)] out TableExpression? tableExpression) - { - if (selectExpression.Offset == null - && selectExpression.GroupBy.Count == 0 - && selectExpression.Having == null - && selectExpression.Orderings.Count == 0) - { - TableExpressionBase table; - if (selectExpression.Tables.Count == 1) - { - table = selectExpression.Tables[0]; - } - else - { - var projectionBindingExpression = (ProjectionBindingExpression)shaper.ValueBufferExpression; - var projection = (StructuralTypeProjectionExpression)selectExpression.GetProjection(projectionBindingExpression); - var column = projection.BindProperty(shaper.StructuralType.GetProperties().First()); - table = selectExpression.GetTable(column).UnwrapJoin(); - } - - if (table is TableExpression te) - { - tableExpression = te; - return true; - } - } - - tableExpression = null; - return false; - } + protected override bool IsValidSelectExpressionForExecuteDelete(SelectExpression selectExpression) + => selectExpression.Offset == null + && selectExpression.GroupBy.Count == 0 + && selectExpression.Having == null + && selectExpression.Orderings.Count == 0; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerSqlExpressionFactory.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerSqlExpressionFactory.cs index f84f3e1abb8..d1aa8cb1828 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerSqlExpressionFactory.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerSqlExpressionFactory.cs @@ -3,7 +3,6 @@ using System.Diagnostics.CodeAnalysis; using Microsoft.EntityFrameworkCore.Query.SqlExpressions; -using Microsoft.EntityFrameworkCore.SqlServer.Infrastructure.Internal; namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal; @@ -26,9 +25,7 @@ public class SqlServerSqlExpressionFactory : SqlExpressionFactory public SqlServerSqlExpressionFactory( SqlExpressionFactoryDependencies dependencies) : base(dependencies) - { - _typeMappingSource = dependencies.TypeMappingSource; - } + => _typeMappingSource = dependencies.TypeMappingSource; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerSqlNullabilityProcessor.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerSqlNullabilityProcessor.cs index 9a41d9caa7b..a3fb56ea225 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerSqlNullabilityProcessor.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerSqlNullabilityProcessor.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Collections; using System.Diagnostics.CodeAnalysis; using Microsoft.EntityFrameworkCore.Query.SqlExpressions; diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerSqlTranslatingExpressionVisitor.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerSqlTranslatingExpressionVisitor.cs index 402b615a13e..039d146feb2 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerSqlTranslatingExpressionVisitor.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerSqlTranslatingExpressionVisitor.cs @@ -211,8 +211,10 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp // Translate non-aggregate string.Join to CONCAT_WS (for aggregate string.Join, see SqlServerStringAggregateMethodTranslator) if (method == StringJoinMethodInfo && methodCallExpression.Arguments[1] is NewArrayExpression newArrayExpression - && ((_sqlServerSingletonOptions.EngineType == SqlServerEngineType.SqlServer && _sqlServerSingletonOptions.SqlServerCompatibilityLevel >= 140) - || (_sqlServerSingletonOptions.EngineType == SqlServerEngineType.AzureSql && _sqlServerSingletonOptions.AzureSqlCompatibilityLevel >= 140) + && ((_sqlServerSingletonOptions.EngineType == SqlServerEngineType.SqlServer + && _sqlServerSingletonOptions.SqlServerCompatibilityLevel >= 140) + || (_sqlServerSingletonOptions.EngineType == SqlServerEngineType.AzureSql + && _sqlServerSingletonOptions.AzureSqlCompatibilityLevel >= 140) || (_sqlServerSingletonOptions.EngineType == SqlServerEngineType.AzureSynapse))) { if (TranslationFailed(methodCallExpression.Arguments[0], Visit(methodCallExpression.Arguments[0]), out var delimiter)) @@ -295,20 +297,8 @@ bool TryTranslateStartsEndsWithContains( // (but SqlNullabilityProcess will convert this to a true constant if the instance is non-nullable) "" => _sqlExpressionFactory.Like(translatedInstance, _sqlExpressionFactory.Constant("%")), - string s => s.Any(IsLikeWildChar) - ? _sqlExpressionFactory.Like( - translatedInstance, - _sqlExpressionFactory.Constant( - methodType switch - { - StartsEndsWithContains.StartsWith => EscapeLikePattern(s) + '%', - StartsEndsWithContains.EndsWith => '%' + EscapeLikePattern(s), - StartsEndsWithContains.Contains => $"%{EscapeLikePattern(s)}%", - - _ => throw new ArgumentOutOfRangeException(nameof(methodType), methodType, null) - }), - _sqlExpressionFactory.Constant(LikeEscapeString)) - : _sqlExpressionFactory.Like( + string s when !s.Any(IsLikeWildChar) + => _sqlExpressionFactory.Like( translatedInstance, _sqlExpressionFactory.Constant( methodType switch @@ -320,6 +310,24 @@ bool TryTranslateStartsEndsWithContains( _ => throw new ArgumentOutOfRangeException(nameof(methodType), methodType, null) })), + // Azure Synapse does not support ESCAPE clause in LIKE + // fallback to translation like with column/expression + string s when _sqlServerSingletonOptions.EngineType == SqlServerEngineType.AzureSynapse + => TranslateWithoutLike(patternIsNonEmptyConstantString: true), + + string s => _sqlExpressionFactory.Like( + translatedInstance, + _sqlExpressionFactory.Constant( + methodType switch + { + StartsEndsWithContains.StartsWith => EscapeLikePattern(s) + '%', + StartsEndsWithContains.EndsWith => '%' + EscapeLikePattern(s), + StartsEndsWithContains.Contains => $"%{EscapeLikePattern(s)}%", + + _ => throw new ArgumentOutOfRangeException(nameof(methodType), methodType, null) + }), + _sqlExpressionFactory.Constant(LikeEscapeString)), + _ => throw new UnreachableException() }; @@ -327,7 +335,10 @@ bool TryTranslateStartsEndsWithContains( } case SqlParameterExpression patternParameter - when patternParameter.Name.StartsWith(QueryCompilationContext.QueryParameterPrefix, StringComparison.Ordinal): + when patternParameter.Name.StartsWith(QueryCompilationContext.QueryParameterPrefix, StringComparison.Ordinal) + // Azure Synapse does not support ESCAPE clause in LIKE + // fall through to translation like with column/expression + && _sqlServerSingletonOptions.EngineType != SqlServerEngineType.AzureSynapse: { // The pattern is a parameter, register a runtime parameter that will contain the rewritten LIKE pattern, where // all special characters have been escaped. @@ -354,23 +365,29 @@ when patternParameter.Name.StartsWith(QueryCompilationContext.QueryParameterPref default: // The pattern is a column or a complex expression; the possible special characters in the pattern cannot be escaped, // preventing us from translating to LIKE. - translation = methodType switch - { - // For StartsWith/EndsWith, use LEFT or RIGHT instead to extract substring and compare: - // WHERE instance IS NOT NULL AND pattern IS NOT NULL AND LEFT(instance, LEN(pattern)) = pattern - // This is less efficient than LIKE (i.e. StartsWith does an index scan instead of seek), but we have no choice. - // Note that we compensate for the case where both the instance and the pattern are null (null.StartsWith(null)); a - // simple equality would yield true in that case, but we want false. We technically - StartsEndsWithContains.StartsWith or StartsEndsWithContains.EndsWith - => _sqlExpressionFactory.AndAlso( - _sqlExpressionFactory.IsNotNull(translatedInstance), - _sqlExpressionFactory.AndAlso( - _sqlExpressionFactory.IsNotNull(translatedPattern), - _sqlExpressionFactory.Equal( - _sqlExpressionFactory.Function( - methodType is StartsEndsWithContains.StartsWith ? "LEFT" : "RIGHT", - new[] - { + translation = TranslateWithoutLike(); + return true; + } + + SqlExpression TranslateWithoutLike(bool patternIsNonEmptyConstantString = false) + { + return methodType switch + { + // For StartsWith/EndsWith, use LEFT or RIGHT instead to extract substring and compare: + // WHERE instance IS NOT NULL AND pattern IS NOT NULL AND LEFT(instance, LEN(pattern)) = pattern + // This is less efficient than LIKE (i.e. StartsWith does an index scan instead of seek), but we have no choice. + // Note that we compensate for the case where both the instance and the pattern are null (null.StartsWith(null)); a + // simple equality would yield true in that case, but we want false. We technically + StartsEndsWithContains.StartsWith or StartsEndsWithContains.EndsWith + => _sqlExpressionFactory.AndAlso( + _sqlExpressionFactory.IsNotNull(translatedInstance), + _sqlExpressionFactory.AndAlso( + _sqlExpressionFactory.IsNotNull(translatedPattern), + _sqlExpressionFactory.Equal( + _sqlExpressionFactory.Function( + methodType is StartsEndsWithContains.StartsWith ? "LEFT" : "RIGHT", + new[] + { translatedInstance, _sqlExpressionFactory.Function( "LEN", @@ -378,37 +395,44 @@ StartsEndsWithContains.StartsWith or StartsEndsWithContains.EndsWith nullable: true, argumentsPropagateNullability: new[] { true }, typeof(int)) - }, - nullable: true, - argumentsPropagateNullability: new[] { true, true }, - typeof(string), - stringTypeMapping), - translatedPattern))), - - // For Contains, just use CHARINDEX and check if the result is greater than 0. - // Add a check to return null when the pattern is an empty string (and the string isn't null) - StartsEndsWithContains.Contains - => _sqlExpressionFactory.AndAlso( - _sqlExpressionFactory.IsNotNull(translatedInstance), - _sqlExpressionFactory.AndAlso( - _sqlExpressionFactory.IsNotNull(translatedPattern), - _sqlExpressionFactory.OrElse( - _sqlExpressionFactory.GreaterThan( - _sqlExpressionFactory.Function( - "CHARINDEX", - new[] { translatedPattern, translatedInstance }, - nullable: true, - argumentsPropagateNullability: new[] { true, true }, - typeof(int)), - _sqlExpressionFactory.Constant(0)), - _sqlExpressionFactory.Like( - translatedPattern, - _sqlExpressionFactory.Constant(string.Empty, stringTypeMapping))))), - - _ => throw new UnreachableException() - }; - - return true; + }, + nullable: true, + argumentsPropagateNullability: new[] { true, true }, + typeof(string), + stringTypeMapping), + translatedPattern))), + + // For Contains, just use CHARINDEX and check if the result is greater than 0. + StartsEndsWithContains.Contains when patternIsNonEmptyConstantString + => _sqlExpressionFactory.AndAlso( + _sqlExpressionFactory.IsNotNull(translatedInstance), + CharIndexGreaterThanZero()), + + // For Contains, just use CHARINDEX and check if the result is greater than 0. + // Add a check to return null when the pattern is an empty string (and the string isn't null) + StartsEndsWithContains.Contains + => _sqlExpressionFactory.AndAlso( + _sqlExpressionFactory.IsNotNull(translatedInstance), + _sqlExpressionFactory.AndAlso( + _sqlExpressionFactory.IsNotNull(translatedPattern), + _sqlExpressionFactory.OrElse( + CharIndexGreaterThanZero(), + _sqlExpressionFactory.Like( + translatedPattern, + _sqlExpressionFactory.Constant(string.Empty, stringTypeMapping))))), + + _ => throw new UnreachableException() + }; + + SqlExpression CharIndexGreaterThanZero() + => _sqlExpressionFactory.GreaterThan( + _sqlExpressionFactory.Function( + "CHARINDEX", + new[] { translatedPattern, translatedInstance }, + nullable: true, + argumentsPropagateNullability: new[] { true, true }, + typeof(int)), + _sqlExpressionFactory.Constant(0)); } } } @@ -540,6 +564,7 @@ private static string EscapeLikePattern(string pattern) { return null; } + if (_sqlServerSingletonOptions.EngineType == SqlServerEngineType.AzureSql && _sqlServerSingletonOptions.AzureSqlCompatibilityLevel < 160) { @@ -568,6 +593,7 @@ private static string EscapeLikePattern(string pattern) { return null; } + if (_sqlServerSingletonOptions.EngineType == SqlServerEngineType.AzureSql && _sqlServerSingletonOptions.AzureSqlCompatibilityLevel < 160) { diff --git a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerByteArrayMethodTranslator.cs b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerByteArrayMethodTranslator.cs index dc50a5a2008..e9740e070e7 100644 --- a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerByteArrayMethodTranslator.cs +++ b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerByteArrayMethodTranslator.cs @@ -23,9 +23,7 @@ public class SqlServerByteArrayMethodTranslator : IMethodCallTranslator /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqlServerByteArrayMethodTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -49,15 +47,15 @@ public SqlServerByteArrayMethodTranslator(ISqlExpressionFactory sqlExpressionFac var sourceTypeMapping = source.TypeMapping; var value = arguments[1] is SqlConstantExpression constantValue - ? (SqlExpression)_sqlExpressionFactory.Constant(new[] { (byte)constantValue.Value! }, sourceTypeMapping) + ? _sqlExpressionFactory.Constant(new[] { (byte)constantValue.Value! }, sourceTypeMapping) : _sqlExpressionFactory.Convert(arguments[1], typeof(byte[]), sourceTypeMapping); return _sqlExpressionFactory.GreaterThan( _sqlExpressionFactory.Function( "CHARINDEX", - new[] { value, source }, + [value, source], nullable: true, - argumentsPropagateNullability: new[] { true, true }, + argumentsPropagateNullability: [true, true], typeof(int)), _sqlExpressionFactory.Constant(0)); } @@ -68,9 +66,9 @@ public SqlServerByteArrayMethodTranslator(ISqlExpressionFactory sqlExpressionFac return _sqlExpressionFactory.Convert( _sqlExpressionFactory.Function( "SUBSTRING", - new[] { arguments[0], _sqlExpressionFactory.Constant(1), _sqlExpressionFactory.Constant(1) }, + [arguments[0], _sqlExpressionFactory.Constant(1), _sqlExpressionFactory.Constant(1)], nullable: true, - argumentsPropagateNullability: new[] { true, true, true }, + argumentsPropagateNullability: [true, true, true], typeof(byte[])), method.ReturnType); } diff --git a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerConvertTranslator.cs b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerConvertTranslator.cs index 5bd07b1a8a9..3da7cde0c77 100644 --- a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerConvertTranslator.cs +++ b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerConvertTranslator.cs @@ -59,9 +59,7 @@ private static readonly MethodInfo[] SupportedMethods /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqlServerConvertTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerDataLengthFunctionTranslator.cs b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerDataLengthFunctionTranslator.cs index 18a70bc0120..83d1aa4fcea 100644 --- a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerDataLengthFunctionTranslator.cs +++ b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerDataLengthFunctionTranslator.cs @@ -53,9 +53,7 @@ private static readonly HashSet MethodInfoDataLengthMapping /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqlServerDataLengthFunctionTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerDateDiffFunctionsTranslator.cs b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerDateDiffFunctionsTranslator.cs index b056890c53a..e0bc46dd906 100644 --- a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerDateDiffFunctionsTranslator.cs +++ b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerDateDiffFunctionsTranslator.cs @@ -533,9 +533,7 @@ private readonly Dictionary _methodInfoDateDiffMapping /// public SqlServerDateDiffFunctionsTranslator( ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerDateOnlyMemberTranslator.cs b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerDateOnlyMemberTranslator.cs index dfda2ddad35..03f0255165e 100644 --- a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerDateOnlyMemberTranslator.cs +++ b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerDateOnlyMemberTranslator.cs @@ -32,9 +32,7 @@ private static readonly Dictionary DatePartMapping /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqlServerDateOnlyMemberTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerDateOnlyMethodTranslator.cs b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerDateOnlyMethodTranslator.cs index 4642ee27ade..8d638c63f22 100644 --- a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerDateOnlyMethodTranslator.cs +++ b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerDateOnlyMethodTranslator.cs @@ -30,9 +30,7 @@ public class SqlServerDateOnlyMethodTranslator : IMethodCallTranslator /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqlServerDateOnlyMethodTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerDateTimeMemberTranslator.cs b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerDateTimeMemberTranslator.cs index 01fcba5be4e..944b676307f 100644 --- a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerDateTimeMemberTranslator.cs +++ b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerDateTimeMemberTranslator.cs @@ -85,17 +85,18 @@ public class SqlServerDateTimeMemberTranslator( nameof(DateTime.UtcNow) when declaringType == typeof(DateTimeOffset) - => sqlExpressionFactory.Convert(sqlExpressionFactory.Function( - "SYSUTCDATETIME", - arguments: [], - nullable: false, - argumentsPropagateNullability: [], - returnType), returnType), + => sqlExpressionFactory.Convert( + sqlExpressionFactory.Function( + "SYSUTCDATETIME", + arguments: [], + nullable: false, + argumentsPropagateNullability: [], + returnType), returnType), nameof(DateTime.Today) => sqlExpressionFactory.Function( "CONVERT", - new SqlExpression[] + new[] { sqlExpressionFactory.Fragment("date"), sqlExpressionFactory.Function( diff --git a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerFullTextSearchFunctionsTranslator.cs b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerFullTextSearchFunctionsTranslator.cs index 63bb03f90ef..f8bf8db4c7b 100644 --- a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerFullTextSearchFunctionsTranslator.cs +++ b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerFullTextSearchFunctionsTranslator.cs @@ -54,9 +54,7 @@ private static readonly IDictionary FunctionMapping /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqlServerFullTextSearchFunctionsTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerIsDateFunctionTranslator.cs b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerIsDateFunctionTranslator.cs index 05d92721650..7e12f4c0feb 100644 --- a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerIsDateFunctionTranslator.cs +++ b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerIsDateFunctionTranslator.cs @@ -26,9 +26,7 @@ public class SqlServerIsDateFunctionTranslator : IMethodCallTranslator /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqlServerIsDateFunctionTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerIsNumericFunctionTranslator.cs b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerIsNumericFunctionTranslator.cs index 336e1d883ed..474620ea730 100644 --- a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerIsNumericFunctionTranslator.cs +++ b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerIsNumericFunctionTranslator.cs @@ -26,9 +26,7 @@ public class SqlServerIsNumericFunctionTranslator : IMethodCallTranslator /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqlServerIsNumericFunctionTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerLongCountMethodTranslator.cs b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerLongCountMethodTranslator.cs index d38c0c3f1e7..e9926289727 100644 --- a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerLongCountMethodTranslator.cs +++ b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerLongCountMethodTranslator.cs @@ -23,9 +23,7 @@ public class SqlServerLongCountMethodTranslator : IAggregateMethodCallTranslator /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqlServerLongCountMethodTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerMathTranslator.cs b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerMathTranslator.cs index a1d84af1098..4df28709ffe 100644 --- a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerMathTranslator.cs +++ b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerMathTranslator.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.EntityFrameworkCore.Query.SqlExpressions; -using Microsoft.EntityFrameworkCore.SqlServer.Infrastructure.Internal; -using Microsoft.EntityFrameworkCore.SqlServer.Internal; using ExpressionExtensions = Microsoft.EntityFrameworkCore.Query.ExpressionExtensions; // ReSharper disable once CheckNamespace @@ -99,9 +97,7 @@ public class SqlServerMathTranslator : IMethodCallTranslator /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqlServerMathTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerNewGuidTranslator.cs b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerNewGuidTranslator.cs index f21fc49c50f..ecead0e611c 100644 --- a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerNewGuidTranslator.cs +++ b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerNewGuidTranslator.cs @@ -24,9 +24,7 @@ public class SqlServerNewGuidTranslator : IMethodCallTranslator /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqlServerNewGuidTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerStringMemberTranslator.cs b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerStringMemberTranslator.cs index 47856438036..a5f089fb49d 100644 --- a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerStringMemberTranslator.cs +++ b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerStringMemberTranslator.cs @@ -23,9 +23,7 @@ public class SqlServerStringMemberTranslator : IMemberTranslator /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqlServerStringMemberTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerStringMethodTranslator.cs b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerStringMethodTranslator.cs index f8dd1a44713..c7fa87c684d 100644 --- a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerStringMethodTranslator.cs +++ b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerStringMethodTranslator.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Text; using Microsoft.EntityFrameworkCore.Query.SqlExpressions; using Microsoft.EntityFrameworkCore.SqlServer.Infrastructure.Internal; using ExpressionExtensions = Microsoft.EntityFrameworkCore.Query.ExpressionExtensions; @@ -202,8 +201,10 @@ public SqlServerStringMethodTranslator(ISqlExpressionFactory sqlExpressionFactor // an overload that accepts the characters to trim. if (method == TrimStartMethodInfoWithoutArgs || (method == TrimStartMethodInfoWithCharArrayArg && arguments[0] is SqlConstantExpression { Value: char[] { Length: 0 } }) - || (((_sqlServerSingletonOptions.EngineType == SqlServerEngineType.SqlServer && _sqlServerSingletonOptions.SqlServerCompatibilityLevel >= 160) - || (_sqlServerSingletonOptions.EngineType == SqlServerEngineType.AzureSql && _sqlServerSingletonOptions.AzureSqlCompatibilityLevel >= 160) + || (((_sqlServerSingletonOptions.EngineType == SqlServerEngineType.SqlServer + && _sqlServerSingletonOptions.SqlServerCompatibilityLevel >= 160) + || (_sqlServerSingletonOptions.EngineType == SqlServerEngineType.AzureSql + && _sqlServerSingletonOptions.AzureSqlCompatibilityLevel >= 160) || (_sqlServerSingletonOptions.EngineType == SqlServerEngineType.AzureSynapse)) && (method == TrimStartMethodInfoWithCharArg || method == TrimStartMethodInfoWithCharArrayArg))) { @@ -212,8 +213,10 @@ public SqlServerStringMethodTranslator(ISqlExpressionFactory sqlExpressionFactor if (method == TrimEndMethodInfoWithoutArgs || (method == TrimEndMethodInfoWithCharArrayArg && arguments[0] is SqlConstantExpression { Value: char[] { Length: 0 } }) - || (((_sqlServerSingletonOptions.EngineType == SqlServerEngineType.SqlServer && _sqlServerSingletonOptions.SqlServerCompatibilityLevel >= 160) - || (_sqlServerSingletonOptions.EngineType == SqlServerEngineType.AzureSql && _sqlServerSingletonOptions.AzureSqlCompatibilityLevel >= 160) + || (((_sqlServerSingletonOptions.EngineType == SqlServerEngineType.SqlServer + && _sqlServerSingletonOptions.SqlServerCompatibilityLevel >= 160) + || (_sqlServerSingletonOptions.EngineType == SqlServerEngineType.AzureSql + && _sqlServerSingletonOptions.AzureSqlCompatibilityLevel >= 160) || (_sqlServerSingletonOptions.EngineType == SqlServerEngineType.AzureSynapse)) && (method == TrimEndMethodInfoWithCharArg || method == TrimEndMethodInfoWithCharArrayArg))) { @@ -364,12 +367,12 @@ private SqlExpression TranslateIndexOf( if (searchExpression is SqlConstantExpression { Value: "" }) { return _sqlExpressionFactory.Case( - [new(_sqlExpressionFactory.IsNotNull(instance), _sqlExpressionFactory.Constant(0))], + [new CaseWhenClause(_sqlExpressionFactory.IsNotNull(instance), _sqlExpressionFactory.Constant(0))], elseResult: null ); } - SqlExpression offsetExpression = searchExpression is SqlConstantExpression + var offsetExpression = searchExpression is SqlConstantExpression ? _sqlExpressionFactory.Constant(1) : _sqlExpressionFactory.Case( new[] @@ -382,7 +385,6 @@ private SqlExpression TranslateIndexOf( }, _sqlExpressionFactory.Constant(1)); - return _sqlExpressionFactory.Subtract(charIndexExpression, offsetExpression); } diff --git a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerTimeOnlyMemberTranslator.cs b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerTimeOnlyMemberTranslator.cs index a2c7c39a17c..7f64828d159 100644 --- a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerTimeOnlyMemberTranslator.cs +++ b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerTimeOnlyMemberTranslator.cs @@ -31,9 +31,7 @@ public class SqlServerTimeOnlyMemberTranslator : IMemberTranslator /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqlServerTimeOnlyMemberTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerTimeOnlyMethodTranslator.cs b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerTimeOnlyMethodTranslator.cs index 53e602d74a5..934d0ada3a5 100644 --- a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerTimeOnlyMethodTranslator.cs +++ b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerTimeOnlyMethodTranslator.cs @@ -39,9 +39,7 @@ public class SqlServerTimeOnlyMethodTranslator : IMethodCallTranslator /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqlServerTimeOnlyMethodTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerTimeSpanMemberTranslator.cs b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerTimeSpanMemberTranslator.cs index 76b17e14b4a..efa15cbbad6 100644 --- a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerTimeSpanMemberTranslator.cs +++ b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerTimeSpanMemberTranslator.cs @@ -31,9 +31,7 @@ public class SqlServerTimeSpanMemberTranslator : IMemberTranslator /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqlServerTimeSpanMemberTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer/SqlServerRetryingExecutionStrategy.cs b/src/EFCore.SqlServer/SqlServerRetryingExecutionStrategy.cs index 25874dcbfc5..11efb993679 100644 --- a/src/EFCore.SqlServer/SqlServerRetryingExecutionStrategy.cs +++ b/src/EFCore.SqlServer/SqlServerRetryingExecutionStrategy.cs @@ -122,9 +122,7 @@ public SqlServerRetryingExecutionStrategy( context, maxRetryCount, maxRetryDelay) - { - _additionalErrorNumbers = errorNumbersToAdd?.ToHashSet(); - } + => _additionalErrorNumbers = errorNumbersToAdd?.ToHashSet(); /// /// Creates a new instance of . @@ -139,9 +137,7 @@ public SqlServerRetryingExecutionStrategy( TimeSpan maxRetryDelay, IEnumerable? errorNumbersToAdd) : base(dependencies, maxRetryCount, maxRetryDelay) - { - _additionalErrorNumbers = errorNumbersToAdd?.ToHashSet(); - } + => _additionalErrorNumbers = errorNumbersToAdd?.ToHashSet(); /// /// Additional SQL error numbers that should be considered transient. diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerByteArrayTypeMapping.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerByteArrayTypeMapping.cs index 961c077bfac..d58981950e8 100644 --- a/src/EFCore.SqlServer/Storage/Internal/SqlServerByteArrayTypeMapping.cs +++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerByteArrayTypeMapping.cs @@ -62,9 +62,7 @@ public SqlServerByteArrayTypeMapping( /// protected SqlServerByteArrayTypeMapping(RelationalTypeMappingParameters parameters, SqlDbType? sqlDbType) : base(parameters) - { - _sqlDbType = sqlDbType; - } + => _sqlDbType = sqlDbType; private static int CalculateSize(int? size) => size is > 0 and < MaxSize ? size.Value : MaxSize; diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerDatabaseCreator.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerDatabaseCreator.cs index 589440790a1..e3f3fcdb838 100644 --- a/src/EFCore.SqlServer/Storage/Internal/SqlServerDatabaseCreator.cs +++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerDatabaseCreator.cs @@ -14,26 +14,19 @@ namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal; /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// -public class SqlServerDatabaseCreator : RelationalDatabaseCreator +/// +/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to +/// the same compatibility standards as public APIs. It may be changed or removed without notice in +/// any release. You should only use it directly in your code with extreme caution and knowing that +/// doing so can result in application failures when updating to a new Entity Framework Core release. +/// +public class SqlServerDatabaseCreator( + RelationalDatabaseCreatorDependencies dependencies, + ISqlServerConnection connection, + IRawSqlCommandBuilder rawSqlCommandBuilder) : RelationalDatabaseCreator(dependencies) { - private readonly ISqlServerConnection _connection; - private readonly IRawSqlCommandBuilder _rawSqlCommandBuilder; - - /// - /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to - /// the same compatibility standards as public APIs. It may be changed or removed without notice in - /// any release. You should only use it directly in your code with extreme caution and knowing that - /// doing so can result in application failures when updating to a new Entity Framework Core release. - /// - public SqlServerDatabaseCreator( - RelationalDatabaseCreatorDependencies dependencies, - ISqlServerConnection connection, - IRawSqlCommandBuilder rawSqlCommandBuilder) - : base(dependencies) - { - _connection = connection; - _rawSqlCommandBuilder = rawSqlCommandBuilder; - } + private readonly ISqlServerConnection _connection = connection; + private readonly IRawSqlCommandBuilder _rawSqlCommandBuilder = rawSqlCommandBuilder; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -62,7 +55,7 @@ public override void Create() using (var masterConnection = _connection.CreateMasterConnection()) { Dependencies.MigrationCommandExecutor - .ExecuteNonQuery(CreateCreateOperations(), masterConnection); + .ExecuteNonQuery(CreateCreateOperations(), masterConnection, new MigrationExecutionState(), commitTransaction: true); ClearPool(); } @@ -82,7 +75,7 @@ public override async Task CreateAsync(CancellationToken cancellationToken = def await using (masterConnection.ConfigureAwait(false)) { await Dependencies.MigrationCommandExecutor - .ExecuteNonQueryAsync(CreateCreateOperations(), masterConnection, cancellationToken) + .ExecuteNonQueryAsync(CreateCreateOperations(), masterConnection, new MigrationExecutionState(), commitTransaction: true, cancellationToken: cancellationToken) .ConfigureAwait(false); ClearPool(); @@ -157,8 +150,7 @@ private IReadOnlyList CreateCreateOperations() { var builder = new SqlConnectionStringBuilder(_connection.DbConnection.ConnectionString); return Dependencies.MigrationsSqlGenerator.Generate( - new[] - { + [ new SqlServerCreateDatabaseOperation { Name = builder.InitialCatalog, @@ -166,7 +158,7 @@ private IReadOnlyList CreateCreateOperations() Collation = Dependencies.CurrentContext.Context.GetService() .Model.GetRelationalModel().Collation } - }); + ]); } /// @@ -345,7 +337,7 @@ public override void Delete() using var masterConnection = _connection.CreateMasterConnection(); Dependencies.MigrationCommandExecutor - .ExecuteNonQuery(CreateDropCommands(), masterConnection); + .ExecuteNonQuery(CreateDropCommands(), masterConnection, new MigrationExecutionState(), commitTransaction: true); } /// @@ -361,7 +353,7 @@ public override async Task DeleteAsync(CancellationToken cancellationToken = def var masterConnection = _connection.CreateMasterConnection(); await using var _ = masterConnection.ConfigureAwait(false); await Dependencies.MigrationCommandExecutor - .ExecuteNonQueryAsync(CreateDropCommands(), masterConnection, cancellationToken) + .ExecuteNonQueryAsync(CreateDropCommands(), masterConnection, new MigrationExecutionState(), commitTransaction: true, cancellationToken: cancellationToken) .ConfigureAwait(false); } diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerDateTimeTypeMapping.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerDateTimeTypeMapping.cs index 7b7d58f5241..4ae2350fa6c 100644 --- a/src/EFCore.SqlServer/Storage/Internal/SqlServerDateTimeTypeMapping.cs +++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerDateTimeTypeMapping.cs @@ -72,9 +72,7 @@ public SqlServerDateTimeTypeMapping( /// protected SqlServerDateTimeTypeMapping(RelationalTypeMappingParameters parameters, SqlDbType? sqlDbType) : base(parameters) - { - _sqlDbType = sqlDbType; - } + => _sqlDbType = sqlDbType; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerDecimalTypeMapping.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerDecimalTypeMapping.cs index 1ac62cfe7c0..2d271222033 100644 --- a/src/EFCore.SqlServer/Storage/Internal/SqlServerDecimalTypeMapping.cs +++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerDecimalTypeMapping.cs @@ -56,9 +56,7 @@ public SqlServerDecimalTypeMapping( /// protected SqlServerDecimalTypeMapping(RelationalTypeMappingParameters parameters, SqlDbType? sqlDbType) : base(parameters) - { - _sqlDbType = sqlDbType; - } + => _sqlDbType = sqlDbType; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerExecutionStrategy.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerExecutionStrategy.cs index 662964e61ab..cfce6dd4a37 100644 --- a/src/EFCore.SqlServer/Storage/Internal/SqlServerExecutionStrategy.cs +++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerExecutionStrategy.cs @@ -20,9 +20,7 @@ public class SqlServerExecutionStrategy : IExecutionStrategy /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqlServerExecutionStrategy(ExecutionStrategyDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerJsonTypeMapping.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerOwnedJsonTypeMapping.cs similarity index 65% rename from src/EFCore.SqlServer/Storage/Internal/SqlServerJsonTypeMapping.cs rename to src/EFCore.SqlServer/Storage/Internal/SqlServerOwnedJsonTypeMapping.cs index 8f6e7923d3a..6bd4cfeffb0 100644 --- a/src/EFCore.SqlServer/Storage/Internal/SqlServerJsonTypeMapping.cs +++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerOwnedJsonTypeMapping.cs @@ -1,8 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Data; using System.Text; using System.Text.Json; +using Microsoft.Data.SqlClient; namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal; @@ -12,19 +14,21 @@ namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal; /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// -public class SqlServerJsonTypeMapping : JsonTypeMapping +public class SqlServerOwnedJsonTypeMapping : JsonTypeMapping { + private static readonly MethodInfo CreateUtf8StreamMethod + = typeof(SqlServerOwnedJsonTypeMapping).GetMethod(nameof(CreateUtf8Stream), [typeof(string)])!; + private static readonly MethodInfo GetStringMethod = typeof(DbDataReader).GetRuntimeMethod(nameof(DbDataReader.GetString), [typeof(int)])!; - private static readonly PropertyInfo UTF8Property - = typeof(Encoding).GetProperty(nameof(Encoding.UTF8))!; - - private static readonly MethodInfo EncodingGetBytesMethod - = typeof(Encoding).GetMethod(nameof(Encoding.GetBytes), [typeof(string)])!; - - private static readonly ConstructorInfo MemoryStreamConstructor - = typeof(MemoryStream).GetConstructor([typeof(byte[])])!; + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + public static SqlServerOwnedJsonTypeMapping Default { get; } = new("nvarchar(max)"); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -32,7 +36,7 @@ private static readonly ConstructorInfo MemoryStreamConstructor /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public static SqlServerJsonTypeMapping Default { get; } = new("nvarchar(max)"); + public static SqlServerOwnedJsonTypeMapping OwnedJsonTypeDefault { get; } = new("json"); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -40,7 +44,7 @@ private static readonly ConstructorInfo MemoryStreamConstructor /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public SqlServerJsonTypeMapping(string storeType) + public SqlServerOwnedJsonTypeMapping(string storeType) : base(storeType, typeof(JsonElement), System.Data.DbType.String) { } @@ -54,6 +58,17 @@ public SqlServerJsonTypeMapping(string storeType) public override MethodInfo GetDataReaderMethod() => GetStringMethod; + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + public static MemoryStream CreateUtf8Stream(string json) + => json == "" + ? throw new InvalidOperationException(RelationalStrings.JsonEmptyString) + : new MemoryStream(Encoding.UTF8.GetBytes(json)); + /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in @@ -61,12 +76,7 @@ public override MethodInfo GetDataReaderMethod() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public override Expression CustomizeDataReaderExpression(Expression expression) - => Expression.New( - MemoryStreamConstructor, - Expression.Call( - Expression.Property(null, UTF8Property), - EncodingGetBytesMethod, - expression)); + => Expression.Call(CreateUtf8StreamMethod, expression); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -74,7 +84,7 @@ public override Expression CustomizeDataReaderExpression(Expression expression) /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - protected SqlServerJsonTypeMapping(RelationalTypeMappingParameters parameters) + protected SqlServerOwnedJsonTypeMapping(RelationalTypeMappingParameters parameters) : base(parameters) { } @@ -104,5 +114,23 @@ protected override string GenerateNonNullSqlLiteral(object value) /// doing so can result in application failures when updating to a new Entity Framework Core release. /// protected override RelationalTypeMapping Clone(RelationalTypeMappingParameters parameters) - => new SqlServerJsonTypeMapping(parameters); + => new SqlServerOwnedJsonTypeMapping(parameters); + + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + protected override void ConfigureParameter(DbParameter parameter) + { + if (StoreType == "json" + && parameter is SqlParameter sqlParameter) // To avoid crashing wrapping providers + { + // TODO:SQLJSON Issue #34414 + sqlParameter.SqlDbType = ((SqlDbType)35); + } + + base.ConfigureParameter(parameter); + } } diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerStringTypeMapping.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerStringTypeMapping.cs index 7d3d6f724e0..89eb2779f4f 100644 --- a/src/EFCore.SqlServer/Storage/Internal/SqlServerStringTypeMapping.cs +++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerStringTypeMapping.cs @@ -34,6 +34,24 @@ public class SqlServerStringTypeMapping : StringTypeMapping /// public static new SqlServerStringTypeMapping Default { get; } = new(); + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + // TODO:SQLJSON Issue #34414 + public static SqlServerStringTypeMapping JsonTypeDefault { get; } = new("json", sqlDbType: (SqlDbType)35); + + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + public static SqlServerStringTypeMapping UnicodeDefault { get; } = new( + "nvarchar(max)", unicode: true, storeTypePostfix: StoreTypePostfix.None); + /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in @@ -68,7 +86,9 @@ public SqlServerStringTypeMapping( private static string GetDefaultStoreName(bool unicode, bool fixedLength) => unicode ? fixedLength ? "nchar" : "nvarchar" - : fixedLength ? "char" : "varchar"; + : fixedLength + ? "char" + : "varchar"; private static DbType? GetDbType(bool unicode, bool fixedLength) => unicode @@ -138,10 +158,14 @@ protected override void ConfigureParameter(DbParameter parameter) var value = parameter.Value; var length = (value as string)?.Length; - if (_sqlDbType.HasValue + // TODO:SQLJSON Issue #34414 + var sqlDbType = _sqlDbType + ?? (StoreType == "json" ? (SqlDbType)35 : null); + + if (sqlDbType.HasValue && parameter is SqlParameter sqlParameter) // To avoid crashing wrapping providers { - sqlParameter.SqlDbType = _sqlDbType.Value; + sqlParameter.SqlDbType = sqlDbType.Value; } if ((value == null diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerTransactionFactory.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerTransactionFactory.cs index 3c365298f2c..8f0f4ba4efb 100644 --- a/src/EFCore.SqlServer/Storage/Internal/SqlServerTransactionFactory.cs +++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerTransactionFactory.cs @@ -16,9 +16,7 @@ public class SqlServerTransactionFactory : IRelationalTransactionFactory /// /// Parameter object containing dependencies for this service. public SqlServerTransactionFactory(RelationalTransactionFactoryDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Relational provider-specific dependencies for this service. diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerTransientExceptionDetector.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerTransientExceptionDetector.cs index 6b11941e6b3..4790998937d 100644 --- a/src/EFCore.SqlServer/Storage/Internal/SqlServerTransientExceptionDetector.cs +++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerTransientExceptionDetector.cs @@ -680,6 +680,7 @@ public static bool ShouldRetryOn(Exception? ex) { return true; } + continue; // SQL Error Code: 121 // The semaphore timeout period has expired diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerTypeMappingSource.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerTypeMappingSource.cs index be70a79a7af..50d50413c28 100644 --- a/src/EFCore.SqlServer/Storage/Internal/SqlServerTypeMappingSource.cs +++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerTypeMappingSource.cs @@ -141,8 +141,7 @@ static SqlServerTypeMappingSource() { typeof(float), SqlServerFloatTypeMapping.Default }, { typeof(decimal), SqlServerDecimalTypeMapping.Default }, { typeof(TimeOnly), SqlServerTimeOnlyTypeMapping.Default }, - { typeof(TimeSpan), SqlServerTimeSpanTypeMapping.Default }, - { typeof(JsonElement), SqlServerJsonTypeMapping.Default } + { typeof(TimeSpan), SqlServerTimeSpanTypeMapping.Default } }; _clrNoFacetTypeMappings @@ -180,6 +179,7 @@ static SqlServerTypeMappingSource() { "float", [SqlServerDoubleTypeMapping.Default] }, { "image", [ImageBinary] }, { "int", [IntTypeMapping.Default] }, + { "json", [SqlServerStringTypeMapping.JsonTypeDefault] }, { "money", [Money] }, { "national char varying", [VariableLengthUnicodeString] }, { "national char varying(max)", [VariableLengthMaxUnicodeString] }, @@ -239,6 +239,13 @@ public SqlServerTypeMappingSource( var clrType = mappingInfo.ClrType; var storeTypeName = mappingInfo.StoreTypeName; + if (clrType == typeof(JsonElement)) + { + return storeTypeName == "json" + ? SqlServerOwnedJsonTypeMapping.OwnedJsonTypeDefault + : SqlServerOwnedJsonTypeMapping.Default; + } + if (storeTypeName != null) { var storeTypeNameBase = mappingInfo.StoreTypeNameBase; @@ -310,6 +317,11 @@ public SqlServerTypeMappingSource( if (clrType == typeof(string)) { + if (storeTypeName == "json") + { + return SqlServerStringTypeMapping.JsonTypeDefault; + } + var isAnsi = mappingInfo.IsUnicode == false; var isFixedLength = mappingInfo.IsFixedLength == true; var maxSize = isAnsi ? 8000 : 4000; diff --git a/src/EFCore.SqlServer/Update/Internal/SqlServerModificationCommand.cs b/src/EFCore.SqlServer/Update/Internal/SqlServerModificationCommand.cs index 7f46d58d144..d4d8ae07587 100644 --- a/src/EFCore.SqlServer/Update/Internal/SqlServerModificationCommand.cs +++ b/src/EFCore.SqlServer/Update/Internal/SqlServerModificationCommand.cs @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal; + namespace Microsoft.EntityFrameworkCore.SqlServer.Update.Internal; /// @@ -32,4 +34,60 @@ public SqlServerModificationCommand(in NonTrackedModificationCommandParameters m : base(modificationCommandParameters) { } + + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + protected override void ProcessSinglePropertyJsonUpdate(ref ColumnModificationParameters parameters) + { + // See: Issue #34432 + var property = parameters.Property!; + var mapping = property.GetRelationalTypeMapping(); + var propertyProviderClrType = (mapping.Converter?.ProviderClrType ?? property.ClrType).UnwrapNullableType(); + var value = parameters.Value; + + // JSON-compatible non-string values (bool, numeric, null) are sent directly as non-string parameters. + if (value is null + || propertyProviderClrType == typeof(bool) + || propertyProviderClrType.IsNumeric()) + { + parameters = parameters with { Value = value, TypeMapping = mapping }; + } + else + { + // Everything else must go as either a string parameter or a json parameter, depending on whether the json type + // is being used or not. To determine this, we get the JSON value and check if it is a string or some other + // type of JSON object. + var jsonValueReaderWriter = mapping.JsonValueReaderWriter; + if (jsonValueReaderWriter != null) + { + var stringValue = jsonValueReaderWriter.ToJsonString(value); + if (!stringValue.StartsWith('\"')) + { + // This is actual JSON, so send with the original type mapping, which may indicate the column type is JSON. + parameters = parameters with { Value = stringValue }; + + return; + } + + // Otherwise remove the quotes and send the value as a string. + value = stringValue[1..^1]; + } + else if (mapping.Converter != null) + { + value = mapping.Converter.ConvertToProvider(value); + } + + parameters = parameters with + { + Value = value, + TypeMapping = parameters.TypeMapping is SqlServerOwnedJsonTypeMapping + ? SqlServerStringTypeMapping.UnicodeDefault + : parameters.TypeMapping + }; + } + } } diff --git a/src/EFCore.SqlServer/ValueGeneration/Internal/SqlServerSequenceValueGeneratorFactory.cs b/src/EFCore.SqlServer/ValueGeneration/Internal/SqlServerSequenceValueGeneratorFactory.cs index cd993a68906..a77dc154d28 100644 --- a/src/EFCore.SqlServer/ValueGeneration/Internal/SqlServerSequenceValueGeneratorFactory.cs +++ b/src/EFCore.SqlServer/ValueGeneration/Internal/SqlServerSequenceValueGeneratorFactory.cs @@ -24,9 +24,7 @@ public class SqlServerSequenceValueGeneratorFactory : ISqlServerSequenceValueGen /// public SqlServerSequenceValueGeneratorFactory( ISqlServerUpdateSqlGenerator sqlGenerator) - { - _sqlGenerator = sqlGenerator; - } + => _sqlGenerator = sqlGenerator; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer/ValueGeneration/Internal/SqlServerSequenceValueGeneratorState.cs b/src/EFCore.SqlServer/ValueGeneration/Internal/SqlServerSequenceValueGeneratorState.cs index 61b6e678afe..1d3e193adc6 100644 --- a/src/EFCore.SqlServer/ValueGeneration/Internal/SqlServerSequenceValueGeneratorState.cs +++ b/src/EFCore.SqlServer/ValueGeneration/Internal/SqlServerSequenceValueGeneratorState.cs @@ -19,9 +19,7 @@ public class SqlServerSequenceValueGeneratorState : HiLoValueGeneratorState /// public SqlServerSequenceValueGeneratorState(ISequence sequence) : base(sequence.IncrementBy) - { - Sequence = sequence; - } + => Sequence = sequence; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.Core/Diagnostics/Internal/UnexpectedConnectionTypeEventData.cs b/src/EFCore.Sqlite.Core/Diagnostics/Internal/UnexpectedConnectionTypeEventData.cs index 1c1b22ced29..1aa805bd015 100644 --- a/src/EFCore.Sqlite.Core/Diagnostics/Internal/UnexpectedConnectionTypeEventData.cs +++ b/src/EFCore.Sqlite.Core/Diagnostics/Internal/UnexpectedConnectionTypeEventData.cs @@ -20,9 +20,7 @@ public UnexpectedConnectionTypeEventData( Func messageGenerator, Type connectionType) : base(eventDefinition, messageGenerator) - { - ConnectionType = connectionType; - } + => ConnectionType = connectionType; /// /// The connection type. diff --git a/src/EFCore.Sqlite.Core/EFCore.Sqlite.Core.csproj b/src/EFCore.Sqlite.Core/EFCore.Sqlite.Core.csproj index 82672a9741f..b916b92851a 100644 --- a/src/EFCore.Sqlite.Core/EFCore.Sqlite.Core.csproj +++ b/src/EFCore.Sqlite.Core/EFCore.Sqlite.Core.csproj @@ -10,7 +10,7 @@ true $(PackageTags);SQLite true - EF9100 + $(NoWarn);EF9100 @@ -51,7 +51,7 @@ - + diff --git a/src/EFCore.Sqlite.Core/Extensions/SqliteEntityTypeBuilderExtensions.cs b/src/EFCore.Sqlite.Core/Extensions/SqliteEntityTypeBuilderExtensions.cs new file mode 100644 index 00000000000..5ef233470fa --- /dev/null +++ b/src/EFCore.Sqlite.Core/Extensions/SqliteEntityTypeBuilderExtensions.cs @@ -0,0 +1,122 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.EntityFrameworkCore.Sqlite.Metadata.Internal; + +// ReSharper disable once CheckNamespace +namespace Microsoft.EntityFrameworkCore; + +/// +/// Entity type builder extension methods for Sqlite-specific metadata. +/// +/// +/// See Modeling entity types and relationships, and +/// Accessing Sqlite databases with EF Core for more information and examples. +/// +public static class SqliteEntityTypeBuilderExtensions +{ + /// + /// Sets a value indicating whether to use the SQL RETURNING clause when saving changes to the table. + /// The RETURNING clause is incompatible with certain Sqlite features, such as virtual tables or tables with AFTER triggers. + /// + /// + /// See Modeling entity types and relationships for more information and examples. + /// + /// The builder for the entity type being configured. + /// The value to set. + /// Indicates whether the configuration was specified using a data annotation. + /// + /// The same builder instance if the configuration was applied, + /// otherwise. + /// + public static IConventionEntityTypeBuilder? UseSqlReturningClause( + this IConventionEntityTypeBuilder entityTypeBuilder, + bool? useSqlReturningClause, + bool fromDataAnnotation = false) + { + if (!entityTypeBuilder.CanUseSqlReturningClause(useSqlReturningClause, fromDataAnnotation)) + { + return null; + } + + entityTypeBuilder.Metadata.UseSqlReturningClause(useSqlReturningClause, fromDataAnnotation); + return entityTypeBuilder; + } + + /// + /// Sets a value indicating whether to use the SQL RETURNING clause when saving changes to the table. + /// The RETURNING clause is incompatible with certain Sqlite features, such as virtual tables or tables with AFTER triggers. + /// + /// + /// See Modeling entity types and relationships for more information and examples. + /// + /// The builder for the entity type being configured. + /// The value to set. + /// The identifier of the table-like store object. + /// Indicates whether the configuration was specified using a data annotation. + /// + /// The same builder instance if the configuration was applied, + /// otherwise. + /// + public static IConventionEntityTypeBuilder? UseSqlReturningClause( + this IConventionEntityTypeBuilder entityTypeBuilder, + bool? useSqlReturningClause, + in StoreObjectIdentifier storeObject, + bool fromDataAnnotation = false) + { + if (!entityTypeBuilder.CanUseSqlReturningClause(useSqlReturningClause, storeObject, fromDataAnnotation)) + { + return null; + } + + entityTypeBuilder.Metadata.UseSqlReturningClause(useSqlReturningClause, storeObject, fromDataAnnotation); + return entityTypeBuilder; + } + + /// + /// Returns a value indicating whether this entity type can be configured to use the SQL RETURNING clause + /// using the specified configuration source. + /// + /// + /// See Modeling entity types and relationships for more information and examples. + /// + /// The builder for the entity type being configured. + /// The value to set. + /// Indicates whether the configuration was specified using a data annotation. + /// if the configuration can be applied. + public static bool CanUseSqlReturningClause( + this IConventionEntityTypeBuilder entityTypeBuilder, + bool? useSqlReturningClause, + bool fromDataAnnotation = false) + => entityTypeBuilder.CanSetAnnotation( + SqliteAnnotationNames.UseSqlReturningClause, + useSqlReturningClause, + fromDataAnnotation); + + /// + /// Returns a value indicating whether this entity type can be configured to use the SQL RETURNING clause + /// using the specified configuration source. + /// + /// + /// See Modeling entity types and relationships for more information and examples. + /// + /// The builder for the entity type being configured. + /// The value to set. + /// The identifier of the table-like store object. + /// Indicates whether the configuration was specified using a data annotation. + /// if the configuration can be applied. + public static bool CanUseSqlReturningClause( + this IConventionEntityTypeBuilder entityTypeBuilder, + bool? useSqlReturningClause, + in StoreObjectIdentifier storeObject, + bool fromDataAnnotation = false) + => StoreObjectIdentifier.Create(entityTypeBuilder.Metadata, storeObject.StoreObjectType) == storeObject + ? entityTypeBuilder.CanSetAnnotation( + SqliteAnnotationNames.UseSqlReturningClause, + useSqlReturningClause, + fromDataAnnotation) + : entityTypeBuilder.Metadata.GetOrCreateMappingFragment(storeObject, fromDataAnnotation).Builder.CanSetAnnotation( + SqliteAnnotationNames.UseSqlReturningClause, + useSqlReturningClause, + fromDataAnnotation); +} diff --git a/src/EFCore.Sqlite.Core/Extensions/SqliteEntityTypeExtensions.cs b/src/EFCore.Sqlite.Core/Extensions/SqliteEntityTypeExtensions.cs index 02d732c030f..80df120bf80 100644 --- a/src/EFCore.Sqlite.Core/Extensions/SqliteEntityTypeExtensions.cs +++ b/src/EFCore.Sqlite.Core/Extensions/SqliteEntityTypeExtensions.cs @@ -77,6 +77,19 @@ public static void UseSqlReturningClause(this IMutableEntityType entityType, boo public static ConfigurationSource? GetUseSqlReturningClauseConfigurationSource(this IConventionEntityType entityType) => entityType.FindAnnotation(SqliteAnnotationNames.UseSqlReturningClause)?.GetConfigurationSource(); + /// + /// Gets the configuration source for whether to use the SQL RETURNING clause when saving changes to the table. + /// + /// The entity type. + /// The identifier of the table-like store object. + /// The configuration source for the memory-optimized setting. + public static ConfigurationSource? GetUseSqlReturningClauseConfigurationSource( + this IConventionEntityType entityType, + in StoreObjectIdentifier storeObject) + => StoreObjectIdentifier.Create(entityType, storeObject.StoreObjectType) == storeObject + ? entityType.GetUseSqlReturningClauseConfigurationSource() + : (entityType.FindMappingFragment(storeObject)?.GetUseSqlReturningClauseConfigurationSource()); + /// /// Returns a value indicating whether to use the SQL RETURNING clause when saving changes to the table. /// The RETURNING clause is incompatible with certain Sqlite features, such as virtual tables or tables with AFTER triggers. diff --git a/src/EFCore.Sqlite.Core/Extensions/SqliteEntityTypeMappingFragmentExtensions.cs b/src/EFCore.Sqlite.Core/Extensions/SqliteEntityTypeMappingFragmentExtensions.cs index 2d2ee626bd2..60a59cb8c11 100644 --- a/src/EFCore.Sqlite.Core/Extensions/SqliteEntityTypeMappingFragmentExtensions.cs +++ b/src/EFCore.Sqlite.Core/Extensions/SqliteEntityTypeMappingFragmentExtensions.cs @@ -27,7 +27,7 @@ public static bool IsSqlReturningClauseUsed(this IReadOnlyEntityTypeMappingFragm /// The entity type mapping fragment. /// The value to set. public static void UseSqlReturningClause(this IMutableEntityTypeMappingFragment fragment, bool? useSqlReturningClause) - => fragment.SetAnnotation(SqliteAnnotationNames.UseSqlReturningClause, useSqlReturningClause); + => fragment.SetOrRemoveAnnotation(SqliteAnnotationNames.UseSqlReturningClause, useSqlReturningClause); /// /// Sets a value indicating whether to use the SQL RETURNING clause when saving changes to the table. @@ -41,7 +41,8 @@ public static void UseSqlReturningClause(this IMutableEntityTypeMappingFragment this IConventionEntityTypeMappingFragment fragment, bool? useSqlReturningClause, bool fromDataAnnotation = false) - => (bool?)fragment.SetAnnotation(SqliteAnnotationNames.UseSqlReturningClause, useSqlReturningClause, fromDataAnnotation)?.Value; + => (bool?)fragment.SetOrRemoveAnnotation(SqliteAnnotationNames.UseSqlReturningClause, useSqlReturningClause, fromDataAnnotation) + ?.Value; /// /// Gets the configuration source for whether to use the SQL RETURNING clause when saving changes to the associated table. diff --git a/src/EFCore.Sqlite.Core/Infrastructure/Internal/SqliteOptionsExtension.cs b/src/EFCore.Sqlite.Core/Infrastructure/Internal/SqliteOptionsExtension.cs index c9f3fbe0a0b..ece0d98105f 100644 --- a/src/EFCore.Sqlite.Core/Infrastructure/Internal/SqliteOptionsExtension.cs +++ b/src/EFCore.Sqlite.Core/Infrastructure/Internal/SqliteOptionsExtension.cs @@ -36,9 +36,7 @@ public SqliteOptionsExtension() /// protected SqliteOptionsExtension(SqliteOptionsExtension copyFrom) : base(copyFrom) - { - _loadSpatialite = copyFrom._loadSpatialite; - } + => _loadSpatialite = copyFrom._loadSpatialite; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.Core/Migrations/Internal/SqliteHistoryRepository.cs b/src/EFCore.Sqlite.Core/Migrations/Internal/SqliteHistoryRepository.cs index 477a43a65eb..89d8fefc0c8 100644 --- a/src/EFCore.Sqlite.Core/Migrations/Internal/SqliteHistoryRepository.cs +++ b/src/EFCore.Sqlite.Core/Migrations/Internal/SqliteHistoryRepository.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Text; using Microsoft.EntityFrameworkCore.Sqlite.Internal; namespace Microsoft.EntityFrameworkCore.Sqlite.Migrations.Internal; @@ -33,7 +32,8 @@ public SqliteHistoryRepository(HistoryRepositoryDependencies dependencies) /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - protected override string ExistsSql => CreateExistsSql(TableName); + protected override string ExistsSql + => CreateExistsSql(TableName); /// /// The name of the table that will serve as a database-wide lock for migrations. @@ -103,17 +103,27 @@ public override string GetEndIfScript() /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public override IDisposable GetDatabaseLock(TimeSpan timeout) + public override LockReleaseBehavior LockReleaseBehavior => LockReleaseBehavior.Explicit; + + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + public override IMigrationsDatabaseLock AcquireDatabaseLock() { - if (!InterpretExistsResult(Dependencies.RawSqlCommandBuilder.Build(CreateExistsSql(LockTableName)) - .ExecuteScalar(CreateRelationalCommandParameters()))) + Dependencies.MigrationsLogger.AcquiringMigrationLock(); + + if (!InterpretExistsResult( + Dependencies.RawSqlCommandBuilder.Build(CreateExistsSql(LockTableName)) + .ExecuteScalar(CreateRelationalCommandParameters()))) { CreateLockTableCommand().ExecuteNonQuery(CreateRelationalCommandParameters()); } var retryDelay = _retryDelay; - var startTime = DateTimeOffset.UtcNow; - while (DateTimeOffset.UtcNow - startTime < timeout) + while (true) { var dbLock = CreateMigrationDatabaseLock(); var insertCount = CreateInsertLockCommand(DateTimeOffset.UtcNow) @@ -123,25 +133,12 @@ public override IDisposable GetDatabaseLock(TimeSpan timeout) return dbLock; } - using var reader = CreateGetLockCommand().ExecuteReader(CreateRelationalCommandParameters()); - if (reader.Read()) - { - var timestamp = reader.DbDataReader.GetFieldValue(1); - if (DateTimeOffset.UtcNow - timestamp > timeout) - { - var id = reader.DbDataReader.GetFieldValue(0); - CreateDeleteLockCommand(id).ExecuteNonQuery(CreateRelationalCommandParameters()); - } - } - Thread.Sleep(retryDelay); if (retryDelay < TimeSpan.FromMinutes(1)) { retryDelay = retryDelay.Add(retryDelay); } } - - throw new TimeoutException(); } /// @@ -150,17 +147,21 @@ public override IDisposable GetDatabaseLock(TimeSpan timeout) /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public override async Task GetDatabaseLockAsync(TimeSpan timeout, CancellationToken cancellationToken = default) + public override async Task AcquireDatabaseLockAsync( + CancellationToken cancellationToken = default) { - if (!InterpretExistsResult(await Dependencies.RawSqlCommandBuilder.Build(CreateExistsSql(LockTableName)) - .ExecuteScalarAsync(CreateRelationalCommandParameters(), cancellationToken).ConfigureAwait(false))) + Dependencies.MigrationsLogger.AcquiringMigrationLock(); + + if (!InterpretExistsResult( + await Dependencies.RawSqlCommandBuilder.Build(CreateExistsSql(LockTableName)) + .ExecuteScalarAsync(CreateRelationalCommandParameters(), cancellationToken).ConfigureAwait(false))) { - await CreateLockTableCommand().ExecuteNonQueryAsync(CreateRelationalCommandParameters(), cancellationToken).ConfigureAwait(false); + await CreateLockTableCommand().ExecuteNonQueryAsync(CreateRelationalCommandParameters(), cancellationToken) + .ConfigureAwait(false); } var retryDelay = _retryDelay; - var startTime = DateTimeOffset.UtcNow; - while (DateTimeOffset.UtcNow - startTime < timeout) + while (true) { var dbLock = CreateMigrationDatabaseLock(); var insertCount = await CreateInsertLockCommand(DateTimeOffset.UtcNow) @@ -171,31 +172,17 @@ public override async Task GetDatabaseLockAsync(TimeSpan timeo return dbLock; } - using var reader = await CreateGetLockCommand().ExecuteReaderAsync(CreateRelationalCommandParameters(), cancellationToken) - .ConfigureAwait(false); - if (await reader.ReadAsync(cancellationToken).ConfigureAwait(false)) - { - var timestamp = await reader.DbDataReader.GetFieldValueAsync(1).ConfigureAwait(false); - if (DateTimeOffset.UtcNow - timestamp > timeout) - { - var id = await reader.DbDataReader.GetFieldValueAsync(0).ConfigureAwait(false); - await CreateDeleteLockCommand(id).ExecuteNonQueryAsync(CreateRelationalCommandParameters(), cancellationToken) - .ConfigureAwait(false); - } - } - await Task.Delay(_retryDelay, cancellationToken).ConfigureAwait(true); if (retryDelay < TimeSpan.FromMinutes(1)) { retryDelay = retryDelay.Add(retryDelay); } } - - throw new TimeoutException(); } private IRelationalCommand CreateLockTableCommand() - => Dependencies.RawSqlCommandBuilder.Build($""" + => Dependencies.RawSqlCommandBuilder.Build( + $""" CREATE TABLE IF NOT EXISTS "{LockTableName}" ( "Id" INTEGER NOT NULL CONSTRAINT "PK_{LockTableName}" PRIMARY KEY, "Timestamp" TEXT NOT NULL @@ -206,17 +193,13 @@ private IRelationalCommand CreateInsertLockCommand(DateTimeOffset timestamp) { var timestampLiteral = Dependencies.TypeMappingSource.GetMapping(typeof(DateTimeOffset)).GenerateSqlLiteral(timestamp); - return Dependencies.RawSqlCommandBuilder.Build($""" + return Dependencies.RawSqlCommandBuilder.Build( + $""" INSERT OR IGNORE INTO "{LockTableName}"("Id", "Timestamp") VALUES(1, {timestampLiteral}); SELECT changes(); """); } - private IRelationalCommand CreateGetLockCommand() - => Dependencies.RawSqlCommandBuilder.Build($""" -SELECT "Id", "Timestamp" FROM "{LockTableName}" LIMIT 1; -"""); - private IRelationalCommand CreateDeleteLockCommand(int? id = null) { var sql = $""" @@ -226,12 +209,13 @@ DELETE FROM "{LockTableName}" { sql += $""" WHERE "Id" = {id}"""; } + sql += ";"; return Dependencies.RawSqlCommandBuilder.Build(sql); } private SqliteMigrationDatabaseLock CreateMigrationDatabaseLock() - => new(CreateDeleteLockCommand(), CreateRelationalCommandParameters()); + => new(CreateDeleteLockCommand(), CreateRelationalCommandParameters(), this); private RelationalCommandParameterObject CreateRelationalCommandParameters() => new( diff --git a/src/EFCore.Sqlite.Core/Migrations/Internal/SqliteMigrationDatabaseLock.cs b/src/EFCore.Sqlite.Core/Migrations/Internal/SqliteMigrationDatabaseLock.cs index 997cbcd4710..668d2107eaf 100644 --- a/src/EFCore.Sqlite.Core/Migrations/Internal/SqliteMigrationDatabaseLock.cs +++ b/src/EFCore.Sqlite.Core/Migrations/Internal/SqliteMigrationDatabaseLock.cs @@ -10,11 +10,20 @@ namespace Microsoft.EntityFrameworkCore.Sqlite.Migrations.Internal; /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public class SqliteMigrationDatabaseLock( - IRelationalCommand relationalCommand, + IRelationalCommand releaseLockCommand, RelationalCommandParameterObject relationalCommandParameters, + IHistoryRepository historyRepository, CancellationToken cancellationToken = default) - : IDisposable, IAsyncDisposable + : IMigrationsDatabaseLock { + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + public virtual IHistoryRepository HistoryRepository => historyRepository; + /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in @@ -22,7 +31,7 @@ public class SqliteMigrationDatabaseLock( /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public void Dispose() - => relationalCommand.ExecuteScalar(relationalCommandParameters); + => releaseLockCommand.ExecuteScalar(relationalCommandParameters); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -31,5 +40,5 @@ public void Dispose() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public async ValueTask DisposeAsync() - => await relationalCommand.ExecuteScalarAsync(relationalCommandParameters, cancellationToken).ConfigureAwait(false); + => await releaseLockCommand.ExecuteScalarAsync(relationalCommandParameters, cancellationToken).ConfigureAwait(false); } diff --git a/src/EFCore.Sqlite.Core/Query/Internal/SqlExpressions/JsonEachExpression.cs b/src/EFCore.Sqlite.Core/Query/Internal/SqlExpressions/JsonEachExpression.cs index 6b8c36c7565..3a2eef74f86 100644 --- a/src/EFCore.Sqlite.Core/Query/Internal/SqlExpressions/JsonEachExpression.cs +++ b/src/EFCore.Sqlite.Core/Query/Internal/SqlExpressions/JsonEachExpression.cs @@ -52,9 +52,7 @@ public JsonEachExpression( SqlExpression jsonExpression, IReadOnlyList? path = null) : base(alias, "json_each", schema: null, builtIn: true, new[] { jsonExpression }) - { - Path = path; - } + => Path = path; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.Core/Query/Internal/SqliteParameterBasedSqlProcessorFactory.cs b/src/EFCore.Sqlite.Core/Query/Internal/SqliteParameterBasedSqlProcessorFactory.cs index 58fdf8869f2..e8bb5067efa 100644 --- a/src/EFCore.Sqlite.Core/Query/Internal/SqliteParameterBasedSqlProcessorFactory.cs +++ b/src/EFCore.Sqlite.Core/Query/Internal/SqliteParameterBasedSqlProcessorFactory.cs @@ -20,9 +20,7 @@ public class SqliteParameterBasedSqlProcessorFactory : IRelationalParameterBased /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqliteParameterBasedSqlProcessorFactory(RelationalParameterBasedSqlProcessorDependencies dependencies) - { - _dependencies = dependencies; - } + => _dependencies = dependencies; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.Core/Query/Internal/SqliteQueryCompilationContext.cs b/src/EFCore.Sqlite.Core/Query/Internal/SqliteQueryCompilationContext.cs index 587e8af2bee..b3691691414 100644 --- a/src/EFCore.Sqlite.Core/Query/Internal/SqliteQueryCompilationContext.cs +++ b/src/EFCore.Sqlite.Core/Query/Internal/SqliteQueryCompilationContext.cs @@ -45,5 +45,6 @@ public SqliteQueryCompilationContext( } /// - public override bool SupportsPrecompiledQuery => true; + public override bool SupportsPrecompiledQuery + => true; } diff --git a/src/EFCore.Sqlite.Core/Query/Internal/SqliteQuerySqlGeneratorFactory.cs b/src/EFCore.Sqlite.Core/Query/Internal/SqliteQuerySqlGeneratorFactory.cs index df978876c75..34ca15770ec 100644 --- a/src/EFCore.Sqlite.Core/Query/Internal/SqliteQuerySqlGeneratorFactory.cs +++ b/src/EFCore.Sqlite.Core/Query/Internal/SqliteQuerySqlGeneratorFactory.cs @@ -18,9 +18,7 @@ public class SqliteQuerySqlGeneratorFactory : IQuerySqlGeneratorFactory /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqliteQuerySqlGeneratorFactory(QuerySqlGeneratorDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Relational provider-specific dependencies for this service. diff --git a/src/EFCore.Sqlite.Core/Query/Internal/SqliteQueryStringFactory.cs b/src/EFCore.Sqlite.Core/Query/Internal/SqliteQueryStringFactory.cs index 6619cd14e4b..3e1da0f579d 100644 --- a/src/EFCore.Sqlite.Core/Query/Internal/SqliteQueryStringFactory.cs +++ b/src/EFCore.Sqlite.Core/Query/Internal/SqliteQueryStringFactory.cs @@ -22,9 +22,7 @@ public class SqliteQueryStringFactory : IRelationalQueryStringFactory /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqliteQueryStringFactory(IRelationalTypeMappingSource typeMapper) - { - _typeMapper = typeMapper; - } + => _typeMapper = typeMapper; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.Core/Query/Internal/SqliteQueryableMethodTranslatingExpressionVisitor.cs b/src/EFCore.Sqlite.Core/Query/Internal/SqliteQueryableMethodTranslatingExpressionVisitor.cs index bfbe7c930ad..4e3f724e46e 100644 --- a/src/EFCore.Sqlite.Core/Query/Internal/SqliteQueryableMethodTranslatingExpressionVisitor.cs +++ b/src/EFCore.Sqlite.Core/Query/Internal/SqliteQueryableMethodTranslatingExpressionVisitor.cs @@ -261,7 +261,11 @@ protected override QueryableMethodTranslatingExpressionVisitor CreateSubqueryVis elementClrType.UnwrapNullableType(), elementTypeMapping, isElementNullable ?? elementClrType.IsNullableType()), - identifier: [(new ColumnExpression(JsonEachKeyColumnName, tableAlias, typeof(int), keyColumnTypeMapping, nullable: false), keyColumnTypeMapping.Comparer)], + identifier: + [ + (new ColumnExpression(JsonEachKeyColumnName, tableAlias, typeof(int), keyColumnTypeMapping, nullable: false), + keyColumnTypeMapping.Comparer) + ], _sqlAliasManager); #pragma warning restore EF1001 // Internal EF Core API usage. diff --git a/src/EFCore.Sqlite.Core/Query/Internal/SqliteSqlExpressionFactory.cs b/src/EFCore.Sqlite.Core/Query/Internal/SqliteSqlExpressionFactory.cs index e70c4289e0e..bd837879247 100644 --- a/src/EFCore.Sqlite.Core/Query/Internal/SqliteSqlExpressionFactory.cs +++ b/src/EFCore.Sqlite.Core/Query/Internal/SqliteSqlExpressionFactory.cs @@ -25,9 +25,7 @@ public class SqliteSqlExpressionFactory : SqlExpressionFactory /// public SqliteSqlExpressionFactory(SqlExpressionFactoryDependencies dependencies) : base(dependencies) - { - _boolTypeMapping = dependencies.TypeMappingSource.FindMapping(typeof(bool), dependencies.Model)!; - } + => _boolTypeMapping = dependencies.TypeMappingSource.FindMapping(typeof(bool), dependencies.Model)!; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.Core/Query/Internal/SqliteSqlNullabilityProcessor.cs b/src/EFCore.Sqlite.Core/Query/Internal/SqliteSqlNullabilityProcessor.cs index 653b963d70d..9a0cd639c3b 100644 --- a/src/EFCore.Sqlite.Core/Query/Internal/SqliteSqlNullabilityProcessor.cs +++ b/src/EFCore.Sqlite.Core/Query/Internal/SqliteSqlNullabilityProcessor.cs @@ -84,7 +84,7 @@ protected virtual SqlExpression VisitRegexp( return regexpExpression.Update(match, pattern); } - /// + /// protected override SqlExpression VisitSqlFunction( SqlFunctionExpression sqlFunctionExpression, bool allowOptimizedExpansion, diff --git a/src/EFCore.Sqlite.Core/Query/Internal/SqliteSqlTranslatingExpressionVisitorFactory.cs b/src/EFCore.Sqlite.Core/Query/Internal/SqliteSqlTranslatingExpressionVisitorFactory.cs index a7a61226553..72f6afb6dba 100644 --- a/src/EFCore.Sqlite.Core/Query/Internal/SqliteSqlTranslatingExpressionVisitorFactory.cs +++ b/src/EFCore.Sqlite.Core/Query/Internal/SqliteSqlTranslatingExpressionVisitorFactory.cs @@ -19,9 +19,7 @@ public class SqliteSqlTranslatingExpressionVisitorFactory : IRelationalSqlTransl /// public SqliteSqlTranslatingExpressionVisitorFactory( RelationalSqlTranslatingExpressionVisitorDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Relational provider-specific dependencies for this service. diff --git a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteByteArrayMethodTranslator.cs b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteByteArrayMethodTranslator.cs index d4e67d23a7c..195726644e3 100644 --- a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteByteArrayMethodTranslator.cs +++ b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteByteArrayMethodTranslator.cs @@ -23,9 +23,7 @@ public class SqliteByteArrayMethodTranslator : IMethodCallTranslator /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqliteByteArrayMethodTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteCharMethodTranslator.cs b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteCharMethodTranslator.cs index 8982e24e662..4e75f3de527 100644 --- a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteCharMethodTranslator.cs +++ b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteCharMethodTranslator.cs @@ -29,9 +29,7 @@ public class SqliteCharMethodTranslator : IMethodCallTranslator /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqliteCharMethodTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteDateOnlyMemberTranslator.cs b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteDateOnlyMemberTranslator.cs index f1e4a7d7451..7f04454c387 100644 --- a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteDateOnlyMemberTranslator.cs +++ b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteDateOnlyMemberTranslator.cs @@ -33,9 +33,7 @@ private static readonly Dictionary DatePartMapping /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqliteDateOnlyMemberTranslator(SqliteSqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteDateOnlyMethodTranslator.cs b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteDateOnlyMethodTranslator.cs index 48413a49347..3f9aade9abb 100644 --- a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteDateOnlyMethodTranslator.cs +++ b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteDateOnlyMethodTranslator.cs @@ -23,9 +23,7 @@ public class SqliteDateOnlyMethodTranslator : IMethodCallTranslator /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqliteDateOnlyMethodTranslator(SqliteSqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteDateTimeMemberTranslator.cs b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteDateTimeMemberTranslator.cs index 954f1f694e2..1080c6791f9 100644 --- a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteDateTimeMemberTranslator.cs +++ b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteDateTimeMemberTranslator.cs @@ -118,11 +118,11 @@ public class SqliteDateTimeMemberTranslator(SqliteSqlExpressionFactory sqlExpres return sqlExpressionFactory.Function( "rtrim", - new SqlExpression[] + new[] { sqlExpressionFactory.Function( "rtrim", - new SqlExpression[] + new[] { sqlExpressionFactory.Strftime( returnType, diff --git a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteDateTimeMethodTranslator.cs b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteDateTimeMethodTranslator.cs index a547abab5cc..a9b392e0690 100644 --- a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteDateTimeMethodTranslator.cs +++ b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteDateTimeMethodTranslator.cs @@ -87,11 +87,11 @@ private static readonly MethodInfo AddTicks { return sqlExpressionFactory.Function( "rtrim", - new SqlExpression[] + new[] { sqlExpressionFactory.Function( "rtrim", - new SqlExpression[] + new[] { sqlExpressionFactory.Strftime( method.ReturnType, diff --git a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteGlobMethodTranslator.cs b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteGlobMethodTranslator.cs index 0c6d64427f3..c69d1d189f4 100644 --- a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteGlobMethodTranslator.cs +++ b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteGlobMethodTranslator.cs @@ -26,9 +26,7 @@ public class SqliteGlobMethodTranslator : IMethodCallTranslator /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqliteGlobMethodTranslator(SqliteSqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteHexMethodTranslator.cs b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteHexMethodTranslator.cs index 019a57ce1ef..0d617eb2c6f 100644 --- a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteHexMethodTranslator.cs +++ b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteHexMethodTranslator.cs @@ -32,9 +32,7 @@ public class SqliteHexMethodTranslator : IMethodCallTranslator /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqliteHexMethodTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteMathTranslator.cs b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteMathTranslator.cs index 953b46c2abd..c39e58a2961 100644 --- a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteMathTranslator.cs +++ b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteMathTranslator.cs @@ -103,9 +103,7 @@ public class SqliteMathTranslator : IMethodCallTranslator /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqliteMathTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteObjectToStringTranslator.cs b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteObjectToStringTranslator.cs index e55d3d993b4..6e4b24b5b0f 100644 --- a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteObjectToStringTranslator.cs +++ b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteObjectToStringTranslator.cs @@ -46,9 +46,7 @@ public class SqliteObjectToStringTranslator : IMethodCallTranslator /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqliteObjectToStringTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteQueryableAggregateMethodTranslator.cs b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteQueryableAggregateMethodTranslator.cs index 2872a2ccb24..2e5d7a51bd2 100644 --- a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteQueryableAggregateMethodTranslator.cs +++ b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteQueryableAggregateMethodTranslator.cs @@ -24,9 +24,7 @@ public class SqliteQueryableAggregateMethodTranslator : IAggregateMethodCallTran /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqliteQueryableAggregateMethodTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteRandomTranslator.cs b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteRandomTranslator.cs index 2a9e3ce530a..bb230c8fd34 100644 --- a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteRandomTranslator.cs +++ b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteRandomTranslator.cs @@ -26,9 +26,7 @@ private static readonly MethodInfo MethodInfo /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqliteRandomTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -45,7 +43,7 @@ public SqliteRandomTranslator(ISqlExpressionFactory sqlExpressionFactory) => MethodInfo.Equals(method) ? _sqlExpressionFactory.Function( "abs", - new SqlExpression[] + new[] { _sqlExpressionFactory.Divide( _sqlExpressionFactory.Function( diff --git a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteRegexMethodTranslator.cs b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteRegexMethodTranslator.cs index a517bba5d0e..6df83ebe284 100644 --- a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteRegexMethodTranslator.cs +++ b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteRegexMethodTranslator.cs @@ -27,9 +27,7 @@ private static readonly MethodInfo RegexIsMatchMethodInfo /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqliteRegexMethodTranslator(SqliteSqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteStringAggregateMethodTranslator.cs b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteStringAggregateMethodTranslator.cs index 98aaa2518ff..dc6e832fc28 100644 --- a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteStringAggregateMethodTranslator.cs +++ b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteStringAggregateMethodTranslator.cs @@ -29,9 +29,7 @@ private static readonly MethodInfo StringJoinMethod /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqliteStringAggregateMethodTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteStringLengthTranslator.cs b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteStringLengthTranslator.cs index 492a7267233..d4633ece277 100644 --- a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteStringLengthTranslator.cs +++ b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteStringLengthTranslator.cs @@ -23,9 +23,7 @@ public class SqliteStringLengthTranslator : IMemberTranslator /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqliteStringLengthTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteStringMethodTranslator.cs b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteStringMethodTranslator.cs index 709122ef33e..3748af7d46a 100644 --- a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteStringMethodTranslator.cs +++ b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteStringMethodTranslator.cs @@ -87,9 +87,7 @@ private static readonly MethodInfo LastOrDefaultMethodInfoWithoutArgs /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqliteStringMethodTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteSubstrMethodTranslator.cs b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteSubstrMethodTranslator.cs index 02ce44732eb..a9b2883a72b 100644 --- a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteSubstrMethodTranslator.cs +++ b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteSubstrMethodTranslator.cs @@ -30,9 +30,7 @@ public class SqliteSubstrMethodTranslator : IMethodCallTranslator /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqliteSubstrMethodTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.Core/Storage/Internal/SqliteRelationalConnection.cs b/src/EFCore.Sqlite.Core/Storage/Internal/SqliteRelationalConnection.cs index b8f52d90c17..44daa250463 100644 --- a/src/EFCore.Sqlite.Core/Storage/Internal/SqliteRelationalConnection.cs +++ b/src/EFCore.Sqlite.Core/Storage/Internal/SqliteRelationalConnection.cs @@ -159,7 +159,9 @@ private void InitializeDbConnection(DbConnection connection) seed: null, (decimal? sum, decimal? value) => value is null ? sum - : sum is null ? value : sum.Value + value.Value, + : sum is null + ? value + : sum.Value + value.Value, isDeterministic: true); } else diff --git a/src/EFCore.Sqlite.Core/Storage/Json/Internal/SqliteJsonByteArrayReaderWriter.cs b/src/EFCore.Sqlite.Core/Storage/Json/Internal/SqliteJsonByteArrayReaderWriter.cs index 56edacb293f..6a65e3fe2df 100644 --- a/src/EFCore.Sqlite.Core/Storage/Json/Internal/SqliteJsonByteArrayReaderWriter.cs +++ b/src/EFCore.Sqlite.Core/Storage/Json/Internal/SqliteJsonByteArrayReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Text.Json; using Microsoft.EntityFrameworkCore.Storage.Json; @@ -52,5 +51,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, byte[] value) => writer.WriteStringValue(Convert.ToHexString(value)); /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore.Sqlite.Core/Storage/Json/Internal/SqliteJsonDateTimeOffsetReaderWriter.cs b/src/EFCore.Sqlite.Core/Storage/Json/Internal/SqliteJsonDateTimeOffsetReaderWriter.cs index 6d89a713313..3f2bd3c352c 100644 --- a/src/EFCore.Sqlite.Core/Storage/Json/Internal/SqliteJsonDateTimeOffsetReaderWriter.cs +++ b/src/EFCore.Sqlite.Core/Storage/Json/Internal/SqliteJsonDateTimeOffsetReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Text.Encodings.Web; using System.Text.Json; @@ -61,5 +60,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, DateTimeOffset value) JavaScriptEncoder.UnsafeRelaxedJsonEscaping)); /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore.Sqlite.Core/Storage/Json/Internal/SqliteJsonDateTimeReaderWriter.cs b/src/EFCore.Sqlite.Core/Storage/Json/Internal/SqliteJsonDateTimeReaderWriter.cs index 878dec01f70..d26f4152722 100644 --- a/src/EFCore.Sqlite.Core/Storage/Json/Internal/SqliteJsonDateTimeReaderWriter.cs +++ b/src/EFCore.Sqlite.Core/Storage/Json/Internal/SqliteJsonDateTimeReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Text.Json; using Microsoft.EntityFrameworkCore.Storage.Json; @@ -55,5 +54,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, DateTime value) => writer.WriteStringValue(string.Format(CultureInfo.InvariantCulture, DateTimeFormatConst, value)); /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore.Sqlite.Core/Storage/Json/Internal/SqliteJsonDecimalReaderWriter.cs b/src/EFCore.Sqlite.Core/Storage/Json/Internal/SqliteJsonDecimalReaderWriter.cs index bd26949e84e..f8ac04bb107 100644 --- a/src/EFCore.Sqlite.Core/Storage/Json/Internal/SqliteJsonDecimalReaderWriter.cs +++ b/src/EFCore.Sqlite.Core/Storage/Json/Internal/SqliteJsonDecimalReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Text.Json; using Microsoft.EntityFrameworkCore.Storage.Json; @@ -55,5 +54,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, decimal value) => writer.WriteStringValue(string.Format(CultureInfo.InvariantCulture, DecimalFormatConst, value)); /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore.Sqlite.Core/Storage/Json/Internal/SqliteJsonGuidReaderWriter.cs b/src/EFCore.Sqlite.Core/Storage/Json/Internal/SqliteJsonGuidReaderWriter.cs index 5597b30b0a3..d83439fb487 100644 --- a/src/EFCore.Sqlite.Core/Storage/Json/Internal/SqliteJsonGuidReaderWriter.cs +++ b/src/EFCore.Sqlite.Core/Storage/Json/Internal/SqliteJsonGuidReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Text.Json; using Microsoft.EntityFrameworkCore.Storage.Json; @@ -52,5 +51,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, Guid value) => writer.WriteStringValue(value.ToString().ToUpperInvariant()); /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore.Sqlite.Core/Update/Internal/SqliteModificationCommandBatchFactory.cs b/src/EFCore.Sqlite.Core/Update/Internal/SqliteModificationCommandBatchFactory.cs index 95121f87831..d75a8de2a25 100644 --- a/src/EFCore.Sqlite.Core/Update/Internal/SqliteModificationCommandBatchFactory.cs +++ b/src/EFCore.Sqlite.Core/Update/Internal/SqliteModificationCommandBatchFactory.cs @@ -19,9 +19,7 @@ public class SqliteModificationCommandBatchFactory : IModificationCommandBatchFa /// public SqliteModificationCommandBatchFactory( ModificationCommandBatchFactoryDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Relational provider-specific dependencies for this service. diff --git a/src/EFCore.Sqlite.Core/Update/Internal/SqliteUpdateSqlGenerator.cs b/src/EFCore.Sqlite.Core/Update/Internal/SqliteUpdateSqlGenerator.cs index 626a9a0ce68..e8229d61af2 100644 --- a/src/EFCore.Sqlite.Core/Update/Internal/SqliteUpdateSqlGenerator.cs +++ b/src/EFCore.Sqlite.Core/Update/Internal/SqliteUpdateSqlGenerator.cs @@ -25,11 +25,9 @@ public class SqliteUpdateSqlGenerator : UpdateAndSelectSqlGenerator /// public SqliteUpdateSqlGenerator(UpdateSqlGeneratorDependencies dependencies) : base(dependencies) - { - // Support for the RETURNING clause on INSERT/UPDATE/DELETE was added in Sqlite 3.35. - // Detect which version we're using, and fall back to the older INSERT/UPDATE+SELECT behavior on legacy versions. - _isReturningClauseSupported = new Version(new SqliteConnection().ServerVersion) >= new Version(3, 35); - } + // Support for the RETURNING clause on INSERT/UPDATE/DELETE was added in Sqlite 3.35. + // Detect which version we're using, and fall back to the older INSERT/UPDATE+SELECT behavior on legacy versions. + => _isReturningClauseSupported = new Version(new SqliteConnection().ServerVersion) >= new Version(3, 35); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to 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.NTS/Query/Internal/SqliteGeometryCollectionMemberTranslator.cs b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteGeometryCollectionMemberTranslator.cs index aed20ee6df1..56a58cb90ad 100644 --- a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteGeometryCollectionMemberTranslator.cs +++ b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteGeometryCollectionMemberTranslator.cs @@ -26,9 +26,7 @@ private static readonly MemberInfo Count /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqliteGeometryCollectionMemberTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteGeometryCollectionMethodTranslator.cs b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteGeometryCollectionMethodTranslator.cs index ed0fb221f45..0484bf795cd 100644 --- a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteGeometryCollectionMethodTranslator.cs +++ b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteGeometryCollectionMethodTranslator.cs @@ -24,9 +24,7 @@ public class SqliteGeometryCollectionMethodTranslator : IMethodCallTranslator /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqliteGeometryCollectionMethodTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteGeometryMemberTranslator.cs b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteGeometryMemberTranslator.cs index f5465515b17..e9f9db41e6f 100644 --- a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteGeometryMemberTranslator.cs +++ b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteGeometryMemberTranslator.cs @@ -47,9 +47,7 @@ private static readonly MemberInfo OgcGeometryType /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqliteGeometryMemberTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -94,7 +92,7 @@ public SqliteGeometryMemberTranslator(ISqlExpressionFactory sqlExpressionFactory return _sqlExpressionFactory.Case( _sqlExpressionFactory.Function( "rtrim", - new SqlExpression[] + new[] { _sqlExpressionFactory.Function( "GeometryType", @@ -128,7 +126,7 @@ public SqliteGeometryMemberTranslator(ISqlExpressionFactory sqlExpressionFactory return _sqlExpressionFactory.Case( _sqlExpressionFactory.Function( "rtrim", - new SqlExpression[] + new[] { _sqlExpressionFactory.Function( "GeometryType", diff --git a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteGeometryMethodTranslator.cs b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteGeometryMethodTranslator.cs index 6d5d32eb85b..0dbe802c8de 100644 --- a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteGeometryMethodTranslator.cs +++ b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteGeometryMethodTranslator.cs @@ -58,9 +58,7 @@ public class SqliteGeometryMethodTranslator : IMethodCallTranslator /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqliteGeometryMethodTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteLineStringMemberTranslator.cs b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteLineStringMemberTranslator.cs index 0dfa4f6527e..a265ef03c62 100644 --- a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteLineStringMemberTranslator.cs +++ b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteLineStringMemberTranslator.cs @@ -33,9 +33,7 @@ private static readonly IDictionary MemberToFunctionName /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqliteLineStringMemberTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteLineStringMethodTranslator.cs b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteLineStringMethodTranslator.cs index a37192c2f58..517931307e3 100644 --- a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteLineStringMethodTranslator.cs +++ b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteLineStringMethodTranslator.cs @@ -26,9 +26,7 @@ private static readonly MethodInfo GetPointN /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqliteLineStringMethodTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteMultiLineStringMemberTranslator.cs b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteMultiLineStringMemberTranslator.cs index 030c8dde72f..4d89dfe37b7 100644 --- a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteMultiLineStringMemberTranslator.cs +++ b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteMultiLineStringMemberTranslator.cs @@ -26,9 +26,7 @@ private static readonly MemberInfo IsClosed /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqliteMultiLineStringMemberTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteNetTopologySuiteAggregateMethodCallTranslatorPlugin.cs b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteNetTopologySuiteAggregateMethodCallTranslatorPlugin.cs index 36f4742a425..649deb97f34 100644 --- a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteNetTopologySuiteAggregateMethodCallTranslatorPlugin.cs +++ b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteNetTopologySuiteAggregateMethodCallTranslatorPlugin.cs @@ -18,9 +18,7 @@ public class SqliteNetTopologySuiteAggregateMethodCallTranslatorPlugin : IAggreg /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqliteNetTopologySuiteAggregateMethodCallTranslatorPlugin(ISqlExpressionFactory sqlExpressionFactory) - { - Translators = new IAggregateMethodCallTranslator[] { new SqliteNetTopologySuiteAggregateMethodTranslator(sqlExpressionFactory) }; - } + => Translators = new IAggregateMethodCallTranslator[] { new SqliteNetTopologySuiteAggregateMethodTranslator(sqlExpressionFactory) }; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteNetTopologySuiteAggregateMethodTranslator.cs b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteNetTopologySuiteAggregateMethodTranslator.cs index 60a43dec99f..d263b220e41 100644 --- a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteNetTopologySuiteAggregateMethodTranslator.cs +++ b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteNetTopologySuiteAggregateMethodTranslator.cs @@ -38,9 +38,7 @@ private static readonly MethodInfo EnvelopeCombineMethod /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqliteNetTopologySuiteAggregateMethodTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteNetTopologySuiteMemberTranslatorPlugin.cs b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteNetTopologySuiteMemberTranslatorPlugin.cs index 04ebab7f46b..1fd35c70226 100644 --- a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteNetTopologySuiteMemberTranslatorPlugin.cs +++ b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteNetTopologySuiteMemberTranslatorPlugin.cs @@ -19,8 +19,7 @@ public class SqliteNetTopologySuiteMemberTranslatorPlugin : IMemberTranslatorPlu /// public SqliteNetTopologySuiteMemberTranslatorPlugin( ISqlExpressionFactory sqlExpressionFactory) - { - Translators = new IMemberTranslator[] + => Translators = new IMemberTranslator[] { new SqliteGeometryMemberTranslator(sqlExpressionFactory), new SqliteGeometryCollectionMemberTranslator(sqlExpressionFactory), @@ -29,7 +28,6 @@ public SqliteNetTopologySuiteMemberTranslatorPlugin( new SqlitePointMemberTranslator(sqlExpressionFactory), new SqlitePolygonMemberTranslator(sqlExpressionFactory) }; - } /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteNetTopologySuiteMethodCallTranslatorPlugin.cs b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteNetTopologySuiteMethodCallTranslatorPlugin.cs index ba868cb0861..e763a582ddd 100644 --- a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteNetTopologySuiteMethodCallTranslatorPlugin.cs +++ b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteNetTopologySuiteMethodCallTranslatorPlugin.cs @@ -18,15 +18,13 @@ public class SqliteNetTopologySuiteMethodCallTranslatorPlugin : IMethodCallTrans /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqliteNetTopologySuiteMethodCallTranslatorPlugin(ISqlExpressionFactory sqlExpressionFactory) - { - Translators = new IMethodCallTranslator[] + => Translators = new IMethodCallTranslator[] { new SqliteGeometryMethodTranslator(sqlExpressionFactory), new SqliteGeometryCollectionMethodTranslator(sqlExpressionFactory), new SqliteLineStringMethodTranslator(sqlExpressionFactory), new SqlitePolygonMethodTranslator(sqlExpressionFactory) }; - } /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.NTS/Query/Internal/SqlitePointMemberTranslator.cs b/src/EFCore.Sqlite.NTS/Query/Internal/SqlitePointMemberTranslator.cs index 989c0f8a642..fd672d7f989 100644 --- a/src/EFCore.Sqlite.NTS/Query/Internal/SqlitePointMemberTranslator.cs +++ b/src/EFCore.Sqlite.NTS/Query/Internal/SqlitePointMemberTranslator.cs @@ -31,9 +31,7 @@ public class SqlitePointMemberTranslator : IMemberTranslator /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqlitePointMemberTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.NTS/Query/Internal/SqlitePolygonMemberTranslator.cs b/src/EFCore.Sqlite.NTS/Query/Internal/SqlitePolygonMemberTranslator.cs index b49727df557..367523867f6 100644 --- a/src/EFCore.Sqlite.NTS/Query/Internal/SqlitePolygonMemberTranslator.cs +++ b/src/EFCore.Sqlite.NTS/Query/Internal/SqlitePolygonMemberTranslator.cs @@ -30,9 +30,7 @@ private static readonly IDictionary MemberToFunctionName /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqlitePolygonMemberTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.NTS/Query/Internal/SqlitePolygonMethodTranslator.cs b/src/EFCore.Sqlite.NTS/Query/Internal/SqlitePolygonMethodTranslator.cs index 8c0fcdd4a80..6b1548f94a1 100644 --- a/src/EFCore.Sqlite.NTS/Query/Internal/SqlitePolygonMethodTranslator.cs +++ b/src/EFCore.Sqlite.NTS/Query/Internal/SqlitePolygonMethodTranslator.cs @@ -26,9 +26,7 @@ private static readonly MethodInfo GetInteriorRingN /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqlitePolygonMethodTranslator(ISqlExpressionFactory sqlExpressionFactory) - { - _sqlExpressionFactory = sqlExpressionFactory; - } + => _sqlExpressionFactory = sqlExpressionFactory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.NTS/Storage/Internal/SqliteNetTopologySuiteTypeMappingSourcePlugin.cs b/src/EFCore.Sqlite.NTS/Storage/Internal/SqliteNetTopologySuiteTypeMappingSourcePlugin.cs index de1f03e02dc..415b584e058 100644 --- a/src/EFCore.Sqlite.NTS/Storage/Internal/SqliteNetTopologySuiteTypeMappingSourcePlugin.cs +++ b/src/EFCore.Sqlite.NTS/Storage/Internal/SqliteNetTopologySuiteTypeMappingSourcePlugin.cs @@ -58,9 +58,7 @@ public class SqliteNetTopologySuiteTypeMappingSourcePlugin : IRelationalTypeMapp /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqliteNetTopologySuiteTypeMappingSourcePlugin(NtsGeometryServices geometryServices) - { - _geometryServices = geometryServices; - } + => _geometryServices = geometryServices; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Sqlite.NTS/Storage/Json/SqliteJsonGeometryWktReaderWriter.cs b/src/EFCore.Sqlite.NTS/Storage/Json/SqliteJsonGeometryWktReaderWriter.cs index 658124ea586..eb52f0fd768 100644 --- a/src/EFCore.Sqlite.NTS/Storage/Json/SqliteJsonGeometryWktReaderWriter.cs +++ b/src/EFCore.Sqlite.NTS/Storage/Json/SqliteJsonGeometryWktReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Text.Json; using Microsoft.EntityFrameworkCore.Storage.Json; using NetTopologySuite.Geometries; @@ -36,5 +35,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, Geometry value) => writer.WriteStringValue(value.ToText()); /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore.Sqlite/EFCore.Sqlite.csproj b/src/EFCore.Sqlite/EFCore.Sqlite.csproj index 4f245bf6871..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..eb72b2ae76a 100644 --- a/src/EFCore.Tasks/EFCore.Tasks.csproj +++ b/src/EFCore.Tasks/EFCore.Tasks.csproj @@ -10,7 +10,7 @@ true true true - NU5100;NU5128 + $(NoWarn);NU5100;NU5128 true $(MSBuildThisFileDirectory)..\..\rulesets\EFCore.noxmldocs.ruleset @@ -49,16 +49,14 @@ - - - + + - + - diff --git a/src/EFCore.Tasks/Tasks/Internal/MsBuildUtilities.cs b/src/EFCore.Tasks/Tasks/Internal/MsBuildUtilities.cs index 5fbaa229ef1..d329cc74df8 100644 --- a/src/EFCore.Tasks/Tasks/Internal/MsBuildUtilities.cs +++ b/src/EFCore.Tasks/Tasks/Internal/MsBuildUtilities.cs @@ -44,11 +44,15 @@ public static string[] TrimAndExcludeNullOrEmpty(string?[]? strings) .Cast() .ToArray(); - public static bool IsTrue(string? value) => bool.TrueString.Equals(TrimAndGetNullForEmpty(value), StringComparison.OrdinalIgnoreCase); + public static bool IsTrue(string? value) + => bool.TrueString.Equals(TrimAndGetNullForEmpty(value), StringComparison.OrdinalIgnoreCase); - public static bool IsTrueOrEmpty(string? value) => TrimAndGetNullForEmpty(value) == null || IsTrue(value); + public static bool IsTrueOrEmpty(string? value) + => TrimAndGetNullForEmpty(value) == null || IsTrue(value); - public static bool? GetBooleanOrNull(string? value) => bool.TryParse(value, out var result) ? result : null; + public static bool? GetBooleanOrNull(string? value) + => bool.TryParse(value, out var result) ? result : null; - public static string? ToMsBuild(string? value) => value?.Replace(',', ';'); + public static string? ToMsBuild(string? value) + => value?.Replace(',', ';'); } diff --git a/src/EFCore.Tasks/Tasks/Internal/OperationTaskBase.cs b/src/EFCore.Tasks/Tasks/Internal/OperationTaskBase.cs index 4d7610609e3..6849955bdc2 100644 --- a/src/EFCore.Tasks/Tasks/Internal/OperationTaskBase.cs +++ b/src/EFCore.Tasks/Tasks/Internal/OperationTaskBase.cs @@ -5,6 +5,7 @@ using System.Text; using System.Text.Json; using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; using Microsoft.EntityFrameworkCore.Tools; using Microsoft.EntityFrameworkCore.Tools.Properties; @@ -16,7 +17,7 @@ namespace Microsoft.EntityFrameworkCore.Tasks.Internal; /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// -public abstract class OperationTaskBase : Build.Utilities.ToolTask +public abstract class OperationTaskBase : ToolTask { /// /// The assembly to use. @@ -51,12 +52,12 @@ public abstract class OperationTaskBase : Build.Utilities.ToolTask public ITaskItem? DataDir { get; set; } /// - /// The target project. + /// The target project. /// public ITaskItem? Project { get; set; } /// - /// The project directory. + /// The project directory. /// public ITaskItem? ProjectDir { get; set; } @@ -66,7 +67,7 @@ public abstract class OperationTaskBase : Build.Utilities.ToolTask public string? RootNamespace { get; set; } /// - /// The language to use. Defaults to C#. + /// The language to use. Defaults to C#. /// public string? Language { get; set; } @@ -85,9 +86,11 @@ public abstract class OperationTaskBase : Build.Utilities.ToolTask /// protected string Output { get; set; } = null!; - protected override string ToolName => "dotnet"; + protected override string ToolName + => "dotnet"; - protected override string GenerateFullPathToTool() => ToolName; + protected override string GenerateFullPathToTool() + => ToolName; protected override bool ValidateParameters() { @@ -133,7 +136,8 @@ public override bool Execute() return success; } - protected override string? GetWorkingDirectory() => ProjectDir?.ItemSpec; + protected override string? GetWorkingDirectory() + => ProjectDir?.ItemSpec; protected override string GenerateCommandLineCommands() { @@ -184,13 +188,14 @@ protected override string GenerateCommandLineCommands() args.Add(runtimeFrameworkVersion); } - args.Add(Path.Combine( - Path.GetDirectoryName(typeof(OperationTaskBase).Assembly.Location)!, - "..", - "..", - "tools", - "netcoreapp2.0", - "ef.dll")); + args.Add( + Path.Combine( + Path.GetDirectoryName(typeof(OperationTaskBase).Assembly.Location)!, + "..", + "..", + "tools", + "netcoreapp2.0", + "ef.dll")); args.AddRange(AdditionalArguments); args.Add("--assembly"); @@ -289,7 +294,7 @@ protected override void LogEventsFromTextOutput(string singleLine, MessageImport Log.LogMessage(singleLine.Substring(6)); } else if (singleLine.StartsWith("dbug: ", StringComparison.InvariantCulture) - || singleLine.StartsWith("trce: ", StringComparison.InvariantCulture)) + || singleLine.StartsWith("trce: ", StringComparison.InvariantCulture)) { Log.LogMessage(MessageImportance.Low, singleLine.Substring(6)); } diff --git a/src/EFCore.Tasks/Tasks/OptimizeDbContext.cs b/src/EFCore.Tasks/Tasks/OptimizeDbContext.cs index da98cd1e4c7..dbcafa6ad10 100644 --- a/src/EFCore.Tasks/Tasks/OptimizeDbContext.cs +++ b/src/EFCore.Tasks/Tasks/OptimizeDbContext.cs @@ -43,7 +43,7 @@ public class OptimizeDbContext : OperationTaskBase [Output] public ITaskItem[] GeneratedFiles { get; private set; } = null!; - /// + /// public override bool Execute() { try @@ -82,6 +82,8 @@ public override bool Execute() AdditionalArguments.Add("--precompile-queries"); } + AdditionalArguments.Add("--nativeaot"); + AdditionalArguments.Add("--suffix"); AdditionalArguments.Add(".g"); @@ -94,7 +96,7 @@ public override bool Execute() return false; } - GeneratedFiles = Output.Split(new string[] { Environment.NewLine }, StringSplitOptions.None) + GeneratedFiles = Output.Split(new[] { Environment.NewLine }, StringSplitOptions.None) .Select(f => new TaskItem(f)).ToArray(); } catch (Exception e) diff --git a/src/EFCore.Tasks/buildTransitive/Microsoft.EntityFrameworkCore.Tasks.targets b/src/EFCore.Tasks/buildTransitive/Microsoft.EntityFrameworkCore.Tasks.targets index 507ea1d8165..25463696b4c 100644 --- a/src/EFCore.Tasks/buildTransitive/Microsoft.EntityFrameworkCore.Tasks.targets +++ b/src/EFCore.Tasks/buildTransitive/Microsoft.EntityFrameworkCore.Tasks.targets @@ -114,15 +114,14 @@ For Publish: - - - + + + Condition="Exists('$(EFGeneratedSourcesBuildFile)')"> + Condition="Exists('$(EFGeneratedSourcesPublishFile)')"> @@ -185,12 +184,15 @@ For Publish: @(_DebugSymbolsIntermediatePath); $(NonExistentFile); @(CustomAdditionalCompileOutputs)"> + + + + + + - - - 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/ChangeTracking/CollectionEntry.cs b/src/EFCore/ChangeTracking/CollectionEntry.cs index af1e566401d..75b1050c085 100644 --- a/src/EFCore/ChangeTracking/CollectionEntry.cs +++ b/src/EFCore/ChangeTracking/CollectionEntry.cs @@ -36,9 +36,7 @@ public class CollectionEntry : NavigationEntry [EntityFrameworkInternal] public CollectionEntry(InternalEntityEntry internalEntry, string name) : base(internalEntry, name, collection: true) - { - LocalDetectChanges(); - } + => LocalDetectChanges(); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -49,9 +47,7 @@ public CollectionEntry(InternalEntityEntry internalEntry, string name) [EntityFrameworkInternal] public CollectionEntry(InternalEntityEntry internalEntry, INavigationBase navigationBase) : base(internalEntry, navigationBase, collection: true) - { - LocalDetectChanges(); - } + => LocalDetectChanges(); private void LocalDetectChanges() { diff --git a/src/EFCore/ChangeTracking/ComplexPropertyEntry.cs b/src/EFCore/ChangeTracking/ComplexPropertyEntry.cs index bf1e6eee96c..da72eda9d72 100644 --- a/src/EFCore/ChangeTracking/ComplexPropertyEntry.cs +++ b/src/EFCore/ChangeTracking/ComplexPropertyEntry.cs @@ -3,7 +3,6 @@ using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; using Microsoft.EntityFrameworkCore.Internal; -using Microsoft.EntityFrameworkCore.Metadata.Internal; namespace Microsoft.EntityFrameworkCore.ChangeTracking; diff --git a/src/EFCore/ChangeTracking/ComplexPropertyEntry`.cs b/src/EFCore/ChangeTracking/ComplexPropertyEntry`.cs index 3e8f57b49a7..7e21d38fa48 100644 --- a/src/EFCore/ChangeTracking/ComplexPropertyEntry`.cs +++ b/src/EFCore/ChangeTracking/ComplexPropertyEntry`.cs @@ -3,7 +3,6 @@ using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; using Microsoft.EntityFrameworkCore.Internal; -using Microsoft.EntityFrameworkCore.Metadata.Internal; namespace Microsoft.EntityFrameworkCore.ChangeTracking; diff --git a/src/EFCore/ChangeTracking/DetectEntityChangesEventArgs.cs b/src/EFCore/ChangeTracking/DetectEntityChangesEventArgs.cs index c84f1ab7992..8e8283182a4 100644 --- a/src/EFCore/ChangeTracking/DetectEntityChangesEventArgs.cs +++ b/src/EFCore/ChangeTracking/DetectEntityChangesEventArgs.cs @@ -24,9 +24,7 @@ public class DetectEntityChangesEventArgs : DetectChangesEventArgs /// [EntityFrameworkInternal] public DetectEntityChangesEventArgs(InternalEntityEntry internalEntityEntry) - { - _internalEntityEntry = internalEntityEntry; - } + => _internalEntityEntry = internalEntityEntry; /// /// The for the entity. diff --git a/src/EFCore/ChangeTracking/DetectedChangesEventArgs.cs b/src/EFCore/ChangeTracking/DetectedChangesEventArgs.cs index 81019ddec20..997d17dfebb 100644 --- a/src/EFCore/ChangeTracking/DetectedChangesEventArgs.cs +++ b/src/EFCore/ChangeTracking/DetectedChangesEventArgs.cs @@ -19,9 +19,7 @@ public class DetectedChangesEventArgs : EventArgs /// [EntityFrameworkInternal] public DetectedChangesEventArgs(bool changesFound) - { - ChangesFound = changesFound; - } + => ChangesFound = changesFound; /// /// Returns if changes were found, otherwise. diff --git a/src/EFCore/ChangeTracking/DetectedEntityChangesEventArgs.cs b/src/EFCore/ChangeTracking/DetectedEntityChangesEventArgs.cs index 870f94a860c..8d45c6ee6dd 100644 --- a/src/EFCore/ChangeTracking/DetectedEntityChangesEventArgs.cs +++ b/src/EFCore/ChangeTracking/DetectedEntityChangesEventArgs.cs @@ -27,9 +27,7 @@ public DetectedEntityChangesEventArgs( InternalEntityEntry internalEntityEntry, bool changesFound) : base(changesFound) - { - _internalEntityEntry = internalEntityEntry; - } + => _internalEntityEntry = internalEntityEntry; /// /// The for the entity. diff --git a/src/EFCore/ChangeTracking/EntityEntry.cs b/src/EFCore/ChangeTracking/EntityEntry.cs index f01bc20ebff..35a0eceddf6 100644 --- a/src/EFCore/ChangeTracking/EntityEntry.cs +++ b/src/EFCore/ChangeTracking/EntityEntry.cs @@ -44,9 +44,7 @@ public class EntityEntry : IInfrastructure /// [EntityFrameworkInternal] public EntityEntry(InternalEntityEntry internalEntry) - { - InternalEntry = internalEntry; - } + => InternalEntry = internalEntry; /// /// Gets the entity being tracked by this entry. diff --git a/src/EFCore/ChangeTracking/EntityEntryEventArgs.cs b/src/EFCore/ChangeTracking/EntityEntryEventArgs.cs index f696ae826e1..41404ca21dc 100644 --- a/src/EFCore/ChangeTracking/EntityEntryEventArgs.cs +++ b/src/EFCore/ChangeTracking/EntityEntryEventArgs.cs @@ -26,9 +26,7 @@ public class EntityEntryEventArgs : EventArgs [EntityFrameworkInternal] public EntityEntryEventArgs( InternalEntityEntry internalEntityEntry) - { - _internalEntityEntry = internalEntityEntry; - } + => _internalEntityEntry = internalEntityEntry; /// /// The for the entity. diff --git a/src/EFCore/ChangeTracking/EntityEntryGraphNode`.cs b/src/EFCore/ChangeTracking/EntityEntryGraphNode`.cs index 5701f6d7cb5..5758247ee7e 100644 --- a/src/EFCore/ChangeTracking/EntityEntryGraphNode`.cs +++ b/src/EFCore/ChangeTracking/EntityEntryGraphNode`.cs @@ -28,9 +28,7 @@ public EntityEntryGraphNode( InternalEntityEntry? sourceEntry, INavigationBase? inboundNavigation) : base(entry, sourceEntry, inboundNavigation) - { - NodeState = state; - } + => NodeState = state; /// /// Creates a new node in the entity graph. diff --git a/src/EFCore/ChangeTracking/EntityEntry`.cs b/src/EFCore/ChangeTracking/EntityEntry`.cs index b17e4d5aa00..5539b7d631b 100644 --- a/src/EFCore/ChangeTracking/EntityEntry`.cs +++ b/src/EFCore/ChangeTracking/EntityEntry`.cs @@ -3,7 +3,6 @@ using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; using Microsoft.EntityFrameworkCore.Internal; -using Microsoft.EntityFrameworkCore.Metadata.Internal; namespace Microsoft.EntityFrameworkCore.ChangeTracking; diff --git a/src/EFCore/ChangeTracking/EntityTrackedEventArgs.cs b/src/EFCore/ChangeTracking/EntityTrackedEventArgs.cs index 73e86f220c3..2e598ef5190 100644 --- a/src/EFCore/ChangeTracking/EntityTrackedEventArgs.cs +++ b/src/EFCore/ChangeTracking/EntityTrackedEventArgs.cs @@ -24,9 +24,7 @@ public EntityTrackedEventArgs( InternalEntityEntry internalEntityEntry, bool fromQuery) : base(internalEntityEntry) - { - FromQuery = fromQuery; - } + => FromQuery = fromQuery; /// /// if the entity is being tracked as part of a database query; otherwise. diff --git a/src/EFCore/ChangeTracking/Internal/ArrayPropertyValues.cs b/src/EFCore/ChangeTracking/Internal/ArrayPropertyValues.cs index 80e263b4b5b..ddbc7ee4b4b 100644 --- a/src/EFCore/ChangeTracking/Internal/ArrayPropertyValues.cs +++ b/src/EFCore/ChangeTracking/Internal/ArrayPropertyValues.cs @@ -24,9 +24,7 @@ public class ArrayPropertyValues : PropertyValues /// public ArrayPropertyValues(InternalEntityEntry internalEntry, object?[] values) : base(internalEntry) - { - _values = values; - } + => _values = values; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/ChangeTracking/Internal/CompositePrincipalKeyValueFactory.cs b/src/EFCore/ChangeTracking/Internal/CompositePrincipalKeyValueFactory.cs index d6fc8e9e67e..726b2458bcf 100644 --- a/src/EFCore/ChangeTracking/Internal/CompositePrincipalKeyValueFactory.cs +++ b/src/EFCore/ChangeTracking/Internal/CompositePrincipalKeyValueFactory.cs @@ -21,9 +21,7 @@ public class CompositePrincipalKeyValueFactory : CompositeValueFactory, IPrincip /// public CompositePrincipalKeyValueFactory(IKey key) : base(key.Properties) - { - _key = key; - } + => _key = key; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/ChangeTracking/Internal/EntityGraphAttacher.cs b/src/EFCore/ChangeTracking/Internal/EntityGraphAttacher.cs index c09f54bf26f..ba7048a022e 100644 --- a/src/EFCore/ChangeTracking/Internal/EntityGraphAttacher.cs +++ b/src/EFCore/ChangeTracking/Internal/EntityGraphAttacher.cs @@ -22,9 +22,7 @@ public class EntityGraphAttacher : IEntityGraphAttacher /// public EntityGraphAttacher( IEntityEntryGraphIterator graphIterator) - { - _graphIterator = graphIterator; - } + => _graphIterator = graphIterator; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/ChangeTracking/Internal/EntityReferenceMap.cs b/src/EFCore/ChangeTracking/Internal/EntityReferenceMap.cs index a77de1f1f43..26905ffd1c7 100644 --- a/src/EFCore/ChangeTracking/Internal/EntityReferenceMap.cs +++ b/src/EFCore/ChangeTracking/Internal/EntityReferenceMap.cs @@ -28,9 +28,7 @@ public class EntityReferenceMap /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public EntityReferenceMap(bool hasSubMap) - { - _hasSubMap = hasSubMap; - } + => _hasSubMap = hasSubMap; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/ChangeTracking/Internal/EntryCurrentProviderValueComparer.cs b/src/EFCore/ChangeTracking/Internal/EntryCurrentProviderValueComparer.cs index 8459ef53f96..f0d0000a7f8 100644 --- a/src/EFCore/ChangeTracking/Internal/EntryCurrentProviderValueComparer.cs +++ b/src/EFCore/ChangeTracking/Internal/EntryCurrentProviderValueComparer.cs @@ -21,9 +21,7 @@ public class EntryCurrentProviderValueComparer : EntryCurrentValueComparer /// public EntryCurrentProviderValueComparer(IProperty property) : base(property) - { - _converter = property.GetTypeMapping().Converter!; - } + => _converter = property.GetTypeMapping().Converter!; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/ChangeTracking/Internal/IdentityMap.cs b/src/EFCore/ChangeTracking/Internal/IdentityMap.cs index 1c4e6b8d1c1..47ac7750c94 100644 --- a/src/EFCore/ChangeTracking/Internal/IdentityMap.cs +++ b/src/EFCore/ChangeTracking/Internal/IdentityMap.cs @@ -102,7 +102,7 @@ public virtual IEnumerable All() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual InternalEntityEntry? TryGetEntryTyped(TKey keyValue) - => _identityMap.TryGetValue(keyValue, out var entry) ? entry : null; + => _identityMap.GetValueOrDefault(keyValue); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -141,9 +141,7 @@ public virtual IEnumerable All() try { - return _identityMap.TryGetValue((TKey)key, out var entry) - ? entry - : null; + return _identityMap.GetValueOrDefault((TKey)key); } catch (InvalidCastException e) { diff --git a/src/EFCore/ChangeTracking/Internal/KeyPropagator.cs b/src/EFCore/ChangeTracking/Internal/KeyPropagator.cs index 15b9c89231b..4aba01bdca3 100644 --- a/src/EFCore/ChangeTracking/Internal/KeyPropagator.cs +++ b/src/EFCore/ChangeTracking/Internal/KeyPropagator.cs @@ -23,9 +23,7 @@ public class KeyPropagator : IKeyPropagator /// public KeyPropagator( IValueGeneratorSelector valueGeneratorSelector) - { - _valueGeneratorSelector = valueGeneratorSelector; - } + => _valueGeneratorSelector = valueGeneratorSelector; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/ChangeTracking/Internal/KeyValueFactoryFactory.cs b/src/EFCore/ChangeTracking/Internal/KeyValueFactoryFactory.cs index a46717bf392..4b343857dc0 100644 --- a/src/EFCore/ChangeTracking/Internal/KeyValueFactoryFactory.cs +++ b/src/EFCore/ChangeTracking/Internal/KeyValueFactoryFactory.cs @@ -35,16 +35,14 @@ public static IPrincipalKeyValueFactory Create(IKey key) _createSimpleFactoryNullableMethod ??= typeof(KeyValueFactoryFactory).GetMethod(nameof(CreateSimpleNullableFactory))!; var nonNullableKeyType = keyType.UnwrapNullableType(); return (IPrincipalKeyValueFactory)_createSimpleFactoryNullableMethod.MakeGenericMethod( - keyType, nonNullableKeyType == keyType ? typeof(int) : nonNullableKeyType) - .Invoke(null, [key])!; - } - else - { - _createSimpleFactoryNonNullableMethod ??= typeof(KeyValueFactoryFactory) - .GetMethod(nameof(CreateSimpleNonNullableFactory))!; - return (IPrincipalKeyValueFactory)_createSimpleFactoryNonNullableMethod.MakeGenericMethod(keyType) + keyType, nonNullableKeyType == keyType ? typeof(int) : nonNullableKeyType) .Invoke(null, [key])!; } + + _createSimpleFactoryNonNullableMethod ??= typeof(KeyValueFactoryFactory) + .GetMethod(nameof(CreateSimpleNonNullableFactory))!; + return (IPrincipalKeyValueFactory)_createSimpleFactoryNonNullableMethod.MakeGenericMethod(keyType) + .Invoke(null, [key])!; } /// diff --git a/src/EFCore/ChangeTracking/Internal/MultiSnapshot.cs b/src/EFCore/ChangeTracking/Internal/MultiSnapshot.cs index 5b5164c702f..7d2f0b1bc39 100644 --- a/src/EFCore/ChangeTracking/Internal/MultiSnapshot.cs +++ b/src/EFCore/ChangeTracking/Internal/MultiSnapshot.cs @@ -20,9 +20,7 @@ namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal; /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public MultiSnapshot(ISnapshot[] snapshots) - { - _snapshots = snapshots; - } + => _snapshots = snapshots; internal static readonly ConstructorInfo Constructor = typeof(MultiSnapshot).GetDeclaredConstructor([typeof(ISnapshot[])])!; diff --git a/src/EFCore/ChangeTracking/Internal/NavigationFixer.cs b/src/EFCore/ChangeTracking/Internal/NavigationFixer.cs index 86a1ae7a5ff..d9f4a9e171f 100644 --- a/src/EFCore/ChangeTracking/Internal/NavigationFixer.cs +++ b/src/EFCore/ChangeTracking/Internal/NavigationFixer.cs @@ -1102,7 +1102,8 @@ private void FindOrCreateJoinEntry( SetForeignKeyProperties( joinEntry, arguments.OtherEntry, arguments.SkipNavigation.Inverse.ForeignKey, arguments.SetModified, arguments.FromQuery); - SetNavigation(joinEntry, arguments.SkipNavigation.Inverse.ForeignKey.DependentToPrincipal, arguments.OtherEntry, arguments.FromQuery); + SetNavigation( + joinEntry, arguments.SkipNavigation.Inverse.ForeignKey.DependentToPrincipal, arguments.OtherEntry, arguments.FromQuery); joinEntry.SetEntityState( arguments.SetModified diff --git a/src/EFCore/ChangeTracking/Internal/NullableValueComparer`.cs b/src/EFCore/ChangeTracking/Internal/NullableValueComparer`.cs index 08ab11d801e..061f7b09c06 100644 --- a/src/EFCore/ChangeTracking/Internal/NullableValueComparer`.cs +++ b/src/EFCore/ChangeTracking/Internal/NullableValueComparer`.cs @@ -26,9 +26,7 @@ public NullableValueComparer(ValueComparer valueComparer) CreateEquals(valueComparer), CreateHashCode(valueComparer), CreateSnapshot(valueComparer)) - { - _valueComparer = valueComparer; - } + => _valueComparer = valueComparer; private static Expression> CreateEquals(ValueComparer valueComparer) { @@ -38,18 +36,18 @@ public NullableValueComparer(ValueComparer valueComparer) var v1HasValue = Expression.MakeMemberAccess(newEqualsParam1, _hasValueProperty); var v2HasValue = Expression.MakeMemberAccess(newEqualsParam2, _hasValueProperty); return Expression.Lambda>( - Expression.OrElse( - Expression.AndAlso( - v1HasValue, - Expression.AndAlso( - v2HasValue, - valueComparer.ExtractEqualsBody( - Expression.Convert(newEqualsParam1, valueComparer.Type), - Expression.Convert(newEqualsParam2, valueComparer.Type)))), - Expression.AndAlso( - Expression.Not(v1HasValue), - Expression.Not(v2HasValue))), - newEqualsParam1, newEqualsParam2); + Expression.OrElse( + Expression.AndAlso( + v1HasValue, + Expression.AndAlso( + v2HasValue, + valueComparer.ExtractEqualsBody( + Expression.Convert(newEqualsParam1, valueComparer.Type), + Expression.Convert(newEqualsParam2, valueComparer.Type)))), + Expression.AndAlso( + Expression.Not(v1HasValue), + Expression.Not(v2HasValue))), + newEqualsParam1, newEqualsParam2); } private static Expression> CreateHashCode(ValueComparer valueComparer) @@ -57,12 +55,12 @@ public NullableValueComparer(ValueComparer valueComparer) var clrType = typeof(T?); var newHashCodeParam = Expression.Parameter(clrType, "v"); return Expression.Lambda>( - Expression.Condition( - Expression.MakeMemberAccess(newHashCodeParam, _hasValueProperty), - valueComparer.ExtractHashCodeBody( - Expression.Convert(newHashCodeParam, valueComparer.Type)), - Expression.Constant(0, typeof(int))), - newHashCodeParam); + Expression.Condition( + Expression.MakeMemberAccess(newHashCodeParam, _hasValueProperty), + valueComparer.ExtractHashCodeBody( + Expression.Convert(newHashCodeParam, valueComparer.Type)), + Expression.Constant(0, typeof(int))), + newHashCodeParam); } private static Expression> CreateSnapshot(ValueComparer valueComparer) @@ -70,14 +68,15 @@ public NullableValueComparer(ValueComparer valueComparer) var clrType = typeof(T?); var newSnapshotParam = Expression.Parameter(clrType, "v"); return Expression.Lambda>( - Expression.Condition( - Expression.MakeMemberAccess(newSnapshotParam, _hasValueProperty), - Expression.Convert( - valueComparer.ExtractSnapshotBody( - Expression.Convert(newSnapshotParam, valueComparer.Type)), clrType), - Expression.Default(clrType)), - newSnapshotParam); + Expression.Condition( + Expression.MakeMemberAccess(newSnapshotParam, _hasValueProperty), + Expression.Convert( + valueComparer.ExtractSnapshotBody( + Expression.Convert(newSnapshotParam, valueComparer.Type)), clrType), + Expression.Default(clrType)), + newSnapshotParam); } - ValueComparer IInfrastructure.Instance => _valueComparer; + ValueComparer IInfrastructure.Instance + => _valueComparer; } diff --git a/src/EFCore/ChangeTracking/Internal/ShadowValuesFactoryFactory.cs b/src/EFCore/ChangeTracking/Internal/ShadowValuesFactoryFactory.cs index 9b845c7edbb..5e80c288ab1 100644 --- a/src/EFCore/ChangeTracking/Internal/ShadowValuesFactoryFactory.cs +++ b/src/EFCore/ChangeTracking/Internal/ShadowValuesFactoryFactory.cs @@ -99,11 +99,13 @@ protected override Expression CreateReadShadowValueExpression( property.ClrType); } - return Expression.Condition(Expression.Call(parameter, PropertyAccessorsFactory.ContainsKeyMethod, Expression.Constant(property.Name)), - Expression.Convert(Expression.MakeIndex( - parameter, - DictionaryIndexer, - new[] { Expression.Constant(property.Name) }), + return Expression.Condition( + Expression.Call(parameter, PropertyAccessorsFactory.ContainsKeyMethod, Expression.Constant(property.Name)), + Expression.Convert( + Expression.MakeIndex( + parameter, + DictionaryIndexer, + new[] { Expression.Constant(property.Name) }), property.ClrType), Expression.Constant(property.Sentinel, property.ClrType)); } diff --git a/src/EFCore/ChangeTracking/Internal/Snapshot.cs b/src/EFCore/ChangeTracking/Internal/Snapshot.cs index 9bd08b53dbb..460dfc5c6e0 100644 --- a/src/EFCore/ChangeTracking/Internal/Snapshot.cs +++ b/src/EFCore/ChangeTracking/Internal/Snapshot.cs @@ -70,7 +70,8 @@ public T GetValue(int index) /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public static readonly MethodInfo GetValueMethod - = typeof(ISnapshot).GetMethod(nameof(GetValue), 1, BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, + = typeof(ISnapshot).GetMethod( + nameof(GetValue), 1, BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, null, CallingConventions.Any, [typeof(int)], null)!; /// @@ -117,7 +118,7 @@ public static Type CreateSnapshotType(Type[] types) _ => throw new IndexOutOfRangeException() }; - /// + /// bool ISnapshot.IsEmpty => true; } @@ -129,7 +130,7 @@ bool ISnapshot.IsEmpty /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public sealed class Snapshot + T23, T24, T25, T26, T27, T28, T29> : ISnapshot { private static readonly Delegate[] ValueReaders = @@ -487,7 +488,7 @@ public object? this[int index] /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public sealed class Snapshot + T23, T24, T25, T26, T27, T28> : ISnapshot { private static readonly Delegate[] ValueReaders = @@ -835,7 +836,7 @@ public object? this[int index] /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public sealed class Snapshot + T23, T24, T25, T26, T27> : ISnapshot { private static readonly Delegate[] ValueReaders = @@ -1173,7 +1174,7 @@ public object? this[int index] /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public sealed class Snapshot + T23, T24, T25, T26> : ISnapshot { private static readonly Delegate[] ValueReaders = @@ -1501,7 +1502,7 @@ public object? this[int index] /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public sealed class Snapshot + T23, T24, T25> : ISnapshot { private static readonly Delegate[] ValueReaders = @@ -1819,7 +1820,7 @@ public object? this[int index] /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public sealed class Snapshot + T23, T24> : ISnapshot { private static readonly Delegate[] ValueReaders = @@ -2102,7 +2103,7 @@ public object? this[int index] /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public sealed class Snapshot + T23> : ISnapshot { private static readonly Delegate[] ValueReaders = @@ -5843,9 +5844,7 @@ public sealed class Snapshot /// public Snapshot( T0 value0) - { - _value0 = value0; - } + => _value0 = value0; private T0 _value0; diff --git a/src/EFCore/ChangeTracking/Internal/SnapshotFactoryFactory.cs b/src/EFCore/ChangeTracking/Internal/SnapshotFactoryFactory.cs index 92fe7ef24bf..1f2dd69a7f4 100644 --- a/src/EFCore/ChangeTracking/Internal/SnapshotFactoryFactory.cs +++ b/src/EFCore/ChangeTracking/Internal/SnapshotFactoryFactory.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Reflection.Metadata; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata.Internal; @@ -137,7 +136,8 @@ protected virtual Expression CreateSnapshotExpression( } var memberInfo = propertyBase.GetMemberInfo(forMaterialization: false, forSet: false); - var memberAccess = PropertyAccessorsFactory.CreateMemberAccess(propertyBase, entityVariable!, memberInfo, fromContainingType: false); + var memberAccess = PropertyAccessorsFactory.CreateMemberAccess( + propertyBase, entityVariable!, memberInfo, fromContainingType: false); if (memberAccess.Type != propertyBase.ClrType) { diff --git a/src/EFCore/ChangeTracking/Internal/SnapshotFactoryFactory`.cs b/src/EFCore/ChangeTracking/Internal/SnapshotFactoryFactory`.cs index 375e5b8fe7a..ae4584d3410 100644 --- a/src/EFCore/ChangeTracking/Internal/SnapshotFactoryFactory`.cs +++ b/src/EFCore/ChangeTracking/Internal/SnapshotFactoryFactory`.cs @@ -33,7 +33,7 @@ public virtual Expression> CreateExpression(IRuntimeEnti var parameter = Expression.Parameter(typeof(TInput), "source"); return Expression.Lambda>( - CreateConstructorExpression(entityType, parameter), - parameter); + CreateConstructorExpression(entityType, parameter), + parameter); } } diff --git a/src/EFCore/ChangeTracking/Internal/StateManager.cs b/src/EFCore/ChangeTracking/Internal/StateManager.cs index 8ce4bc0a536..915c5818596 100644 --- a/src/EFCore/ChangeTracking/Internal/StateManager.cs +++ b/src/EFCore/ChangeTracking/Internal/StateManager.cs @@ -812,10 +812,8 @@ public virtual void UpdateReferencedUntrackedEntity( InternalEntityEntry referencedFromEntry) { if (_referencedUntrackedEntities != null - && _referencedUntrackedEntities.TryGetValue(referencedEntity, out var danglers)) + && _referencedUntrackedEntities.Remove(referencedEntity, out var danglers)) { - _referencedUntrackedEntities.Remove(referencedEntity); - if (!_referencedUntrackedEntities.TryGetValue(newReferencedEntity, out var newDanglers)) { newDanglers = new List>(); diff --git a/src/EFCore/ChangeTracking/Internal/StructuralEntryCurrentProviderValueComparer.cs b/src/EFCore/ChangeTracking/Internal/StructuralEntryCurrentProviderValueComparer.cs index a1448a4b41c..4ef172e8463 100644 --- a/src/EFCore/ChangeTracking/Internal/StructuralEntryCurrentProviderValueComparer.cs +++ b/src/EFCore/ChangeTracking/Internal/StructuralEntryCurrentProviderValueComparer.cs @@ -21,9 +21,7 @@ public class StructuralEntryCurrentProviderValueComparer : StructuralEntryCurren /// public StructuralEntryCurrentProviderValueComparer(IProperty property) : base(property) - { - _converter = property.GetTypeMapping().Converter!; - } + => _converter = property.GetTypeMapping().Converter!; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/ChangeTracking/Internal/ValueComparerExtensions.cs b/src/EFCore/ChangeTracking/Internal/ValueComparerExtensions.cs index 293048be884..d5a17ac236f 100644 --- a/src/EFCore/ChangeTracking/Internal/ValueComparerExtensions.cs +++ b/src/EFCore/ChangeTracking/Internal/ValueComparerExtensions.cs @@ -21,8 +21,8 @@ public static class ValueComparerExtensions => valueComparer == null || !clrType.IsNullableValueType() || valueComparer.Type.IsNullableValueType() - ? valueComparer - : (ValueComparer)Activator.CreateInstance( - typeof(NullableValueComparer<>).MakeGenericType(valueComparer.Type), - valueComparer)!; + ? valueComparer + : (ValueComparer)Activator.CreateInstance( + typeof(NullableValueComparer<>).MakeGenericType(valueComparer.Type), + valueComparer)!; } diff --git a/src/EFCore/ChangeTracking/Internal/ValueGenerationManager.cs b/src/EFCore/ChangeTracking/Internal/ValueGenerationManager.cs index 14350e3ab34..5d657e4faa5 100644 --- a/src/EFCore/ChangeTracking/Internal/ValueGenerationManager.cs +++ b/src/EFCore/ChangeTracking/Internal/ValueGenerationManager.cs @@ -213,6 +213,7 @@ private bool TryFindValueGenerator( { propertyWithNoGenerator ??= property; } + return false; } @@ -223,7 +224,6 @@ private bool TryFindValueGenerator( return false; } - return true; } diff --git a/src/EFCore/ChangeTracking/ListOfNullableValueTypesComparer.cs b/src/EFCore/ChangeTracking/ListOfNullableValueTypesComparer.cs index 81c3724b7b4..d95a40877db 100644 --- a/src/EFCore/ChangeTracking/ListOfNullableValueTypesComparer.cs +++ b/src/EFCore/ChangeTracking/ListOfNullableValueTypesComparer.cs @@ -11,7 +11,8 @@ namespace Microsoft.EntityFrameworkCore.ChangeTracking; /// /// /// -/// This comparer should be used for nullable value types. Use for reference +/// This comparer should be used for nullable value types. Use +/// for reference /// types and non-nullable value types. /// /// @@ -20,7 +21,8 @@ namespace Microsoft.EntityFrameworkCore.ChangeTracking; /// /// The collection type to create an index of, if needed. /// The element type. -public sealed class ListOfNullableValueTypesComparer : ValueComparer>, IInfrastructure +public sealed class ListOfNullableValueTypesComparer : ValueComparer>, + IInfrastructure where TElement : struct { private static readonly bool IsArray = typeof(TConcreteList).IsArray; @@ -30,13 +32,16 @@ public sealed class ListOfNullableValueTypesComparer : && typeof(TConcreteList).GetGenericTypeDefinition() == typeof(ReadOnlyCollection<>)); private static readonly MethodInfo CompareMethod = typeof(ListOfNullableValueTypesComparer).GetMethod( - nameof(Compare), BindingFlags.Static | BindingFlags.NonPublic, [typeof(IEnumerable), typeof(IEnumerable), typeof(ValueComparer)])!; + nameof(Compare), BindingFlags.Static | BindingFlags.NonPublic, + [typeof(IEnumerable), typeof(IEnumerable), typeof(ValueComparer)])!; private static readonly MethodInfo GetHashCodeMethod = typeof(ListOfNullableValueTypesComparer).GetMethod( - nameof(GetHashCode), BindingFlags.Static | BindingFlags.NonPublic, [typeof(IEnumerable), typeof(ValueComparer)])!; + nameof(GetHashCode), BindingFlags.Static | BindingFlags.NonPublic, + [typeof(IEnumerable), typeof(ValueComparer)])!; private static readonly MethodInfo SnapshotMethod = typeof(ListOfNullableValueTypesComparer).GetMethod( - nameof(Snapshot), BindingFlags.Static | BindingFlags.NonPublic, [typeof(IEnumerable), typeof(ValueComparer)])!; + nameof(Snapshot), BindingFlags.Static | BindingFlags.NonPublic, + [typeof(IEnumerable), typeof(ValueComparer)])!; /// /// Creates a new instance of the list comparer. @@ -47,16 +52,15 @@ public ListOfNullableValueTypesComparer(ValueComparer elementComparer) CompareLambda(elementComparer), GetHashCodeLambda(elementComparer), SnapshotLambda(elementComparer)) - { - ElementComparer = elementComparer; - } + => ElementComparer = elementComparer; /// /// The comparer to use for comparing elements. /// public ValueComparer ElementComparer { get; } - ValueComparer IInfrastructure.Instance => ElementComparer; + ValueComparer IInfrastructure.Instance + => ElementComparer; private static Expression?, IEnumerable?, bool>> CompareLambda(ValueComparer elementComparer) { @@ -205,7 +209,7 @@ private static int GetHashCode(IEnumerable source, ValueComparer)Activator.CreateInstance(typeof(TConcreteList), [snapshot])! + ? (IList)Activator.CreateInstance(typeof(TConcreteList), snapshot)! : snapshot; } } diff --git a/src/EFCore/ChangeTracking/ListOfReferenceTypesComparer.cs b/src/EFCore/ChangeTracking/ListOfReferenceTypesComparer.cs index dccb4ed9b7b..e0e77528d87 100644 --- a/src/EFCore/ChangeTracking/ListOfReferenceTypesComparer.cs +++ b/src/EFCore/ChangeTracking/ListOfReferenceTypesComparer.cs @@ -47,16 +47,15 @@ public ListOfReferenceTypesComparer(ValueComparer elementComparer) CompareLambda(elementComparer), GetHashCodeLambda(elementComparer), SnapshotLambda(elementComparer)) - { - ElementComparer = elementComparer; - } + => ElementComparer = elementComparer; /// /// The comparer to use for comparing elements. /// public ValueComparer ElementComparer { get; } - ValueComparer IInfrastructure.Instance => ElementComparer; + ValueComparer IInfrastructure.Instance + => ElementComparer; private static Expression> CompareLambda(ValueComparer elementComparer) { @@ -201,7 +200,7 @@ private static int GetHashCode(IEnumerable source, ValueComparer elementComparer } return IsReadOnly - ? (IList)Activator.CreateInstance(typeof(TConcreteList), [snapshot])! + ? (IList)Activator.CreateInstance(typeof(TConcreteList), snapshot)! : snapshot; } } diff --git a/src/EFCore/ChangeTracking/ListOfValueTypesComparer.cs b/src/EFCore/ChangeTracking/ListOfValueTypesComparer.cs index ed3c88735a6..19a3a8d4a2f 100644 --- a/src/EFCore/ChangeTracking/ListOfValueTypesComparer.cs +++ b/src/EFCore/ChangeTracking/ListOfValueTypesComparer.cs @@ -30,10 +30,12 @@ public sealed class ListOfValueTypesComparer : ValueCom && typeof(TConcreteList).GetGenericTypeDefinition() == typeof(ReadOnlyCollection<>)); private static readonly MethodInfo CompareMethod = typeof(ListOfValueTypesComparer).GetMethod( - nameof(Compare), BindingFlags.Static | BindingFlags.NonPublic, [typeof(IEnumerable), typeof(IEnumerable), typeof(ValueComparer)])!; + nameof(Compare), BindingFlags.Static | BindingFlags.NonPublic, + [typeof(IEnumerable), typeof(IEnumerable), typeof(ValueComparer)])!; private static readonly MethodInfo GetHashCodeMethod = typeof(ListOfValueTypesComparer).GetMethod( - nameof(GetHashCode), BindingFlags.Static | BindingFlags.NonPublic, [typeof(IEnumerable), typeof(ValueComparer)])!; + nameof(GetHashCode), BindingFlags.Static | BindingFlags.NonPublic, + [typeof(IEnumerable), typeof(ValueComparer)])!; private static readonly MethodInfo SnapshotMethod = typeof(ListOfValueTypesComparer).GetMethod( nameof(Snapshot), BindingFlags.Static | BindingFlags.NonPublic, [typeof(IEnumerable), typeof(ValueComparer)])!; @@ -47,16 +49,15 @@ public ListOfValueTypesComparer(ValueComparer elementComparer) CompareLambda(elementComparer), GetHashCodeLambda(elementComparer), SnapshotLambda(elementComparer)) - { - ElementComparer = elementComparer; - } + => ElementComparer = elementComparer; /// /// The comparer to use for comparing elements. /// public ValueComparer ElementComparer { get; } - ValueComparer IInfrastructure.Instance => ElementComparer; + ValueComparer IInfrastructure.Instance + => ElementComparer; private static Expression?, IEnumerable?, bool>> CompareLambda(ValueComparer elementComparer) { @@ -190,7 +191,7 @@ private static IList Snapshot(IEnumerable source, ValueCompa } return IsReadOnly - ? (IList)Activator.CreateInstance(typeof(TConcreteList), [snapshot])! + ? (IList)Activator.CreateInstance(typeof(TConcreteList), snapshot)! : snapshot; } } diff --git a/src/EFCore/ChangeTracking/LocalView.cs b/src/EFCore/ChangeTracking/LocalView.cs index 67887ccd149..a84f3010442 100644 --- a/src/EFCore/ChangeTracking/LocalView.cs +++ b/src/EFCore/ChangeTracking/LocalView.cs @@ -54,7 +54,9 @@ public class LocalView<[DynamicallyAccessedMembers(IEntityType.DynamicallyAccess IListSource where TEntity : class { +#pragma warning disable EF1001 private ObservableBackedBindingList? _bindingList; +#pragma warning restore EF1001 private ObservableCollection? _observable; private readonly DbContext _context; private readonly IEntityType _entityType; @@ -472,10 +474,12 @@ private void OnCollectionChanged(NotifyCollectionChangedAction action, object it /// examples. /// /// The binding list. +#pragma warning disable EF1001 [RequiresUnreferencedCode( "BindingList raises ListChanged events with PropertyDescriptors. PropertyDescriptors require unreferenced code.")] public virtual BindingList ToBindingList() => _bindingList ??= new ObservableBackedBindingList(ToObservableCollection()); +#pragma warning restore EF1001 /// /// This method is called by data binding frameworks when attempting to data bind diff --git a/src/EFCore/ChangeTracking/ObservableHashSet.cs b/src/EFCore/ChangeTracking/ObservableHashSet.cs index c0808d762a9..1bcb3d4056d 100644 --- a/src/EFCore/ChangeTracking/ObservableHashSet.cs +++ b/src/EFCore/ChangeTracking/ObservableHashSet.cs @@ -42,9 +42,7 @@ public ObservableHashSet() /// implementation for the set type. /// public ObservableHashSet(IEqualityComparer comparer) - { - _set = new HashSet(comparer); - } + => _set = new HashSet(comparer); /// /// Initializes a new instance of the class @@ -71,9 +69,7 @@ public ObservableHashSet(IEnumerable collection) /// implementation for the set type. /// public ObservableHashSet(IEnumerable collection, IEqualityComparer comparer) - { - _set = new HashSet(collection, comparer); - } + => _set = new HashSet(collection, comparer); /// /// Occurs when a property of this hash set (such as ) changes. diff --git a/src/EFCore/ChangeTracking/PropertyValues.cs b/src/EFCore/ChangeTracking/PropertyValues.cs index 6e56d9815df..d33353d3266 100644 --- a/src/EFCore/ChangeTracking/PropertyValues.cs +++ b/src/EFCore/ChangeTracking/PropertyValues.cs @@ -32,9 +32,7 @@ public abstract class PropertyValues /// [EntityFrameworkInternal] protected PropertyValues(InternalEntityEntry internalEntry) - { - InternalEntry = internalEntry; - } + => InternalEntry = internalEntry; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/ChangeTracking/ValueComparer.cs b/src/EFCore/ChangeTracking/ValueComparer.cs index de943a804cc..831f6f7ba38 100644 --- a/src/EFCore/ChangeTracking/ValueComparer.cs +++ b/src/EFCore/ChangeTracking/ValueComparer.cs @@ -51,13 +51,14 @@ internal static readonly MethodInfo ObjectGetHashCodeMethod /// [EntityFrameworkInternal] public static MethodInfo GetGenericSnapshotMethod(Type type) - => _genericSnapshotMethodMap.GetOrAdd(type, t => - typeof(ValueComparer<>).MakeGenericType(t).GetGenericMethod( - nameof(ValueComparer.Snapshot), - genericParameterCount: 0, - BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, - (a, b) => new[] { a[0] }, - @override: false)!); + => _genericSnapshotMethodMap.GetOrAdd( + type, t => + typeof(ValueComparer<>).MakeGenericType(t).GetGenericMethod( + nameof(ValueComparer.Snapshot), + genericParameterCount: 0, + BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, + (a, b) => new[] { a[0] }, + @override: false)!); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/ChangeTracking/ValueComparer`.cs b/src/EFCore/ChangeTracking/ValueComparer`.cs index 633315f3166..d6eb5da40d8 100644 --- a/src/EFCore/ChangeTracking/ValueComparer`.cs +++ b/src/EFCore/ChangeTracking/ValueComparer`.cs @@ -29,17 +29,18 @@ namespace Microsoft.EntityFrameworkCore.ChangeTracking; /// The type. // PublicMethods is required to preserve e.g. GetHashCode public class ValueComparer - <[DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods - | DynamicallyAccessedMemberTypes.PublicProperties)] - T> +<[DynamicallyAccessedMembers( + DynamicallyAccessedMemberTypes.PublicMethods + | DynamicallyAccessedMemberTypes.NonPublicMethods + | DynamicallyAccessedMemberTypes.PublicProperties)] + T> : ValueComparer, IEqualityComparer { private Func? _equals; private Func? _hashCode; private Func? _snapshot; private LambdaExpression? _objectEqualsExpression; + private static readonly PropertyInfo StructuralComparisonsStructuralEqualityComparerProperty = typeof(StructuralComparisons).GetProperty(nameof(StructuralComparisons.StructuralEqualityComparer))!; @@ -367,8 +368,10 @@ public override Type Type => (Expression>)base.SnapshotExpression; private readonly ConstructorInfo _constructorInfo - = typeof(ValueComparer).GetConstructor([typeof(Expression>), typeof(Expression>), typeof(Expression>)])!; + = typeof(ValueComparer).GetConstructor( + [typeof(Expression>), typeof(Expression>), typeof(Expression>)])!; /// - public override Expression ConstructorExpression => New(_constructorInfo, EqualsExpression, HashCodeExpression, SnapshotExpression); + public override Expression ConstructorExpression + => New(_constructorInfo, EqualsExpression, HashCodeExpression, SnapshotExpression); } diff --git a/src/EFCore/DbContext.cs b/src/EFCore/DbContext.cs index 12f82a0d806..262bec51404 100644 --- a/src/EFCore/DbContext.cs +++ b/src/EFCore/DbContext.cs @@ -1112,6 +1112,7 @@ private bool DisposeSync(bool leaseActive, bool contextShouldBeDisposed) // This is necessary for the corner case where a pooled context is used only for design-time operations var _ = Model; } + _disposed = true; _lease = DbContextLease.InactiveLease; } diff --git a/src/EFCore/DbContextOptions.cs b/src/EFCore/DbContextOptions.cs index e618baca285..13839281a16 100644 --- a/src/EFCore/DbContextOptions.cs +++ b/src/EFCore/DbContextOptions.cs @@ -26,9 +26,7 @@ public abstract class DbContextOptions : IDbContextOptions /// [EntityFrameworkInternal] protected DbContextOptions() - { - _extensionsMap = ImmutableSortedDictionary.Create(TypeFullNameComparer.Instance); - } + => _extensionsMap = ImmutableSortedDictionary.Create(TypeFullNameComparer.Instance); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -39,10 +37,8 @@ protected DbContextOptions() [EntityFrameworkInternal] protected DbContextOptions( IReadOnlyDictionary extensions) - { - _extensionsMap = ImmutableSortedDictionary.Create(TypeFullNameComparer.Instance) + => _extensionsMap = ImmutableSortedDictionary.Create(TypeFullNameComparer.Instance) .AddRange(extensions.Select((p, i) => new KeyValuePair(p.Key, (p.Value, i)))); - } /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -53,9 +49,7 @@ protected DbContextOptions( [EntityFrameworkInternal] protected DbContextOptions( ImmutableSortedDictionary extensions) - { - _extensionsMap = extensions; - } + => _extensionsMap = extensions; /// /// Gets the extensions that store the configured options. diff --git a/src/EFCore/DbContextOptionsBuilder.cs b/src/EFCore/DbContextOptionsBuilder.cs index c77a4a94144..4e9030b2020 100644 --- a/src/EFCore/DbContextOptionsBuilder.cs +++ b/src/EFCore/DbContextOptionsBuilder.cs @@ -730,6 +730,50 @@ public virtual DbContextOptionsBuilder AddInterceptors(params IInterceptor[] int public virtual DbContextOptionsBuilder ConfigureLoggingCacheTime(TimeSpan timeSpan) => WithOption(e => e.WithLoggingCacheTime(timeSpan)); + /// + /// Configures the seed method to run after + /// is called or after migrations are applied. + /// It will be invoked even if no changes to the store were performed. + /// + /// + /// + /// The argument of the seed delegate indicates whether any store management + /// operation was performed. + /// + /// + /// It is recomended to also call with the same logic. + /// + /// + /// See Using DbContextOptions for more information and examples. + /// + /// + /// The seed method to run. + /// The same builder instance so that multiple calls can be chained. + public virtual DbContextOptionsBuilder UseSeeding(Action seed) + => WithOption(e => e.WithSeeding(seed)); + + /// + /// Configures the seed method to run after + /// is called or after migrations are applied asynchronously. + /// It will be invoked even if no changes to the store were performed. + /// + /// + /// + /// The argument of the seed delegate indicates whether any store management + /// operation was performed. + /// + /// + /// It is recomended to also call with the same logic. + /// + /// + /// See Using DbContextOptions for more information and examples. + /// + /// + /// The seed method to run. + /// The same builder instance so that multiple calls can be chained. + public virtual DbContextOptionsBuilder UseAsyncSeeding(Func seedAsync) + => WithOption(e => e.WithAsyncSeeding(seedAsync)); + /// /// Adds the given extension to the options. If an existing extension of the same type already exists, it will be replaced. /// diff --git a/src/EFCore/DbContextOptionsBuilder`.cs b/src/EFCore/DbContextOptionsBuilder`.cs index 6f7953c7d30..9baa9026fb7 100644 --- a/src/EFCore/DbContextOptionsBuilder`.cs +++ b/src/EFCore/DbContextOptionsBuilder`.cs @@ -629,4 +629,92 @@ public DbContextOptionsBuilder(DbContextOptions options) /// The same builder instance so that multiple calls can be chained. public new virtual DbContextOptionsBuilder ConfigureLoggingCacheTime(TimeSpan timeSpan) => (DbContextOptionsBuilder)base.ConfigureLoggingCacheTime(timeSpan); + + /// + /// Configures the seed method to run after + /// is called or after migrations are applied. + /// It will be invoked even if no changes to the store were performed. + /// + /// + /// + /// The argument of the seed delegate indicates whether any store management + /// operation was performed. + /// + /// + /// It is recomended to also call with the same logic. + /// + /// + /// See Using DbContextOptions for more information and examples. + /// + /// + /// The seed method to run. + /// The same builder instance so that multiple calls can be chained. + public new virtual DbContextOptionsBuilder UseSeeding(Action seed) + => (DbContextOptionsBuilder)base.UseSeeding((c, p) => seed(c, p)); + + /// + /// Configures the seed method to run after + /// is called or after migrations are applied. + /// It will be invoked even if no changes to the store were performed. + /// + /// + /// + /// The argument of the seed delegate indicates whether any store management + /// operation was performed. + /// + /// + /// It is recomended to also call with the same logic. + /// + /// + /// See Using DbContextOptions for more information and examples. + /// + /// + /// The seed method to run. + /// The same builder instance so that multiple calls can be chained. + public virtual DbContextOptionsBuilder UseSeeding(Action seed) + => (DbContextOptionsBuilder)base.UseSeeding((c, p) => seed((TContext)c, p)); + + /// + /// Configures the seed method to run after + /// is called or after migrations are applied asynchronously. + /// It will be invoked even if no changes to the store were performed. + /// + /// + /// + /// The argument of the seed delegate indicates whether any store management + /// operation was performed. + /// + /// + /// It is recomended to also call with the same logic. + /// + /// + /// See Using DbContextOptions for more information and examples. + /// + /// + /// The seed method to run. + /// The same builder instance so that multiple calls can be chained. + public new virtual DbContextOptionsBuilder UseAsyncSeeding(Func seedAsync) + => (DbContextOptionsBuilder)base.UseAsyncSeeding((c, p, t) => seedAsync(c, p, t)); + + /// + /// Configures the seed method to run after + /// is called or after migrations are applied asynchronously. + /// It will be invoked even if no changes to the store were performed. + /// + /// + /// + /// The argument of the seed delegate indicates whether any store management + /// operation was performed. + /// + /// + /// It is recomended to also call with the same logic. + /// + /// + /// See Using DbContextOptions for more information and examples. + /// + /// + /// The seed method to run. + /// The same builder instance so that multiple calls can be chained. + public virtual DbContextOptionsBuilder UseAsyncSeeding(Func seedAsync) + => (DbContextOptionsBuilder)base.UseAsyncSeeding((c, p, t) => seedAsync((TContext)c, p, t)); } diff --git a/src/EFCore/DbUpdateException.cs b/src/EFCore/DbUpdateException.cs index a599bebd88f..ed9419f271f 100644 --- a/src/EFCore/DbUpdateException.cs +++ b/src/EFCore/DbUpdateException.cs @@ -66,11 +66,9 @@ public DbUpdateException( Exception? innerException, IReadOnlyList entries) : base(message, innerException) - { - _entries = entries + => _entries = entries .Where(e => e.EntityState != EntityState.Unchanged) .Select(e => e.ToEntityEntry()).ToList(); - } /// /// Initializes a new instance of the class. @@ -95,9 +93,7 @@ public DbUpdateException( Exception? innerException, IReadOnlyList entries) : base(message, innerException) - { - _entries = entries; - } + => _entries = entries; /// /// Initializes a new instance of the class from a serialized form. diff --git a/src/EFCore/Design/ICSharpHelper.cs b/src/EFCore/Design/ICSharpHelper.cs index e477c22d06d..6581ece0618 100644 --- a/src/EFCore/Design/ICSharpHelper.cs +++ b/src/EFCore/Design/ICSharpHelper.cs @@ -362,7 +362,8 @@ string Literal(Dictionary values, bool vertical = fa /// doing so can result in application failures when updating to a new Entity Framework Core release. /// [EntityFrameworkInternal] - string Statement(Expression node, + string Statement( + Expression node, ISet collectedNamespaces, ISet unsafeAccessors, IReadOnlyDictionary? constantReplacements = null, @@ -384,7 +385,8 @@ string Statement(Expression node, /// doing so can result in application failures when updating to a new Entity Framework Core release. /// [EntityFrameworkInternal] - string Expression(Expression node, + string Expression( + Expression node, ISet collectedNamespaces, ISet unsafeAccessors, IReadOnlyDictionary? constantReplacements = null, diff --git a/src/EFCore/Design/Internal/CSharpRuntimeAnnotationCodeGenerator.cs b/src/EFCore/Design/Internal/CSharpRuntimeAnnotationCodeGenerator.cs index 7b74a056669..ef13010eb6b 100644 --- a/src/EFCore/Design/Internal/CSharpRuntimeAnnotationCodeGenerator.cs +++ b/src/EFCore/Design/Internal/CSharpRuntimeAnnotationCodeGenerator.cs @@ -10,21 +10,17 @@ namespace Microsoft.EntityFrameworkCore.Design.Internal; /// /// Base class to be used by database providers when implementing an /// -public class CSharpRuntimeAnnotationCodeGenerator : ICSharpRuntimeAnnotationCodeGenerator +/// +/// Initializes a new instance of this class. +/// +/// Parameter object containing dependencies for this service. +public class CSharpRuntimeAnnotationCodeGenerator(CSharpRuntimeAnnotationCodeGeneratorDependencies dependencies) + : ICSharpRuntimeAnnotationCodeGenerator { - /// - /// Initializes a new instance of this class. - /// - /// Parameter object containing dependencies for this service. - public CSharpRuntimeAnnotationCodeGenerator(CSharpRuntimeAnnotationCodeGeneratorDependencies dependencies) - { - Dependencies = dependencies; - } - /// /// Dependencies for this service. /// - protected virtual CSharpRuntimeAnnotationCodeGeneratorDependencies Dependencies { get; } + protected virtual CSharpRuntimeAnnotationCodeGeneratorDependencies Dependencies { get; } = dependencies; /// public virtual void Generate(IModel model, CSharpRuntimeAnnotationCodeGeneratorParameters parameters) @@ -343,6 +339,10 @@ public static void AddNamespace(Type type, ISet namespaces) } } + /// + public void Create(ValueConverter converter, CSharpRuntimeAnnotationCodeGeneratorParameters parameters) + => Create(converter, parameters, Dependencies.CSharpHelper); + /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in @@ -373,14 +373,16 @@ public static void Create( .Append(codeHelper.Reference(converter.ProviderClrType)) .AppendLine(">(") .IncrementIndent() - .AppendLines(codeHelper.Expression(converter.ConvertToProviderExpression, parameters.Namespaces, unsafeAccessors), + .AppendLines( + codeHelper.Expression(converter.ConvertToProviderExpression, parameters.Namespaces, unsafeAccessors), skipFinalNewline: true) .AppendLine(",") - .AppendLines(codeHelper.Expression(converter.ConvertFromProviderExpression, parameters.Namespaces, unsafeAccessors), + .AppendLines( + codeHelper.Expression(converter.ConvertFromProviderExpression, parameters.Namespaces, unsafeAccessors), skipFinalNewline: true); - Check.DebugAssert(unsafeAccessors.Count == 0, "Generated unsafe accessors not handled: " + - string.Join(Environment.NewLine, unsafeAccessors)); + Check.DebugAssert( + unsafeAccessors.Count == 0, "Generated unsafe accessors not handled: " + string.Join(Environment.NewLine, unsafeAccessors)); if (converter.ConvertsNulls) { @@ -441,19 +443,22 @@ public static void Create( .Append(codeHelper.Reference(comparer.Type)) .AppendLine(">(") .IncrementIndent() - .AppendLines(codeHelper.Expression(comparer.EqualsExpression, parameters.Namespaces, unsafeAccessors), + .AppendLines( + codeHelper.Expression(comparer.EqualsExpression, parameters.Namespaces, unsafeAccessors), skipFinalNewline: true) .AppendLine(",") - .AppendLines(codeHelper.Expression(comparer.HashCodeExpression, parameters.Namespaces, unsafeAccessors), + .AppendLines( + codeHelper.Expression(comparer.HashCodeExpression, parameters.Namespaces, unsafeAccessors), skipFinalNewline: true) .AppendLine(",") - .AppendLines(codeHelper.Expression(comparer.SnapshotExpression, parameters.Namespaces, unsafeAccessors), + .AppendLines( + codeHelper.Expression(comparer.SnapshotExpression, parameters.Namespaces, unsafeAccessors), skipFinalNewline: true) .Append(")") .DecrementIndent(); - Check.DebugAssert(unsafeAccessors.Count == 0, "Generated unsafe accessors not handled: " + - string.Join(Environment.NewLine, unsafeAccessors)); + Check.DebugAssert( + unsafeAccessors.Count == 0, "Generated unsafe accessors not handled: " + string.Join(Environment.NewLine, unsafeAccessors)); } else { diff --git a/src/EFCore/Design/Internal/CSharpRuntimeAnnotationCodeGeneratorDependencies.cs b/src/EFCore/Design/Internal/CSharpRuntimeAnnotationCodeGeneratorDependencies.cs index 97b0f38a875..cbf2e7a9bb2 100644 --- a/src/EFCore/Design/Internal/CSharpRuntimeAnnotationCodeGeneratorDependencies.cs +++ b/src/EFCore/Design/Internal/CSharpRuntimeAnnotationCodeGeneratorDependencies.cs @@ -38,9 +38,7 @@ public sealed record CSharpRuntimeAnnotationCodeGeneratorDependencies /// [EntityFrameworkInternal] public CSharpRuntimeAnnotationCodeGeneratorDependencies(ICSharpHelper cSharpHelper) - { - CSharpHelper = cSharpHelper; - } + => CSharpHelper = cSharpHelper; /// /// The C# helper. diff --git a/src/EFCore/Design/Internal/CSharpRuntimeAnnotationCodeGeneratorParameters.cs b/src/EFCore/Design/Internal/CSharpRuntimeAnnotationCodeGeneratorParameters.cs index be818b6610c..653d116bdcb 100644 --- a/src/EFCore/Design/Internal/CSharpRuntimeAnnotationCodeGeneratorParameters.cs +++ b/src/EFCore/Design/Internal/CSharpRuntimeAnnotationCodeGeneratorParameters.cs @@ -33,7 +33,8 @@ public CSharpRuntimeAnnotationCodeGeneratorParameters( IDictionary scopeObjects, IDictionary scopeVariables, Dictionary configurationClassNames, - bool nullable) + bool nullable, + bool nativeAot) { TargetName = targetName; ClassName = className; @@ -45,6 +46,7 @@ public CSharpRuntimeAnnotationCodeGeneratorParameters( ScopeVariables = scopeVariables; ConfigurationClassNames = configurationClassNames; UseNullableReferenceTypes = nullable; + ForNativeAot = nativeAot; } /// @@ -107,4 +109,10 @@ public CSharpRuntimeAnnotationCodeGeneratorParameters( /// /// A value indicating whether nullable reference types are enabled. public bool UseNullableReferenceTypes { get; init; } + + /// + /// Gets or sets a value indicating whether the generated code should be compatible with NativeAOT. + /// + /// A value indicating whether the generated code should be compatible with NativeAOT. + public bool ForNativeAot { get; init; } } diff --git a/src/EFCore/Design/Internal/ICSharpRuntimeAnnotationCodeGenerator.cs b/src/EFCore/Design/Internal/ICSharpRuntimeAnnotationCodeGenerator.cs index 56a2409c3d2..82a6e67bcb1 100644 --- a/src/EFCore/Design/Internal/ICSharpRuntimeAnnotationCodeGenerator.cs +++ b/src/EFCore/Design/Internal/ICSharpRuntimeAnnotationCodeGenerator.cs @@ -137,4 +137,11 @@ bool Create( /// The value comparer to create. /// Additional parameters used during code generation. void Create(ValueComparer comparer, CSharpRuntimeAnnotationCodeGeneratorParameters parameters); + + /// + /// Generates code to create the given value converter. + /// + /// The value converter to create. + /// Additional parameters used during code generation. + void Create(ValueConverter converter, CSharpRuntimeAnnotationCodeGeneratorParameters parameters); } diff --git a/src/EFCore/Design/MethodCallCodeFragment.cs b/src/EFCore/Design/MethodCallCodeFragment.cs index e0640c4f0fc..97a9fc8f615 100644 --- a/src/EFCore/Design/MethodCallCodeFragment.cs +++ b/src/EFCore/Design/MethodCallCodeFragment.cs @@ -64,18 +64,14 @@ private MethodCallCodeFragment( object?[] arguments, MethodCallCodeFragment chainedCall) : this(methodInfo, arguments) - { - ChainedCall = chainedCall; - } + => ChainedCall = chainedCall; private MethodCallCodeFragment( string method, object?[] arguments, MethodCallCodeFragment chainedCall) : this(method, arguments) - { - ChainedCall = chainedCall; - } + => ChainedCall = chainedCall; /// /// Gets the for this method call. diff --git a/src/EFCore/Diagnostics/AssemblyEventData.cs b/src/EFCore/Diagnostics/AssemblyEventData.cs index e277f72db14..3ebc84453de 100644 --- a/src/EFCore/Diagnostics/AssemblyEventData.cs +++ b/src/EFCore/Diagnostics/AssemblyEventData.cs @@ -22,9 +22,7 @@ public AssemblyEventData( Func messageGenerator, Assembly assembly) : base(eventDefinition, messageGenerator) - { - Assembly = assembly; - } + => Assembly = assembly; /// /// The assembly. diff --git a/src/EFCore/Diagnostics/ComplexPropertyEventData.cs b/src/EFCore/Diagnostics/ComplexPropertyEventData.cs index c38393b9860..7c840eb9ec2 100644 --- a/src/EFCore/Diagnostics/ComplexPropertyEventData.cs +++ b/src/EFCore/Diagnostics/ComplexPropertyEventData.cs @@ -23,9 +23,7 @@ public ComplexPropertyEventData( Func messageGenerator, IReadOnlyComplexProperty property) : base(eventDefinition, messageGenerator) - { - Property = property; - } + => Property = property; /// /// The property. diff --git a/src/EFCore/Diagnostics/ConcurrencyExceptionEventData.cs b/src/EFCore/Diagnostics/ConcurrencyExceptionEventData.cs index 41d3903fba4..ca051e929e4 100644 --- a/src/EFCore/Diagnostics/ConcurrencyExceptionEventData.cs +++ b/src/EFCore/Diagnostics/ConcurrencyExceptionEventData.cs @@ -31,9 +31,7 @@ public ConcurrencyExceptionEventData( IReadOnlyList entries, DbUpdateConcurrencyException exception) : base(eventDefinition, messageGenerator, context, exception) - { - _internalEntries = entries; - } + => _internalEntries = entries; /// /// The exception that will be thrown, unless throwing is suppressed. diff --git a/src/EFCore/Diagnostics/CoreEventId.cs b/src/EFCore/Diagnostics/CoreEventId.cs index 8382a57f2ac..96e7011ec7f 100644 --- a/src/EFCore/Diagnostics/CoreEventId.cs +++ b/src/EFCore/Diagnostics/CoreEventId.cs @@ -617,7 +617,7 @@ private static EventId MakeModelValidationId(Id id) public static readonly EventId TypeLoadingErrorWarning = MakeModelId(Id.TypeLoadingErrorWarning); /// - /// A type that implements could not be instantiated. + /// A type that implements could not be instantiated. /// /// /// @@ -634,7 +634,7 @@ private static EventId MakeModelValidationId(Id id) public static readonly EventId SkippedEntityTypeConfigurationWarning = MakeModelId(Id.SkippedEntityTypeConfigurationWarning); /// - /// A type that implements could not be instantiated. + /// A type that implements could not be instantiated. /// /// /// diff --git a/src/EFCore/Diagnostics/CoreLoggerExtensions.cs b/src/EFCore/Diagnostics/CoreLoggerExtensions.cs index 38645b59f9b..a9278fbce72 100644 --- a/src/EFCore/Diagnostics/CoreLoggerExtensions.cs +++ b/src/EFCore/Diagnostics/CoreLoggerExtensions.cs @@ -758,7 +758,7 @@ private static string TypeLoadingErrorWarning(EventDefinitionBase definition, Ev /// Logs for the event. /// /// The diagnostics logger to use. - /// The type. + /// The type. public static void SkippedEntityTypeConfigurationWarning( this IDiagnosticsLogger diagnostics, Type type) diff --git a/src/EFCore/Diagnostics/DbContextErrorEventData.cs b/src/EFCore/Diagnostics/DbContextErrorEventData.cs index 55d7a71be79..69c47e8b090 100644 --- a/src/EFCore/Diagnostics/DbContextErrorEventData.cs +++ b/src/EFCore/Diagnostics/DbContextErrorEventData.cs @@ -25,9 +25,7 @@ public DbContextErrorEventData( DbContext context, Exception exception) : base(eventDefinition, messageGenerator, context) - { - Exception = exception; - } + => Exception = exception; /// /// The exception that triggered this event. diff --git a/src/EFCore/Diagnostics/DbContextEventData.cs b/src/EFCore/Diagnostics/DbContextEventData.cs index 9979061ea56..938b594ef42 100644 --- a/src/EFCore/Diagnostics/DbContextEventData.cs +++ b/src/EFCore/Diagnostics/DbContextEventData.cs @@ -23,9 +23,7 @@ public DbContextEventData( Func messageGenerator, DbContext? context) : base(eventDefinition, messageGenerator) - { - Context = context; - } + => Context = context; /// /// The current . diff --git a/src/EFCore/Diagnostics/DbContextTypeErrorEventData.cs b/src/EFCore/Diagnostics/DbContextTypeErrorEventData.cs index 6020d38427a..22d3fb3ff95 100644 --- a/src/EFCore/Diagnostics/DbContextTypeErrorEventData.cs +++ b/src/EFCore/Diagnostics/DbContextTypeErrorEventData.cs @@ -25,9 +25,7 @@ public DbContextTypeErrorEventData( Type contextType, Exception exception) : base(eventDefinition, messageGenerator, contextType) - { - Exception = exception; - } + => Exception = exception; /// /// The exception that triggered this event. diff --git a/src/EFCore/Diagnostics/DbContextTypeEventData.cs b/src/EFCore/Diagnostics/DbContextTypeEventData.cs index fb3265e8cb7..a9111907393 100644 --- a/src/EFCore/Diagnostics/DbContextTypeEventData.cs +++ b/src/EFCore/Diagnostics/DbContextTypeEventData.cs @@ -23,9 +23,7 @@ public DbContextTypeEventData( Func messageGenerator, Type contextType) : base(eventDefinition, messageGenerator) - { - ContextType = contextType; - } + => ContextType = contextType; /// /// The current . diff --git a/src/EFCore/Diagnostics/EntityEntryEventData.cs b/src/EFCore/Diagnostics/EntityEntryEventData.cs index 55a03937606..5fccac303f5 100644 --- a/src/EFCore/Diagnostics/EntityEntryEventData.cs +++ b/src/EFCore/Diagnostics/EntityEntryEventData.cs @@ -23,9 +23,7 @@ public EntityEntryEventData( Func messageGenerator, EntityEntry entityEntry) : base(eventDefinition, messageGenerator) - { - EntityEntry = entityEntry; - } + => EntityEntry = entityEntry; /// /// The entity entry. diff --git a/src/EFCore/Diagnostics/EntityTypeEventData.cs b/src/EFCore/Diagnostics/EntityTypeEventData.cs index 6aea10b9489..d32d576a706 100644 --- a/src/EFCore/Diagnostics/EntityTypeEventData.cs +++ b/src/EFCore/Diagnostics/EntityTypeEventData.cs @@ -23,9 +23,7 @@ public EntityTypeEventData( Func messageGenerator, IReadOnlyEntityType entityType) : base(eventDefinition, messageGenerator) - { - EntityType = entityType; - } + => EntityType = entityType; /// /// The entity type. diff --git a/src/EFCore/Diagnostics/EventDefinition.cs b/src/EFCore/Diagnostics/EventDefinition.cs index 953041c6c09..a72ef11cf4f 100644 --- a/src/EFCore/Diagnostics/EventDefinition.cs +++ b/src/EFCore/Diagnostics/EventDefinition.cs @@ -32,9 +32,7 @@ public EventDefinition( string eventIdCode, Func> logActionFunc) : base(loggingOptions, eventId, level, eventIdCode) - { - _logAction = logActionFunc(Level); - } + => _logAction = logActionFunc(Level); /// /// Generates the message that would be logged without logging it. diff --git a/src/EFCore/Diagnostics/EventDefinition`.cs b/src/EFCore/Diagnostics/EventDefinition`.cs index aa7800fa513..be98583f517 100644 --- a/src/EFCore/Diagnostics/EventDefinition`.cs +++ b/src/EFCore/Diagnostics/EventDefinition`.cs @@ -32,9 +32,7 @@ public EventDefinition( string eventIdCode, Func> logActionFunc) : base(loggingOptions, eventId, level, eventIdCode) - { - _logAction = logActionFunc(Level); - } + => _logAction = logActionFunc(Level); /// /// Generates the message that would be logged without logging it. diff --git a/src/EFCore/Diagnostics/EventDefinition``.cs b/src/EFCore/Diagnostics/EventDefinition``.cs index 3d44e1100c6..7fdc8b352f1 100644 --- a/src/EFCore/Diagnostics/EventDefinition``.cs +++ b/src/EFCore/Diagnostics/EventDefinition``.cs @@ -32,9 +32,7 @@ public EventDefinition( string eventIdCode, Func> logActionFunc) : base(loggingOptions, eventId, level, eventIdCode) - { - _logAction = logActionFunc(Level); - } + => _logAction = logActionFunc(Level); /// /// Generates the message that would be logged without logging it. diff --git a/src/EFCore/Diagnostics/EventDefinition```.cs b/src/EFCore/Diagnostics/EventDefinition```.cs index f1f52dacdb8..a5b76ec75d8 100644 --- a/src/EFCore/Diagnostics/EventDefinition```.cs +++ b/src/EFCore/Diagnostics/EventDefinition```.cs @@ -32,9 +32,7 @@ public EventDefinition( string eventIdCode, Func> logActionFunc) : base(loggingOptions, eventId, level, eventIdCode) - { - _logAction = logActionFunc(Level); - } + => _logAction = logActionFunc(Level); /// /// Generates the message that would be logged without logging it. diff --git a/src/EFCore/Diagnostics/EventDefinition````.cs b/src/EFCore/Diagnostics/EventDefinition````.cs index 234880b6d1c..3ccd5e93190 100644 --- a/src/EFCore/Diagnostics/EventDefinition````.cs +++ b/src/EFCore/Diagnostics/EventDefinition````.cs @@ -32,9 +32,7 @@ public EventDefinition( string eventIdCode, Func> logActionFunc) : base(loggingOptions, eventId, level, eventIdCode) - { - _logAction = logActionFunc(Level); - } + => _logAction = logActionFunc(Level); /// /// Generates the message that would be logged without logging it. diff --git a/src/EFCore/Diagnostics/EventDefinition`````.cs b/src/EFCore/Diagnostics/EventDefinition`````.cs index 293aaa90b0e..63d644ad227 100644 --- a/src/EFCore/Diagnostics/EventDefinition`````.cs +++ b/src/EFCore/Diagnostics/EventDefinition`````.cs @@ -32,9 +32,7 @@ public EventDefinition( string eventIdCode, Func> logActionFunc) : base(loggingOptions, eventId, level, eventIdCode) - { - _logAction = logActionFunc(Level); - } + => _logAction = logActionFunc(Level); /// /// Generates the message that would be logged without logging it. diff --git a/src/EFCore/Diagnostics/EventDefinition``````.cs b/src/EFCore/Diagnostics/EventDefinition``````.cs index c9a618697cd..3dcd93029cd 100644 --- a/src/EFCore/Diagnostics/EventDefinition``````.cs +++ b/src/EFCore/Diagnostics/EventDefinition``````.cs @@ -32,9 +32,7 @@ public EventDefinition( string eventIdCode, Func> logActionFunc) : base(loggingOptions, eventId, level, eventIdCode) - { - _logAction = logActionFunc(Level); - } + => _logAction = logActionFunc(Level); /// /// Generates the message that would be logged without logging it. diff --git a/src/EFCore/Diagnostics/ExpressionEventData.cs b/src/EFCore/Diagnostics/ExpressionEventData.cs index 4c585ade1ef..44810eadecd 100644 --- a/src/EFCore/Diagnostics/ExpressionEventData.cs +++ b/src/EFCore/Diagnostics/ExpressionEventData.cs @@ -23,9 +23,7 @@ public ExpressionEventData( Func messageGenerator, Expression expression) : base(eventDefinition, messageGenerator) - { - Expression = expression; - } + => Expression = expression; /// /// The . diff --git a/src/EFCore/Diagnostics/FallbackEventDefinition.cs b/src/EFCore/Diagnostics/FallbackEventDefinition.cs index 3471af3a3e5..b5cbdedbfea 100644 --- a/src/EFCore/Diagnostics/FallbackEventDefinition.cs +++ b/src/EFCore/Diagnostics/FallbackEventDefinition.cs @@ -30,9 +30,7 @@ public FallbackEventDefinition( string eventIdCode, string messageFormat) : base(loggingOptions, eventId, level, eventIdCode) - { - MessageFormat = messageFormat; - } + => MessageFormat = messageFormat; /// /// Generates the message that would be logged without logging it. diff --git a/src/EFCore/Diagnostics/ForeignKeyEventData.cs b/src/EFCore/Diagnostics/ForeignKeyEventData.cs index b2286dae0dd..d2016a02707 100644 --- a/src/EFCore/Diagnostics/ForeignKeyEventData.cs +++ b/src/EFCore/Diagnostics/ForeignKeyEventData.cs @@ -23,9 +23,7 @@ public ForeignKeyEventData( Func messageGenerator, IReadOnlyForeignKey foreignKey) : base(eventDefinition, messageGenerator) - { - ForeignKey = foreignKey; - } + => ForeignKey = foreignKey; /// /// The foreign key. diff --git a/src/EFCore/Diagnostics/IdentityResolutionInterceptionData.cs b/src/EFCore/Diagnostics/IdentityResolutionInterceptionData.cs index 47d407ced20..e8d363fcea2 100644 --- a/src/EFCore/Diagnostics/IdentityResolutionInterceptionData.cs +++ b/src/EFCore/Diagnostics/IdentityResolutionInterceptionData.cs @@ -20,9 +20,7 @@ public readonly struct IdentityResolutionInterceptionData [EntityFrameworkInternal] [UsedImplicitly] public IdentityResolutionInterceptionData(DbContext context) - { - Context = context; - } + => Context = context; /// /// The current instance being used. diff --git a/src/EFCore/Diagnostics/InstantiationBindingInterceptionData.cs b/src/EFCore/Diagnostics/InstantiationBindingInterceptionData.cs index 5341c44a67d..19800577210 100644 --- a/src/EFCore/Diagnostics/InstantiationBindingInterceptionData.cs +++ b/src/EFCore/Diagnostics/InstantiationBindingInterceptionData.cs @@ -20,9 +20,7 @@ public readonly struct InstantiationBindingInterceptionData [EntityFrameworkInternal] [UsedImplicitly] public InstantiationBindingInterceptionData(ITypeBase typeBase) - { - TypeBase = typeBase; - } + => TypeBase = typeBase; /// /// The entity type for which the binding is being used. diff --git a/src/EFCore/Diagnostics/InterceptionResult.cs b/src/EFCore/Diagnostics/InterceptionResult.cs index 387466c682c..10363e09ceb 100644 --- a/src/EFCore/Diagnostics/InterceptionResult.cs +++ b/src/EFCore/Diagnostics/InterceptionResult.cs @@ -29,9 +29,7 @@ public static InterceptionResult Suppress() => new(true); private InterceptionResult(bool suppress) - { - IsSuppressed = suppress; - } + => IsSuppressed = suppress; /// /// If true, then interception is suppressed. diff --git a/src/EFCore/Diagnostics/KeyEventData.cs b/src/EFCore/Diagnostics/KeyEventData.cs index 0755183e20c..9aa593d639b 100644 --- a/src/EFCore/Diagnostics/KeyEventData.cs +++ b/src/EFCore/Diagnostics/KeyEventData.cs @@ -22,9 +22,7 @@ public KeyEventData( Func messageGenerator, IReadOnlyKey key) : base(eventDefinition, messageGenerator) - { - Key = key; - } + => Key = key; /// /// The foreign key. diff --git a/src/EFCore/Diagnostics/NavigationBaseEventData.cs b/src/EFCore/Diagnostics/NavigationBaseEventData.cs index ab21c6ceed0..beba8f8a877 100644 --- a/src/EFCore/Diagnostics/NavigationBaseEventData.cs +++ b/src/EFCore/Diagnostics/NavigationBaseEventData.cs @@ -22,9 +22,7 @@ public NavigationBaseEventData( Func messageGenerator, IReadOnlyNavigationBase navigationBase) : base(eventDefinition, messageGenerator) - { - NavigationBase = navigationBase; - } + => NavigationBase = navigationBase; /// /// The navigation base. diff --git a/src/EFCore/Diagnostics/NavigationEventData.cs b/src/EFCore/Diagnostics/NavigationEventData.cs index b77a2c8bab5..fdc93fc942f 100644 --- a/src/EFCore/Diagnostics/NavigationEventData.cs +++ b/src/EFCore/Diagnostics/NavigationEventData.cs @@ -22,9 +22,7 @@ public NavigationEventData( Func messageGenerator, IReadOnlyNavigation navigation) : base(eventDefinition, messageGenerator) - { - Navigation = navigation; - } + => Navigation = navigation; /// /// The navigation. diff --git a/src/EFCore/Diagnostics/PropertyEventData.cs b/src/EFCore/Diagnostics/PropertyEventData.cs index 9a97b8d5170..29a8b87f5b8 100644 --- a/src/EFCore/Diagnostics/PropertyEventData.cs +++ b/src/EFCore/Diagnostics/PropertyEventData.cs @@ -23,9 +23,7 @@ public PropertyEventData( Func messageGenerator, IReadOnlyProperty property) : base(eventDefinition, messageGenerator) - { - Property = property; - } + => Property = property; /// /// The property. diff --git a/src/EFCore/Diagnostics/SaveChangesCompletedEventData.cs b/src/EFCore/Diagnostics/SaveChangesCompletedEventData.cs index 70f5a040bac..ab14271afeb 100644 --- a/src/EFCore/Diagnostics/SaveChangesCompletedEventData.cs +++ b/src/EFCore/Diagnostics/SaveChangesCompletedEventData.cs @@ -25,9 +25,7 @@ public SaveChangesCompletedEventData( DbContext context, int entitiesSavedCount) : base(eventDefinition, messageGenerator, context) - { - EntitiesSavedCount = entitiesSavedCount; - } + => EntitiesSavedCount = entitiesSavedCount; /// /// The number of entities saved to the database. diff --git a/src/EFCore/Diagnostics/ServiceProviderEventData.cs b/src/EFCore/Diagnostics/ServiceProviderEventData.cs index 3fe2bcc11ea..e907c34f40e 100644 --- a/src/EFCore/Diagnostics/ServiceProviderEventData.cs +++ b/src/EFCore/Diagnostics/ServiceProviderEventData.cs @@ -23,9 +23,7 @@ public ServiceProviderEventData( Func messageGenerator, IServiceProvider serviceProvider) : base(eventDefinition, messageGenerator) - { - ServiceProvider = serviceProvider; - } + => ServiceProvider = serviceProvider; /// /// The . diff --git a/src/EFCore/Diagnostics/ServiceProvidersEventData.cs b/src/EFCore/Diagnostics/ServiceProvidersEventData.cs index 5fe411be4ec..cc2d923355e 100644 --- a/src/EFCore/Diagnostics/ServiceProvidersEventData.cs +++ b/src/EFCore/Diagnostics/ServiceProvidersEventData.cs @@ -23,9 +23,7 @@ public ServiceProvidersEventData( Func messageGenerator, ICollection serviceProviders) : base(eventDefinition, messageGenerator) - { - ServiceProviders = serviceProviders; - } + => ServiceProviders = serviceProviders; /// /// The s. diff --git a/src/EFCore/Diagnostics/SkipNavigationEventData.cs b/src/EFCore/Diagnostics/SkipNavigationEventData.cs index 830a2df93d1..500c1622e69 100644 --- a/src/EFCore/Diagnostics/SkipNavigationEventData.cs +++ b/src/EFCore/Diagnostics/SkipNavigationEventData.cs @@ -22,9 +22,7 @@ public SkipNavigationEventData( Func messageGenerator, IReadOnlySkipNavigation navigation) : base(eventDefinition, messageGenerator) - { - Navigation = navigation; - } + => Navigation = navigation; /// /// The navigation. diff --git a/src/EFCore/Diagnostics/TypeEventData.cs b/src/EFCore/Diagnostics/TypeEventData.cs index 0ec47ca1428..26cf0d2e550 100644 --- a/src/EFCore/Diagnostics/TypeEventData.cs +++ b/src/EFCore/Diagnostics/TypeEventData.cs @@ -22,9 +22,7 @@ public TypeEventData( Func messageGenerator, Type clrType) : base(eventDefinition, messageGenerator) - { - ClrType = clrType; - } + => ClrType = clrType; /// /// The associated with this event. diff --git a/src/EFCore/Diagnostics/TypeLoadingEventData.cs b/src/EFCore/Diagnostics/TypeLoadingEventData.cs index fee5957a7da..e46b02b647d 100644 --- a/src/EFCore/Diagnostics/TypeLoadingEventData.cs +++ b/src/EFCore/Diagnostics/TypeLoadingEventData.cs @@ -12,7 +12,7 @@ namespace Microsoft.EntityFrameworkCore.Diagnostics; public class TypeLoadingEventData : AssemblyEventData, IErrorEventData { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The event definition. /// A delegate that generates a log message for this event. @@ -24,9 +24,7 @@ public TypeLoadingEventData( Assembly assembly, Exception exception) : base(eventDefinition, messageGenerator, assembly) - { - Exception = exception; - } + => Exception = exception; /// /// Gets the type-loading exception. diff --git a/src/EFCore/Diagnostics/UniquifiedPropertyEventData.cs b/src/EFCore/Diagnostics/UniquifiedPropertyEventData.cs index b430dc4dc0d..f9b0a837a01 100644 --- a/src/EFCore/Diagnostics/UniquifiedPropertyEventData.cs +++ b/src/EFCore/Diagnostics/UniquifiedPropertyEventData.cs @@ -25,9 +25,7 @@ public UniquifiedPropertyEventData( IReadOnlyProperty property, string basePropertyName) : base(eventDefinition, messageGenerator, property) - { - BasePropertyName = basePropertyName; - } + => BasePropertyName = basePropertyName; /// /// The property name that was uniquified. diff --git a/src/EFCore/Diagnostics/UpdateEntryEventData.cs b/src/EFCore/Diagnostics/UpdateEntryEventData.cs index 75821e27809..29da2c0294c 100644 --- a/src/EFCore/Diagnostics/UpdateEntryEventData.cs +++ b/src/EFCore/Diagnostics/UpdateEntryEventData.cs @@ -25,9 +25,7 @@ public UpdateEntryEventData( Func messageGenerator, IUpdateEntry entityEntry) : base(eventDefinition, messageGenerator, ((InternalEntityEntry)entityEntry).Context) - { - EntityEntry = entityEntry; - } + => EntityEntry = entityEntry; /// /// The entry for the entity instance on which the property value has changed. diff --git a/src/EFCore/Diagnostics/WarningsConfigurationBuilder.cs b/src/EFCore/Diagnostics/WarningsConfigurationBuilder.cs index 98de024f4bc..6f65b72b7e8 100644 --- a/src/EFCore/Diagnostics/WarningsConfigurationBuilder.cs +++ b/src/EFCore/Diagnostics/WarningsConfigurationBuilder.cs @@ -26,9 +26,7 @@ public class WarningsConfigurationBuilder /// /// The options builder to which the warnings configuration will be applied. public WarningsConfigurationBuilder(DbContextOptionsBuilder optionsBuilder) - { - _optionsBuilder = optionsBuilder; - } + => _optionsBuilder = optionsBuilder; /// /// Sets the default behavior when a warning is generated. diff --git a/src/EFCore/EF.CompileAsyncQuery.cs b/src/EFCore/EF.CompileAsyncQuery.cs index 290b8eb8af7..10f8afb663c 100644 --- a/src/EFCore/EF.CompileAsyncQuery.cs +++ b/src/EFCore/EF.CompileAsyncQuery.cs @@ -1,1320 +1,1392 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -// -using System; -using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Linq.Expressions; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore.Query; using Microsoft.EntityFrameworkCore.Query.Internal; -namespace Microsoft.EntityFrameworkCore +namespace Microsoft.EntityFrameworkCore; + +public static partial class EF { - public static partial class EF - { - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, - [DynamicallyAccessedMembers(IEntityType.DynamicallyAccessedMemberTypes)] TResult>( - Expression>> queryExpression) - where TContext : DbContext - where TResult : class - => new CompiledAsyncEnumerableQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The query result type. - /// The included property type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledAsyncEnumerableQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledAsyncEnumerableQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery( - Expression> queryExpression) - where TContext : DbContext - => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery( - Expression> queryExpression) - where TContext : DbContext - => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The query result type. - /// The included property type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledAsyncEnumerableQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledAsyncEnumerableQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery( - Expression> queryExpression) - where TContext : DbContext - => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery( - Expression> queryExpression) - where TContext : DbContext - => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The query result type. - /// The included property type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledAsyncEnumerableQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledAsyncEnumerableQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery( - Expression> queryExpression) - where TContext : DbContext - => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery( - Expression> queryExpression) - where TContext : DbContext - => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The query result type. - /// The included property type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TResult, TProperty>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledAsyncEnumerableQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TResult>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledAsyncEnumerableQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery( - Expression> queryExpression) - where TContext : DbContext - => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery( - Expression> queryExpression) - where TContext : DbContext - => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The query result type. - /// The included property type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TResult, TProperty>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledAsyncEnumerableQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TResult>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledAsyncEnumerableQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The query result type. - /// The included property type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TResult, TProperty>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledAsyncEnumerableQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TResult>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledAsyncEnumerableQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The query result type. - /// The included property type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TResult, TProperty>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledAsyncEnumerableQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TResult>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledAsyncEnumerableQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The query result type. - /// The included property type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, + [DynamicallyAccessedMembers(IEntityType.DynamicallyAccessedMemberTypes)] TResult>( + Expression>> queryExpression) + where TContext : DbContext + where TResult : class + => new CompiledAsyncEnumerableQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The query result type. + /// The included property type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledAsyncEnumerableQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledAsyncEnumerableQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery( + Expression> queryExpression) + where TContext : DbContext + => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery( + Expression> queryExpression) + where TContext : DbContext + => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The query result type. + /// The included property type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledAsyncEnumerableQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledAsyncEnumerableQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery( + Expression> queryExpression) + where TContext : DbContext + => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery( + Expression> queryExpression) + where TContext : DbContext + => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The query result type. + /// The included property type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledAsyncEnumerableQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledAsyncEnumerableQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery( + Expression> queryExpression) + where TContext : DbContext + => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery( + Expression> queryExpression) + where TContext : DbContext + => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The query result type. + /// The included property type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TResult, TProperty>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledAsyncEnumerableQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TResult>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledAsyncEnumerableQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery( + Expression> queryExpression) + where TContext : DbContext + => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery( + Expression> queryExpression) + where TContext : DbContext + => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The query result type. + /// The included property type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TResult, TProperty>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledAsyncEnumerableQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TResult>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledAsyncEnumerableQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TResult>( + Expression> queryExpression) + where TContext : DbContext + => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TResult>( + Expression> queryExpression) + where TContext : DbContext + => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The query result type. + /// The included property type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TResult, TProperty>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledAsyncEnumerableQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TResult>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledAsyncEnumerableQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TResult>( + Expression> queryExpression) + where TContext : DbContext + => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TResult>( + Expression> queryExpression) + where TContext : DbContext + => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The query result type. + /// The included property type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TResult, TProperty>( + Expression>> + queryExpression) + where TContext : DbContext + => new CompiledAsyncEnumerableQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TResult>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledAsyncEnumerableQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TResult>( + Expression> queryExpression) + where TContext : DbContext + => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TResult>( + Expression> queryExpression) + where TContext : DbContext + => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The query result type. + /// The included property type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> + CompileAsyncQuery< TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TResult, TProperty>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledAsyncEnumerableQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< + Expression>> + queryExpression) + where TContext : DbContext + => new CompiledAsyncEnumerableQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> + CompileAsyncQuery< TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TResult>( Expression>> queryExpression) - where TContext : DbContext - => new CompiledAsyncEnumerableQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< + where TContext : DbContext + => new CompiledAsyncEnumerableQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TResult>( + Expression> queryExpression) + where TContext : DbContext + => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> + CompileAsyncQuery< TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The query result type. - /// The included property type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< + Expression> + queryExpression) + where TContext : DbContext + => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The query result type. + /// The included property type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> + CompileAsyncQuery< TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TResult, TProperty>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledAsyncEnumerableQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TResult>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledAsyncEnumerableQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< + Expression>> queryExpression) + where TContext : DbContext + => new CompiledAsyncEnumerableQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> + CompileAsyncQuery< TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< + Expression>> + queryExpression) + where TContext : DbContext + => new CompiledAsyncEnumerableQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TResult>( + Expression> queryExpression) + where TContext : DbContext + => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> + CompileAsyncQuery< TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The query result type. - /// The included property type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< + Expression> + queryExpression) + where TContext : DbContext + => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The query result type. + /// The included property type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> + CompileAsyncQuery< TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TResult, TProperty>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledAsyncEnumerableQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< + Expression>> queryExpression) + where TContext : DbContext + => new CompiledAsyncEnumerableQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> + CompileAsyncQuery< TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TResult>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledAsyncEnumerableQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< + Expression>> + queryExpression) + where TContext : DbContext + => new CompiledAsyncEnumerableQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> + CompileAsyncQuery< TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The query result type. - /// The included property type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TResult, TProperty>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledAsyncEnumerableQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TResult>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledAsyncEnumerableQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< + Expression> + queryExpression) + where TContext : DbContext + => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TResult>( + Expression> queryExpression) + where TContext : DbContext + => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The query result type. + /// The included property type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TResult, TProperty>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledAsyncEnumerableQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TResult>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledAsyncEnumerableQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> + CompileAsyncQuery< TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The query result type. - /// The included property type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TResult, TProperty>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledAsyncEnumerableQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TResult>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledAsyncEnumerableQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The type of the twelfth query parameter. - /// The query result type. - /// The included property type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TResult, TProperty>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledAsyncEnumerableQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The type of the twelfth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TResult>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledAsyncEnumerableQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The type of the twelfth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The type of the twelfth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The type of the twelfth query parameter. - /// The type of the thirteenth query parameter. - /// The query result type. - /// The included property type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, TResult, TProperty>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledAsyncEnumerableQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The type of the twelfth query parameter. - /// The type of the thirteenth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, TResult>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledAsyncEnumerableQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The type of the twelfth query parameter. - /// The type of the thirteenth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The type of the twelfth query parameter. - /// The type of the thirteenth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The type of the twelfth query parameter. - /// The type of the thirteenth query parameter. - /// The type of the fourteenth query parameter. - /// The query result type. - /// The included property type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, TParam14, TResult, TProperty>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledAsyncEnumerableQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The type of the twelfth query parameter. - /// The type of the thirteenth query parameter. - /// The type of the fourteenth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, TParam14, TResult>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledAsyncEnumerableQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The type of the twelfth query parameter. - /// The type of the thirteenth query parameter. - /// The type of the fourteenth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, TParam14, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The type of the twelfth query parameter. - /// The type of the thirteenth query parameter. - /// The type of the fourteenth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, TParam14, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The type of the twelfth query parameter. - /// The type of the thirteenth query parameter. - /// The type of the fourteenth query parameter. - /// The type of the fifteenth query parameter. - /// The query result type. - /// The included property type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, TParam14, TParam15, TResult, TProperty>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledAsyncEnumerableQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The type of the twelfth query parameter. - /// The type of the thirteenth query parameter. - /// The type of the fourteenth query parameter. - /// The type of the fifteenth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, TParam14, TParam15, TResult>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledAsyncEnumerableQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The type of the twelfth query parameter. - /// The type of the thirteenth query parameter. - /// The type of the fourteenth query parameter. - /// The type of the fifteenth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileAsyncQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, TParam14, TParam15, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; - } + Expression> + queryExpression) + where TContext : DbContext + => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TResult>( + Expression> queryExpression) + where TContext : DbContext + => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The query result type. + /// The included property type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TResult, TProperty>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledAsyncEnumerableQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TResult>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledAsyncEnumerableQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TResult>( + Expression> queryExpression) + where TContext : DbContext + => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TResult>( + Expression> queryExpression) + where TContext : DbContext + => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The type of the twelfth query parameter. + /// The query result type. + /// The included property type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TResult, + TProperty>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledAsyncEnumerableQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The type of the twelfth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TResult>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledAsyncEnumerableQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The type of the twelfth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TResult>( + Expression> queryExpression) + where TContext : DbContext + => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The type of the twelfth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TResult>( + Expression> queryExpression) + where TContext : DbContext + => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The type of the twelfth query parameter. + /// The type of the thirteenth query parameter. + /// The query result type. + /// The included property type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, + TResult, TProperty>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledAsyncEnumerableQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The type of the twelfth query parameter. + /// The type of the thirteenth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, + TResult>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledAsyncEnumerableQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The type of the twelfth query parameter. + /// The type of the thirteenth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, + TResult>( + Expression> queryExpression) + where TContext : DbContext + => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The type of the twelfth query parameter. + /// The type of the thirteenth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, + TResult>( + Expression> queryExpression) + where TContext : DbContext + => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The type of the twelfth query parameter. + /// The type of the thirteenth query parameter. + /// The type of the fourteenth query parameter. + /// The query result type. + /// The included property type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, + TParam14, TResult, TProperty>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledAsyncEnumerableQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The type of the twelfth query parameter. + /// The type of the thirteenth query parameter. + /// The type of the fourteenth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, + TParam14, TResult>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledAsyncEnumerableQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The type of the twelfth query parameter. + /// The type of the thirteenth query parameter. + /// The type of the fourteenth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, + TParam14, TResult>( + Expression> queryExpression) + where TContext : DbContext + => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The type of the twelfth query parameter. + /// The type of the thirteenth query parameter. + /// The type of the fourteenth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, + TParam14, TResult>( + Expression> queryExpression) + where TContext : DbContext + => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The type of the twelfth query parameter. + /// The type of the thirteenth query parameter. + /// The type of the fourteenth query parameter. + /// The type of the fifteenth query parameter. + /// The query result type. + /// The included property type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, + TParam14, TParam15, TResult, TProperty>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledAsyncEnumerableQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The type of the twelfth query parameter. + /// The type of the thirteenth query parameter. + /// The type of the fourteenth query parameter. + /// The type of the fifteenth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, + TParam14, TParam15, TResult>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledAsyncEnumerableQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The type of the twelfth query parameter. + /// The type of the thirteenth query parameter. + /// The type of the fourteenth query parameter. + /// The type of the fifteenth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileAsyncQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, + TParam14, TParam15, TResult>( + Expression> queryExpression) + where TContext : DbContext + => new CompiledAsyncTaskQuery(queryExpression).ExecuteAsync; } diff --git a/src/EFCore/EF.CompileQuery.cs b/src/EFCore/EF.CompileQuery.cs index 12435aae6da..0afd2e5292f 100644 --- a/src/EFCore/EF.CompileQuery.cs +++ b/src/EFCore/EF.CompileQuery.cs @@ -1,1014 +1,1067 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -// using Microsoft.EntityFrameworkCore.Query.Internal; -namespace Microsoft.EntityFrameworkCore +namespace Microsoft.EntityFrameworkCore; + +public static partial class EF { - public static partial class EF - { - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileQuery( - Expression>> queryExpression) - where TContext : DbContext - where TResult : class - => new CompiledQuery>(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The query result type. - /// The included property type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileQuery( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledQuery>(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileQuery( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledQuery>(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func CompileQuery( - Expression> queryExpression) - where TContext : DbContext - => new CompiledQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The query result type. - /// The included property type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileQuery( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledQuery>(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileQuery( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledQuery>(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func CompileQuery( - Expression> queryExpression) - where TContext : DbContext - => new CompiledQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The query result type. - /// The included property type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileQuery( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledQuery>(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileQuery( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledQuery>(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func CompileQuery( - Expression> queryExpression) - where TContext : DbContext - => new CompiledQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The query result type. - /// The included property type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileQuery< - TContext, TParam1, TParam2, TParam3, TResult, TProperty>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledQuery>(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileQuery< - TContext, TParam1, TParam2, TParam3, TResult>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledQuery>(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func CompileQuery( - Expression> queryExpression) - where TContext : DbContext - => new CompiledQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The query result type. - /// The included property type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TResult, TProperty>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledQuery>(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TResult>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledQuery>(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func CompileQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The query result type. - /// The included property type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TResult, TProperty>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledQuery>(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TResult>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledQuery>(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func CompileQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The query result type. - /// The included property type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TResult, TProperty>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledQuery>(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TResult>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledQuery>(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func CompileQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The query result type. - /// The included property type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TResult, TProperty>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledQuery>(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TResult>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledQuery>(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func CompileQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The query result type. - /// The included property type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TResult, TProperty>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledQuery>(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TResult>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledQuery>(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func CompileQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The query result type. - /// The included property type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileQuery< + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileQuery( + Expression>> queryExpression) + where TContext : DbContext + where TResult : class + => new CompiledQuery>(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The query result type. + /// The included property type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileQuery( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledQuery>(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileQuery( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledQuery>(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func CompileQuery( + Expression> queryExpression) + where TContext : DbContext + => new CompiledQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The query result type. + /// The included property type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileQuery( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledQuery>(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileQuery( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledQuery>(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func CompileQuery( + Expression> queryExpression) + where TContext : DbContext + => new CompiledQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The query result type. + /// The included property type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileQuery( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledQuery>(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileQuery( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledQuery>(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func CompileQuery( + Expression> queryExpression) + where TContext : DbContext + => new CompiledQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The query result type. + /// The included property type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileQuery< + TContext, TParam1, TParam2, TParam3, TResult, TProperty>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledQuery>(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileQuery< + TContext, TParam1, TParam2, TParam3, TResult>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledQuery>(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func CompileQuery( + Expression> queryExpression) + where TContext : DbContext + => new CompiledQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The query result type. + /// The included property type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TResult, TProperty>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledQuery>(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TResult>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledQuery>(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func CompileQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TResult>( + Expression> queryExpression) + where TContext : DbContext + => new CompiledQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The query result type. + /// The included property type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TResult, TProperty>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledQuery>(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TResult>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledQuery>(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func CompileQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TResult>( + Expression> queryExpression) + where TContext : DbContext + => new CompiledQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The query result type. + /// The included property type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TResult, TProperty>( + Expression>> + queryExpression) + where TContext : DbContext + => new CompiledQuery>(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TResult>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledQuery>(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func CompileQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TResult>( + Expression> queryExpression) + where TContext : DbContext + => new CompiledQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The query result type. + /// The included property type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TResult, TProperty>( + Expression>> + queryExpression) + where TContext : DbContext + => new CompiledQuery>(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TResult>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledQuery>(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func CompileQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TResult>( + Expression> queryExpression) + where TContext : DbContext + => new CompiledQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The query result type. + /// The included property type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TResult, TProperty>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledQuery>(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TResult>( + Expression>> + queryExpression) + where TContext : DbContext + => new CompiledQuery>(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func CompileQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TResult>( + Expression> queryExpression) + where TContext : DbContext + => new CompiledQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The query result type. + /// The included property type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> + CompileQuery< TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TResult, TProperty>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledQuery>(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TResult>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledQuery>(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func CompileQuery< + Expression>> queryExpression) + where TContext : DbContext + => new CompiledQuery>(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> + CompileQuery< TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The query result type. - /// The included property type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TResult, TProperty>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledQuery>(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TResult>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledQuery>(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func CompileQuery< + Expression>> + queryExpression) + where TContext : DbContext + => new CompiledQuery>(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func CompileQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TResult>( + Expression> + queryExpression) + where TContext : DbContext + => new CompiledQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The query result type. + /// The included property type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TResult, TProperty>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledQuery>(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TResult>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledQuery>(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func + CompileQuery< TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The query result type. - /// The included property type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TResult, TProperty>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledQuery>(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TResult>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledQuery>(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func CompileQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The type of the twelfth query parameter. - /// The query result type. - /// The included property type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TResult, TProperty>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledQuery>(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The type of the twelfth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TResult>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledQuery>(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The type of the twelfth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func CompileQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The type of the twelfth query parameter. - /// The type of the thirteenth query parameter. - /// The query result type. - /// The included property type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, TResult, TProperty>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledQuery>(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The type of the twelfth query parameter. - /// The type of the thirteenth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, TResult>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledQuery>(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The type of the twelfth query parameter. - /// The type of the thirteenth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func CompileQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The type of the twelfth query parameter. - /// The type of the thirteenth query parameter. - /// The type of the fourteenth query parameter. - /// The query result type. - /// The included property type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, TParam14, TResult, TProperty>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledQuery>(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The type of the twelfth query parameter. - /// The type of the thirteenth query parameter. - /// The type of the fourteenth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, TParam14, TResult>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledQuery>(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The type of the twelfth query parameter. - /// The type of the thirteenth query parameter. - /// The type of the fourteenth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func CompileQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, TParam14, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledQuery(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The type of the twelfth query parameter. - /// The type of the thirteenth query parameter. - /// The type of the fourteenth query parameter. - /// The type of the fifteenth query parameter. - /// The query result type. - /// The included property type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, TParam14, TParam15, TResult, TProperty>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledQuery>(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The type of the twelfth query parameter. - /// The type of the thirteenth query parameter. - /// The type of the fourteenth query parameter. - /// The type of the fifteenth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func> CompileQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, TParam14, TParam15, TResult>( - Expression>> queryExpression) - where TContext : DbContext - => new CompiledQuery>(queryExpression).Execute; - - /// - /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. - /// - /// The target DbContext type. - /// The type of the first query parameter. - /// The type of the second query parameter. - /// The type of the third query parameter. - /// The type of the fourth query parameter. - /// The type of the fifth query parameter. - /// The type of the sixth query parameter. - /// The type of the seventh query parameter. - /// The type of the eighth query parameter. - /// The type of the ninth query parameter. - /// The type of the tenth query parameter. - /// The type of the eleventh query parameter. - /// The type of the twelfth query parameter. - /// The type of the thirteenth query parameter. - /// The type of the fourteenth query parameter. - /// The type of the fifteenth query parameter. - /// The query result type. - /// The LINQ query expression. - /// A delegate that can be invoked to execute the compiled query. - public static Func CompileQuery< - TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, TParam14, TParam15, TResult>( - Expression> queryExpression) - where TContext : DbContext - => new CompiledQuery(queryExpression).Execute; - } + Expression> + queryExpression) + where TContext : DbContext + => new CompiledQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The query result type. + /// The included property type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TResult, TProperty>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledQuery>(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TResult>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledQuery>(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func CompileQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TResult>( + Expression> queryExpression) + where TContext : DbContext + => new CompiledQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The type of the twelfth query parameter. + /// The query result type. + /// The included property type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TResult, + TProperty>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledQuery>(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The type of the twelfth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TResult>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledQuery>(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The type of the twelfth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func CompileQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TResult>( + Expression> queryExpression) + where TContext : DbContext + => new CompiledQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The type of the twelfth query parameter. + /// The type of the thirteenth query parameter. + /// The query result type. + /// The included property type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, + TResult, TProperty>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledQuery>(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The type of the twelfth query parameter. + /// The type of the thirteenth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, + TResult>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledQuery>(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The type of the twelfth query parameter. + /// The type of the thirteenth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func CompileQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, + TResult>( + Expression> queryExpression) + where TContext : DbContext + => new CompiledQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The type of the twelfth query parameter. + /// The type of the thirteenth query parameter. + /// The type of the fourteenth query parameter. + /// The query result type. + /// The included property type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, + TParam14, TResult, TProperty>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledQuery>(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The type of the twelfth query parameter. + /// The type of the thirteenth query parameter. + /// The type of the fourteenth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, + TParam14, TResult>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledQuery>(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The type of the twelfth query parameter. + /// The type of the thirteenth query parameter. + /// The type of the fourteenth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func CompileQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, + TParam14, TResult>( + Expression> queryExpression) + where TContext : DbContext + => new CompiledQuery(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The type of the twelfth query parameter. + /// The type of the thirteenth query parameter. + /// The type of the fourteenth query parameter. + /// The type of the fifteenth query parameter. + /// The query result type. + /// The included property type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, + TParam14, TParam15, TResult, TProperty>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledQuery>(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The type of the twelfth query parameter. + /// The type of the thirteenth query parameter. + /// The type of the fourteenth query parameter. + /// The type of the fifteenth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func> CompileQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, + TParam14, TParam15, TResult>( + Expression>> queryExpression) + where TContext : DbContext + => new CompiledQuery>(queryExpression).Execute; + + /// + /// Creates a compiled query delegate that when invoked will execute the specified LINQ query. + /// + /// The target DbContext type. + /// The type of the first query parameter. + /// The type of the second query parameter. + /// The type of the third query parameter. + /// The type of the fourth query parameter. + /// The type of the fifth query parameter. + /// The type of the sixth query parameter. + /// The type of the seventh query parameter. + /// The type of the eighth query parameter. + /// The type of the ninth query parameter. + /// The type of the tenth query parameter. + /// The type of the eleventh query parameter. + /// The type of the twelfth query parameter. + /// The type of the thirteenth query parameter. + /// The type of the fourteenth query parameter. + /// The type of the fifteenth query parameter. + /// The query result type. + /// The LINQ query expression. + /// A delegate that can be invoked to execute the compiled query. + public static Func CompileQuery< + TContext, TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9, TParam10, TParam11, TParam12, TParam13, + TParam14, TParam15, TResult>( + Expression> queryExpression) + where TContext : DbContext + => new CompiledQuery(queryExpression).Execute; } diff --git a/src/EFCore/EFCore.csproj b/src/EFCore/EFCore.csproj index f8ba3e739d9..ebd55af327c 100644 --- a/src/EFCore/EFCore.csproj +++ b/src/EFCore/EFCore.csproj @@ -46,13 +46,13 @@ Microsoft.EntityFrameworkCore.DbSet - - + + - + diff --git a/src/EFCore/Extensions/EntityFrameworkQueryableExtensions.cs b/src/EFCore/Extensions/EntityFrameworkQueryableExtensions.cs index bb03f831ead..088c5193dcf 100644 --- a/src/EFCore/Extensions/EntityFrameworkQueryableExtensions.cs +++ b/src/EFCore/Extensions/EntityFrameworkQueryableExtensions.cs @@ -2391,7 +2391,10 @@ public static async Task> ToHashSetAsync( /// /// The type of the elements of . /// An to create a set from. - /// The implementation to use when comparing values in the set, or null to use the default implementation for the set type. + /// + /// The implementation to use when comparing values in the set, or null to use the + /// default implementation for the set type. + /// /// A to observe while waiting for the task to complete. /// /// A task that represents the asynchronous operation. diff --git a/src/EFCore/Extensions/EntityFrameworkServiceCollectionExtensions.cs b/src/EFCore/Extensions/EntityFrameworkServiceCollectionExtensions.cs index ec8c8bd78f2..fc1c107aa2f 100644 --- a/src/EFCore/Extensions/EntityFrameworkServiceCollectionExtensions.cs +++ b/src/EFCore/Extensions/EntityFrameworkServiceCollectionExtensions.cs @@ -470,13 +470,6 @@ public static IServiceCollection AddDbContext /// and examples. /// /// - /// Entity Framework Core does not support multiple parallel operations being run on the same - /// instance. This includes both parallel execution of async queries and any explicit concurrent use from multiple threads. - /// Therefore, always await async calls immediately, or use separate DbContext instances for operations that execute - /// in parallel. See Avoiding DbContext threading issues for more information - /// and examples. - /// - /// /// See Using DbContext with dependency injection for more information and examples. /// /// diff --git a/src/EFCore/Infrastructure/AnnotatableBase.cs b/src/EFCore/Infrastructure/AnnotatableBase.cs index 8762e07d55d..d2c6020bf55 100644 --- a/src/EFCore/Infrastructure/AnnotatableBase.cs +++ b/src/EFCore/Infrastructure/AnnotatableBase.cs @@ -178,11 +178,7 @@ public virtual void SetAnnotation(string name, object? value) { Check.NotEmpty(name, nameof(name)); - return _annotations == null - ? null - : _annotations.TryGetValue(name, out var annotation) - ? annotation - : null; + return _annotations?.GetValueOrDefault(name); } /// @@ -389,11 +385,7 @@ public virtual TValue GetOrAddRuntimeAnnotationValue( { Check.NotEmpty(name, nameof(name)); - return _runtimeAnnotations == null - ? null - : _runtimeAnnotations.TryGetValue(name, out var annotation) - ? annotation - : null; + return _runtimeAnnotations?.GetValueOrDefault(name); } /// diff --git a/src/EFCore/Infrastructure/ConcurrencyDetectorCriticalSectionDisposer.cs b/src/EFCore/Infrastructure/ConcurrencyDetectorCriticalSectionDisposer.cs index ee14cba09bd..1094ad8580d 100644 --- a/src/EFCore/Infrastructure/ConcurrencyDetectorCriticalSectionDisposer.cs +++ b/src/EFCore/Infrastructure/ConcurrencyDetectorCriticalSectionDisposer.cs @@ -22,9 +22,7 @@ namespace Microsoft.EntityFrameworkCore.Infrastructure; /// The on which the critical section will be exited. /// public ConcurrencyDetectorCriticalSectionDisposer(IConcurrencyDetector concurrencyDetector) - { - _concurrencyDetector = concurrencyDetector; - } + => _concurrencyDetector = concurrencyDetector; /// public void Dispose() diff --git a/src/EFCore/Infrastructure/CoreOptionsExtension.cs b/src/EFCore/Infrastructure/CoreOptionsExtension.cs index 02d7a2c4161..3c87a8f759b 100644 --- a/src/EFCore/Infrastructure/CoreOptionsExtension.cs +++ b/src/EFCore/Infrastructure/CoreOptionsExtension.cs @@ -42,6 +42,8 @@ public class CoreOptionsExtension : IDbContextOptionsExtension private DbContextOptionsExtensionInfo? _info; private IEnumerable? _interceptors; private IEnumerable? _singletonInterceptors; + private Action? _seed; + private Func? _seedAsync; private static readonly TimeSpan DefaultLoggingCacheTime = TimeSpan.FromSeconds(1); @@ -85,6 +87,8 @@ protected CoreOptionsExtension(CoreOptionsExtension copyFrom) _serviceProviderCachingEnabled = copyFrom.ServiceProviderCachingEnabled; _interceptors = copyFrom.Interceptors?.ToList(); _singletonInterceptors = copyFrom.SingletonInterceptors?.ToList(); + _seed = copyFrom._seed; + _seedAsync = copyFrom._seedAsync; if (copyFrom._replacedServices != null) { @@ -407,6 +411,36 @@ public virtual CoreOptionsExtension WithSingletonInterceptors(IEnumerable + /// Creates a new instance with all options the same as for this instance, but with the given option changed. + /// It is unusual to call this method directly. Instead use . + /// + /// The option to change. + /// A new instance with the option changed. + public virtual CoreOptionsExtension WithSeeding(Action seed) + { + var clone = Clone(); + + clone._seed = seed; + + return clone; + } + + /// + /// Creates a new instance with all options the same as for this instance, but with the given option changed. + /// It is unusual to call this method directly. Instead use . + /// + /// The option to change. + /// A new instance with the option changed. + public virtual CoreOptionsExtension WithAsyncSeeding(Func seedAsync) + { + var clone = Clone(); + + clone._seedAsync = seedAsync; + + return clone; + } + /// /// The option set from the method. /// @@ -529,6 +563,24 @@ public virtual IEnumerable? Interceptors public virtual IEnumerable? SingletonInterceptors => _singletonInterceptors; + /// + /// The option set from the + /// + /// method. + /// + public virtual Action? Seeder + => _seed; + + /// + /// The option set from the + /// + /// method. + /// + public virtual Func? AsyncSeeder + => _seedAsync; + /// /// Adds the services required to make the selected options work. This is used when there /// is no external and EF is maintaining its own service diff --git a/src/EFCore/Infrastructure/DatabaseFacade.cs b/src/EFCore/Infrastructure/DatabaseFacade.cs index 893ae4b880f..e370468294f 100644 --- a/src/EFCore/Infrastructure/DatabaseFacade.cs +++ b/src/EFCore/Infrastructure/DatabaseFacade.cs @@ -24,9 +24,7 @@ public class DatabaseFacade : IInfrastructure, IDatabaseFacade /// /// The context this database API belongs to. public DatabaseFacade(DbContext context) - { - _context = context; - } + => _context = context; private IDatabaseFacadeDependencies Dependencies => _dependencies ??= _context.GetService(); diff --git a/src/EFCore/Infrastructure/DbContextOptionsExtensionInfo.cs b/src/EFCore/Infrastructure/DbContextOptionsExtensionInfo.cs index e841410cd88..a853b368273 100644 --- a/src/EFCore/Infrastructure/DbContextOptionsExtensionInfo.cs +++ b/src/EFCore/Infrastructure/DbContextOptionsExtensionInfo.cs @@ -22,9 +22,7 @@ public abstract class DbContextOptionsExtensionInfo /// /// The extension. protected DbContextOptionsExtensionInfo(IDbContextOptionsExtension extension) - { - Extension = extension; - } + => Extension = extension; /// /// The extension for which this instance contains metadata. diff --git a/src/EFCore/Infrastructure/EntityFrameworkEventSource.cs b/src/EFCore/Infrastructure/EntityFrameworkEventSource.cs index 9459240dadf..74a5737e99a 100644 --- a/src/EFCore/Infrastructure/EntityFrameworkEventSource.cs +++ b/src/EFCore/Infrastructure/EntityFrameworkEventSource.cs @@ -126,43 +126,32 @@ protected override void OnEventCommand(EventCommandEventArgs command) _activeDbContextsCounter ??= new PollingCounter( "active-db-contexts", this, - () => EntityFrameworkMetricsData.GetActiveDbContexts()) - { - DisplayName = "Active DbContexts" - }; + () => EntityFrameworkMetricsData.GetActiveDbContexts()) { DisplayName = "Active DbContexts" }; _totalQueriesCounter ??= new PollingCounter( "total-queries", this, - () => EntityFrameworkMetricsData.GetTotalQueriesExecuted()) - { - DisplayName = "Queries (Total)" - }; + () => EntityFrameworkMetricsData.GetTotalQueriesExecuted()) { DisplayName = "Queries (Total)" }; _queriesPerSecondCounter ??= new IncrementingPollingCounter( "queries-per-second", this, () => EntityFrameworkMetricsData.GetTotalQueriesExecuted()) { - DisplayName = "Queries", - DisplayRateTimeScale = TimeSpan.FromSeconds(1) + DisplayName = "Queries", DisplayRateTimeScale = TimeSpan.FromSeconds(1) }; _totalSaveChangesCounter ??= new PollingCounter( "total-save-changes", this, - () => EntityFrameworkMetricsData.GetTotalSaveChanges()) - { - DisplayName = "SaveChanges (Total)" - }; + () => EntityFrameworkMetricsData.GetTotalSaveChanges()) { DisplayName = "SaveChanges (Total)" }; _saveChangesPerSecondCounter ??= new IncrementingPollingCounter( "save-changes-per-second", this, () => EntityFrameworkMetricsData.GetTotalSaveChanges()) { - DisplayName = "SaveChanges", - DisplayRateTimeScale = TimeSpan.FromSeconds(1) + DisplayName = "SaveChanges", DisplayRateTimeScale = TimeSpan.FromSeconds(1) }; _compiledQueryCacheHitRateCounter ??= new PollingCounter( @@ -170,8 +159,7 @@ protected override void OnEventCommand(EventCommandEventArgs command) this, () => EntityFrameworkMetricsData.GetCompiledQueryCacheHitRateEventSource().hitRate) { - DisplayName = "Query Cache Hit Rate", - DisplayUnits = "%" + DisplayName = "Query Cache Hit Rate", DisplayUnits = "%" }; _totalExecutionStrategyOperationFailuresCounter ??= new PollingCounter( @@ -187,8 +175,7 @@ protected override void OnEventCommand(EventCommandEventArgs command) this, () => EntityFrameworkMetricsData.GetTotalExecutionStrategyOperationFailures()) { - DisplayName = "Execution Strategy Operation Failures", - DisplayRateTimeScale = TimeSpan.FromSeconds(1) + DisplayName = "Execution Strategy Operation Failures", DisplayRateTimeScale = TimeSpan.FromSeconds(1) }; _totalOptimisticConcurrencyFailuresCounter ??= new PollingCounter( @@ -204,8 +191,7 @@ protected override void OnEventCommand(EventCommandEventArgs command) this, () => EntityFrameworkMetricsData.GetTotalOptimisticConcurrencyFailures()) { - DisplayName = "Optimistic Concurrency Failures", - DisplayRateTimeScale = TimeSpan.FromSeconds(1) + DisplayName = "Optimistic Concurrency Failures", DisplayRateTimeScale = TimeSpan.FromSeconds(1) }; } } diff --git a/src/EFCore/Infrastructure/EntityFrameworkMetricsData.cs b/src/EFCore/Infrastructure/EntityFrameworkMetricsData.cs index 5bd6a6aa176..055d1a3056d 100644 --- a/src/EFCore/Infrastructure/EntityFrameworkMetricsData.cs +++ b/src/EFCore/Infrastructure/EntityFrameworkMetricsData.cs @@ -33,49 +33,49 @@ public static class EntityFrameworkMetricsData private static CacheInfo _compiledQueryCacheInfoEventSource; /// - /// Indicates that a new instance is being initialized. + /// Indicates that a new instance is being initialized. /// public static void ReportDbContextInitializing() => Interlocked.Increment(ref _activeDbContexts); /// - /// Indicates that a instance is being disposed. + /// Indicates that a instance is being disposed. /// public static void ReportDbContextDisposing() => Interlocked.Decrement(ref _activeDbContexts); /// - /// Number of currently active instances. + /// Number of currently active instances. /// internal static int GetActiveDbContexts() => Volatile.Read(ref _activeDbContexts); /// - /// Indicates that a query is about to begin execution. + /// Indicates that a query is about to begin execution. /// public static void ReportQueryExecuting() => Interlocked.Increment(ref _totalQueriesExecuted); /// - /// Cumulative count of queries executed. + /// Cumulative count of queries executed. /// internal static long GetTotalQueriesExecuted() => Interlocked.Read(ref _totalQueriesExecuted); /// - /// Indicates that changes are about to be saved. + /// Indicates that changes are about to be saved. /// public static void ReportSavingChanges() => Interlocked.Increment(ref _totalSaveChanges); /// - /// Cumulative count of changes saved. + /// Cumulative count of changes saved. /// internal static long GetTotalSaveChanges() => Interlocked.Read(ref _totalSaveChanges); /// - /// Indicates a hit in the compiled query cache, signifying that query compilation will not need to occur. + /// Indicates a hit in the compiled query cache, signifying that query compilation will not need to occur. /// public static void ReportCompiledQueryCacheHit() { @@ -84,7 +84,7 @@ public static void ReportCompiledQueryCacheHit() } /// - /// Indicates a miss in the compiled query cache, signifying that query compilation will need to occur. + /// Indicates a miss in the compiled query cache, signifying that query compilation will need to occur. /// public static void ReportCompiledQueryCacheMiss() { @@ -93,37 +93,37 @@ public static void ReportCompiledQueryCacheMiss() } /// - /// Gets number of hits and misses and also the computed hit rate for the compiled query cache. + /// Gets number of hits and misses and also the computed hit rate for the compiled query cache. /// internal static (int hits, int misses, double hitRate) GetCompiledQueryCacheHitRate() => _compiledQueryCacheInfo.CalculateHitsMissesHitRate(false); /// - /// Gets number of hits and misses and also the computed hit rate for the compiled query cache. + /// Gets number of hits and misses and also the computed hit rate for the compiled query cache. /// internal static (int hits, int misses, double hitRate) GetCompiledQueryCacheHitRateEventSource() => _compiledQueryCacheInfoEventSource.CalculateHitsMissesHitRate(true); /// - /// Indicates that an operation executed by an failed (and may be retried). + /// Indicates that an operation executed by an failed (and may be retried). /// public static void ReportExecutionStrategyOperationFailure() => Interlocked.Increment(ref _totalExecutionStrategyOperationFailures); /// - /// Cumulative number of failed operation executed by an . + /// Cumulative number of failed operation executed by an . /// internal static long GetTotalExecutionStrategyOperationFailures() => Interlocked.Read(ref _totalExecutionStrategyOperationFailures); /// - /// Indicates that an optimistic concurrency failure has occurred. + /// Indicates that an optimistic concurrency failure has occurred. /// public static void ReportOptimisticConcurrencyFailure() => Interlocked.Increment(ref _totalOptimisticConcurrencyFailures); /// - /// Cumulative number of optimistic concurrency failures. + /// Cumulative number of optimistic concurrency failures. /// internal static long GetTotalOptimisticConcurrencyFailures() => Interlocked.Read(ref _totalOptimisticConcurrencyFailures); @@ -159,7 +159,6 @@ private struct CacheInfo : ((double)cacheInfo.Hits / hitsAndMisses) * 100; return (cacheInfo.Hits, cacheInfo.Misses, hitRate); } - } } } diff --git a/src/EFCore/Infrastructure/EntityFrameworkServicesBuilder.cs b/src/EFCore/Infrastructure/EntityFrameworkServicesBuilder.cs index 07a3f4ec653..7504ced2ba0 100644 --- a/src/EFCore/Infrastructure/EntityFrameworkServicesBuilder.cs +++ b/src/EFCore/Infrastructure/EntityFrameworkServicesBuilder.cs @@ -131,7 +131,10 @@ public static readonly IDictionary CoreServices { typeof(ILazyLoaderFactory), new ServiceCharacteristics(ServiceLifetime.Scoped) }, { typeof(IParameterBindingFactory), new ServiceCharacteristics(ServiceLifetime.Singleton, multipleRegistrations: true) }, { typeof(ITypeMappingSourcePlugin), new ServiceCharacteristics(ServiceLifetime.Singleton, multipleRegistrations: true) }, - { typeof(IEvaluatableExpressionFilterPlugin), new ServiceCharacteristics(ServiceLifetime.Singleton, multipleRegistrations: true) }, + { + typeof(IEvaluatableExpressionFilterPlugin), + new ServiceCharacteristics(ServiceLifetime.Singleton, multipleRegistrations: true) + }, { typeof(ISingletonOptions), new ServiceCharacteristics(ServiceLifetime.Singleton, multipleRegistrations: true) }, { typeof(IConventionSetPlugin), new ServiceCharacteristics(ServiceLifetime.Scoped, multipleRegistrations: true) }, { typeof(ISingletonInterceptor), new ServiceCharacteristics(ServiceLifetime.Singleton, multipleRegistrations: true) }, @@ -151,9 +154,7 @@ public static readonly IDictionary CoreServices /// /// The collection to which services will be registered. public EntityFrameworkServicesBuilder(IServiceCollection serviceCollection) - { - ServiceCollectionMap = new ServiceCollectionMap(serviceCollection); - } + => ServiceCollectionMap = new ServiceCollectionMap(serviceCollection); /// /// Access to the underlying . diff --git a/src/EFCore/Infrastructure/IDbContextOptionsConfiguration.cs b/src/EFCore/Infrastructure/IDbContextOptionsConfiguration.cs index e835c36f959..9ca54bd66cb 100644 --- a/src/EFCore/Infrastructure/IDbContextOptionsConfiguration.cs +++ b/src/EFCore/Infrastructure/IDbContextOptionsConfiguration.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore.Infrastructure; /// /// Configures the options to be used by a . You normally call -/// +/// /// to register this class, it is not designed to be directly constructed in your application code. /// /// The type of the context these options apply to. diff --git a/src/EFCore/Infrastructure/Internal/CurrentDbContext.cs b/src/EFCore/Infrastructure/Internal/CurrentDbContext.cs index 5c7c0a1e0c7..5691417d651 100644 --- a/src/EFCore/Infrastructure/Internal/CurrentDbContext.cs +++ b/src/EFCore/Infrastructure/Internal/CurrentDbContext.cs @@ -20,9 +20,7 @@ public sealed class CurrentDbContext : ICurrentDbContext /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public CurrentDbContext(DbContext context) - { - Context = context; - } + => Context = context; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/Infrastructure/Internal/DbContextOptionsConfiguration.cs b/src/EFCore/Infrastructure/Internal/DbContextOptionsConfiguration.cs index 3e241b8a566..fe35e0ee65a 100644 --- a/src/EFCore/Infrastructure/Internal/DbContextOptionsConfiguration.cs +++ b/src/EFCore/Infrastructure/Internal/DbContextOptionsConfiguration.cs @@ -21,9 +21,7 @@ public class DbContextOptionsConfiguration : IDbContextOptionsConfigur /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public DbContextOptionsConfiguration(Action configure) - { - _configure = configure; - } + => _configure = configure; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/Infrastructure/Internal/LazyLoader.cs b/src/EFCore/Infrastructure/Internal/LazyLoader.cs index b2ea2ec93d9..6dd385600d3 100644 --- a/src/EFCore/Infrastructure/Internal/LazyLoader.cs +++ b/src/EFCore/Infrastructure/Internal/LazyLoader.cs @@ -46,7 +46,8 @@ public LazyLoader( public virtual void Injected(DbContext context, object entity, QueryTrackingBehavior? queryTrackingBehavior, ITypeBase structuralType) { _queryTrackingBehavior = queryTrackingBehavior; - _nonLazyNavigations ??= InitNavigationsMetadata(structuralType as IEntityType + _nonLazyNavigations ??= InitNavigationsMetadata( + structuralType as IEntityType ?? throw new NotImplementedException("Navigations on complex types are not supported")); } diff --git a/src/EFCore/Infrastructure/Internal/LazyLoaderFactory.cs b/src/EFCore/Infrastructure/Internal/LazyLoaderFactory.cs index 54fd56eeba7..efeca77ca9c 100644 --- a/src/EFCore/Infrastructure/Internal/LazyLoaderFactory.cs +++ b/src/EFCore/Infrastructure/Internal/LazyLoaderFactory.cs @@ -54,6 +54,7 @@ public void Dispose() { loader.Dispose(); } + _loaders.Clear(); } diff --git a/src/EFCore/Infrastructure/ModelCacheKey.cs b/src/EFCore/Infrastructure/ModelCacheKey.cs index cb216b9b1ba..cb400e0ec88 100644 --- a/src/EFCore/Infrastructure/ModelCacheKey.cs +++ b/src/EFCore/Infrastructure/ModelCacheKey.cs @@ -23,9 +23,7 @@ public class ModelCacheKey /// The context instance that this key is for. /// public ModelCacheKey(DbContext context) - { - _dbContextType = context.GetType(); - } + => _dbContextType = context.GetType(); /// /// Initializes a new instance of the class. diff --git a/src/EFCore/Infrastructure/ModelCacheKeyFactory.cs b/src/EFCore/Infrastructure/ModelCacheKeyFactory.cs index 0a8314148ec..68da067c5c0 100644 --- a/src/EFCore/Infrastructure/ModelCacheKeyFactory.cs +++ b/src/EFCore/Infrastructure/ModelCacheKeyFactory.cs @@ -25,9 +25,7 @@ public class ModelCacheKeyFactory : IModelCacheKeyFactory /// /// Parameter object containing dependencies for this service. public ModelCacheKeyFactory(ModelCacheKeyFactoryDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Infrastructure/ModelCustomizer.cs b/src/EFCore/Infrastructure/ModelCustomizer.cs index d416bc7b087..38a5ee56aaa 100644 --- a/src/EFCore/Infrastructure/ModelCustomizer.cs +++ b/src/EFCore/Infrastructure/ModelCustomizer.cs @@ -31,9 +31,7 @@ public class ModelCustomizer : IModelCustomizer /// /// Parameter object containing dependencies for this service. public ModelCustomizer(ModelCustomizerDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Infrastructure/ModelDependencies.cs b/src/EFCore/Infrastructure/ModelDependencies.cs index d0a4adc7142..650eabb262e 100644 --- a/src/EFCore/Infrastructure/ModelDependencies.cs +++ b/src/EFCore/Infrastructure/ModelDependencies.cs @@ -47,9 +47,7 @@ public sealed record ModelDependencies [EntityFrameworkInternal] public ModelDependencies( IDiagnosticsLogger logger) - { - Logger = logger; - } + => Logger = logger; /// /// Gets the logger. diff --git a/src/EFCore/Infrastructure/ModelRuntimeInitializer.cs b/src/EFCore/Infrastructure/ModelRuntimeInitializer.cs index 99b3902f136..eee799fd065 100644 --- a/src/EFCore/Infrastructure/ModelRuntimeInitializer.cs +++ b/src/EFCore/Infrastructure/ModelRuntimeInitializer.cs @@ -34,9 +34,7 @@ public class ModelRuntimeInitializer : IModelRuntimeInitializer /// /// The dependencies to use. public ModelRuntimeInitializer(ModelRuntimeInitializerDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Infrastructure/ModelSource.cs b/src/EFCore/Infrastructure/ModelSource.cs index acfeb24beb5..d1113d8bd27 100644 --- a/src/EFCore/Infrastructure/ModelSource.cs +++ b/src/EFCore/Infrastructure/ModelSource.cs @@ -37,9 +37,7 @@ public class ModelSource : IModelSource /// /// The dependencies to use. public ModelSource(ModelSourceDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. @@ -78,7 +76,8 @@ public virtual IModel GetModel( var designTimeKey = designTime ? cacheKey : Dependencies.ModelCacheKeyFactory.Create(context, designTime: true); var runtimeKey = designTime ? Dependencies.ModelCacheKeyFactory.Create(context, designTime: false) : cacheKey; - cache.Set(designTimeKey, designTimeModel, new MemoryCacheEntryOptions { Size = 150, Priority = CacheItemPriority.High }); + cache.Set( + designTimeKey, designTimeModel, new MemoryCacheEntryOptions { Size = 150, Priority = CacheItemPriority.High }); cache.Set(runtimeKey, runtimeModel, new MemoryCacheEntryOptions { Size = 100, Priority = CacheItemPriority.High }); model = designTime ? designTimeModel : runtimeModel; diff --git a/src/EFCore/Infrastructure/ModelValidator.cs b/src/EFCore/Infrastructure/ModelValidator.cs index e735af2fbcf..35d015c811f 100644 --- a/src/EFCore/Infrastructure/ModelValidator.cs +++ b/src/EFCore/Infrastructure/ModelValidator.cs @@ -33,9 +33,7 @@ public class ModelValidator : IModelValidator /// /// Parameter object containing dependencies for this service. public ModelValidator(ModelValidatorDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Infrastructure/ModelValidatorDependencies.cs b/src/EFCore/Infrastructure/ModelValidatorDependencies.cs index c8cdf12439a..21fee306f3a 100644 --- a/src/EFCore/Infrastructure/ModelValidatorDependencies.cs +++ b/src/EFCore/Infrastructure/ModelValidatorDependencies.cs @@ -48,9 +48,7 @@ public sealed record ModelValidatorDependencies /// [EntityFrameworkInternal] public ModelValidatorDependencies(IMemberClassifier memberClassifier) - { - MemberClassifier = memberClassifier; - } + => MemberClassifier = memberClassifier; /// /// The member classifier. diff --git a/src/EFCore/Infrastructure/PooledDbContextFactory.cs b/src/EFCore/Infrastructure/PooledDbContextFactory.cs index 773dcb66804..c99a8b878b9 100644 --- a/src/EFCore/Infrastructure/PooledDbContextFactory.cs +++ b/src/EFCore/Infrastructure/PooledDbContextFactory.cs @@ -35,9 +35,7 @@ public class PooledDbContextFactory<[DynamicallyAccessedMembers(DbContext.Dynami /// [EntityFrameworkInternal] public PooledDbContextFactory(IDbContextPool pool) - { - _pool = pool; - } + => _pool = pool; /// /// Initializes a new instance of the class. diff --git a/src/EFCore/Infrastructure/ServiceCollectionMap.cs b/src/EFCore/Infrastructure/ServiceCollectionMap.cs index affce788bcb..82639bfc533 100644 --- a/src/EFCore/Infrastructure/ServiceCollectionMap.cs +++ b/src/EFCore/Infrastructure/ServiceCollectionMap.cs @@ -31,9 +31,7 @@ public class ServiceCollectionMap : IInfrastructure /// The collection to work with. public ServiceCollectionMap(IServiceCollection serviceCollection) - { - _map = new InternalServiceCollectionMap(serviceCollection); - } + => _map = new InternalServiceCollectionMap(serviceCollection); /// /// The underlying . diff --git a/src/EFCore/Infrastructure/ServiceProviderAccessor.cs b/src/EFCore/Infrastructure/ServiceProviderAccessor.cs index 351da3f2396..412d1b44a3c 100644 --- a/src/EFCore/Infrastructure/ServiceProviderAccessor.cs +++ b/src/EFCore/Infrastructure/ServiceProviderAccessor.cs @@ -14,9 +14,7 @@ public class ServiceProviderAccessor /// /// The injected service provider. public ServiceProviderAccessor(IServiceProvider rootServiceProvider) - { - RootServiceProvider = rootServiceProvider; - } + => RootServiceProvider = rootServiceProvider; /// /// The injected service provider. diff --git a/src/EFCore/Internal/DbContextFactorySource.cs b/src/EFCore/Internal/DbContextFactorySource.cs index 897ff06315b..aa6629a2e3e 100644 --- a/src/EFCore/Internal/DbContextFactorySource.cs +++ b/src/EFCore/Internal/DbContextFactorySource.cs @@ -19,9 +19,7 @@ public class DbContextFactorySource : IDbContextFactorySource public DbContextFactorySource() - { - Factory = CreateActivator(); - } + => Factory = CreateActivator(); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/Internal/DbContextServices.cs b/src/EFCore/Internal/DbContextServices.cs index 63dc7a5b5c9..d7b3ddde953 100644 --- a/src/EFCore/Internal/DbContextServices.cs +++ b/src/EFCore/Internal/DbContextServices.cs @@ -89,10 +89,10 @@ private IModel CreateModel(bool designTime) || (designTime && !(modelFromOptions is Model))) { return RuntimeFeature.IsDynamicCodeSupported - ? dependencies.ModelSource.GetModel(_currentContext!.Context, dependencies, designTime) - : designTime - ? throw new InvalidOperationException(CoreStrings.NativeAotDesignTimeModel) - : throw new InvalidOperationException(CoreStrings.NativeAotNoCompiledModel); + ? dependencies.ModelSource.GetModel(_currentContext!.Context, dependencies, designTime) + : designTime + ? throw new InvalidOperationException(CoreStrings.NativeAotDesignTimeModel) + : throw new InvalidOperationException(CoreStrings.NativeAotNoCompiledModel); } var designTimeModel = dependencies.ModelRuntimeInitializer.Initialize( @@ -129,8 +129,9 @@ private IModel CreateModel(bool designTime) if (model != null) { - throw new InvalidOperationException(CoreStrings.CompiledModelDuplicateAttribute( - contextAssembly.FullName, contextType.DisplayName())); + throw new InvalidOperationException( + CoreStrings.CompiledModelDuplicateAttribute( + contextAssembly.FullName, contextType.DisplayName())); } model = (IModel)instanceProperty.GetValue(null)!; diff --git a/src/EFCore/Internal/ManyToManyLoaderFactory.cs b/src/EFCore/Internal/ManyToManyLoaderFactory.cs index 123174f8b38..e5a772b8fb0 100644 --- a/src/EFCore/Internal/ManyToManyLoaderFactory.cs +++ b/src/EFCore/Internal/ManyToManyLoaderFactory.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Metadata.Internal; namespace Microsoft.EntityFrameworkCore.Internal; diff --git a/src/EFCore/Internal/RegisteredServices.cs b/src/EFCore/Internal/RegisteredServices.cs index 8581b022f5a..f0436089559 100644 --- a/src/EFCore/Internal/RegisteredServices.cs +++ b/src/EFCore/Internal/RegisteredServices.cs @@ -18,9 +18,7 @@ public class RegisteredServices : IRegisteredServices /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public RegisteredServices(IEnumerable services) - { - Services = new HashSet(services); - } + => Services = new HashSet(services); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/Metadata/AdHocMapper.cs b/src/EFCore/Metadata/AdHocMapper.cs index bfefdce8136..73e041ca4ea 100644 --- a/src/EFCore/Metadata/AdHocMapper.cs +++ b/src/EFCore/Metadata/AdHocMapper.cs @@ -33,9 +33,7 @@ public class AdHocMapper : IAdHocMapper /// the constructor at any point in this process. /// public AdHocMapper(AdHocMapperDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Metadata/Builders/CollectionCollectionBuilder.cs b/src/EFCore/Metadata/Builders/CollectionCollectionBuilder.cs index d552774a446..85d3008cecc 100644 --- a/src/EFCore/Metadata/Builders/CollectionCollectionBuilder.cs +++ b/src/EFCore/Metadata/Builders/CollectionCollectionBuilder.cs @@ -463,6 +463,7 @@ protected virtual IMutableEntityType UsingEntity( { rightForeignKey = GetOrCreateSkipNavigationForeignKey((SkipNavigation)RightNavigation, newJoinEntityType); } + ((SkipNavigation)RightNavigation).Builder .HasForeignKey((ForeignKey)rightForeignKey, ConfigurationSource.Explicit); @@ -477,6 +478,7 @@ protected virtual IMutableEntityType UsingEntity( { leftForeignKey = GetOrCreateSkipNavigationForeignKey((SkipNavigation)LeftNavigation, newJoinEntityType); } + ((SkipNavigation)LeftNavigation).Builder .HasForeignKey((ForeignKey)leftForeignKey, ConfigurationSource.Explicit); diff --git a/src/EFCore/Metadata/Builders/DiscriminatorBuilder.cs b/src/EFCore/Metadata/Builders/DiscriminatorBuilder.cs index 1c1ed79cbfb..a191b5e0caf 100644 --- a/src/EFCore/Metadata/Builders/DiscriminatorBuilder.cs +++ b/src/EFCore/Metadata/Builders/DiscriminatorBuilder.cs @@ -24,9 +24,7 @@ public class DiscriminatorBuilder : IConventionDiscriminatorBuilder /// [EntityFrameworkInternal] public DiscriminatorBuilder(IMutableEntityType entityType) - { - EntityTypeBuilder = ((EntityType)entityType).Builder; - } + => EntityTypeBuilder = ((EntityType)entityType).Builder; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/Metadata/Builders/DiscriminatorBuilder`.cs b/src/EFCore/Metadata/Builders/DiscriminatorBuilder`.cs index 26ceb9e2bde..aaef601555b 100644 --- a/src/EFCore/Metadata/Builders/DiscriminatorBuilder`.cs +++ b/src/EFCore/Metadata/Builders/DiscriminatorBuilder`.cs @@ -22,9 +22,7 @@ public class DiscriminatorBuilder /// [EntityFrameworkInternal] public DiscriminatorBuilder(DiscriminatorBuilder builder) - { - Builder = builder; - } + => Builder = builder; private DiscriminatorBuilder Builder { get; } diff --git a/src/EFCore/Metadata/Builders/EntityTypeBuilder.cs b/src/EFCore/Metadata/Builders/EntityTypeBuilder.cs index 42f81db7f4f..53096d0c673 100644 --- a/src/EFCore/Metadata/Builders/EntityTypeBuilder.cs +++ b/src/EFCore/Metadata/Builders/EntityTypeBuilder.cs @@ -27,9 +27,7 @@ public class EntityTypeBuilder : IInfrastructure /// [EntityFrameworkInternal] public EntityTypeBuilder(IMutableEntityType entityType) - { - Builder = ((EntityType)entityType).Builder; - } + => Builder = ((EntityType)entityType).Builder; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -1148,7 +1146,8 @@ protected virtual ForeignKey HasOneBuilder( && skipNavigation.ForeignKey?.DeclaringEntityType == Builder.Metadata) { return navigationId.MemberInfo != null - ? skipNavigation.ForeignKey.Builder.HasNavigation(navigationId.MemberInfo, pointsToPrincipal: true, ConfigurationSource.Explicit) + ? skipNavigation.ForeignKey.Builder.HasNavigation( + navigationId.MemberInfo, pointsToPrincipal: true, ConfigurationSource.Explicit) !.Metadata : skipNavigation.ForeignKey.Builder.HasNavigation(navigationId.Name, pointsToPrincipal: true, ConfigurationSource.Explicit) !.Metadata; diff --git a/src/EFCore/Metadata/Builders/IndexBuilder.cs b/src/EFCore/Metadata/Builders/IndexBuilder.cs index 2000e3bfd8f..5bf9ffd3d4f 100644 --- a/src/EFCore/Metadata/Builders/IndexBuilder.cs +++ b/src/EFCore/Metadata/Builders/IndexBuilder.cs @@ -30,9 +30,7 @@ public class IndexBuilder : IInfrastructure /// [EntityFrameworkInternal] public IndexBuilder(IMutableIndex index) - { - Builder = ((Index)index).Builder; - } + => Builder = ((Index)index).Builder; /// /// The internal builder being used to configure the index. diff --git a/src/EFCore/Metadata/Builders/OwnedNavigationBuilder.cs b/src/EFCore/Metadata/Builders/OwnedNavigationBuilder.cs index 32ab3c987f0..330dceb2031 100644 --- a/src/EFCore/Metadata/Builders/OwnedNavigationBuilder.cs +++ b/src/EFCore/Metadata/Builders/OwnedNavigationBuilder.cs @@ -334,6 +334,23 @@ public virtual IndexBuilder HasIndex(params string[] propertyNames) DependentEntityType.Builder.HasIndex( Check.NotEmpty(propertyNames, nameof(propertyNames)), ConfigurationSource.Explicit)!.Metadata); + /// + /// Configures an index on the specified properties and with the given name. + /// If there is an existing index on the given list of properties and with + /// the given name, then the existing index will be returned for configuration. + /// + /// The names of the properties that make up the index. + /// The name to assign to the index. + /// An object that can be used to configure the index. + public virtual IndexBuilder HasIndex( + string[] propertyNames, + string name) + => new( + DependentEntityType.Builder.HasIndex( + Check.NotEmpty(propertyNames, nameof(propertyNames)), + Check.NotEmpty(name, nameof(name)), + ConfigurationSource.Explicit)!.Metadata); + /// /// Configures the relationship to the owner. /// diff --git a/src/EFCore/Metadata/Builders/OwnedNavigationBuilder`.cs b/src/EFCore/Metadata/Builders/OwnedNavigationBuilder`.cs index 2801970f893..7c316152070 100644 --- a/src/EFCore/Metadata/Builders/OwnedNavigationBuilder`.cs +++ b/src/EFCore/Metadata/Builders/OwnedNavigationBuilder`.cs @@ -200,6 +200,32 @@ public virtual IndexBuilder HasIndex(Expression + /// Configures an index on the specified properties with the given name. + /// If there is an existing index on the given list of properties and with + /// the given name, then the existing index will be returned for configuration. + /// + /// + /// + /// A lambda expression representing the property(s) to be included in the index + /// (blog => blog.Url). + /// + /// + /// If the index is made up of multiple properties then specify an anonymous type including the + /// properties (post => new { post.Title, post.BlogId }). + /// + /// + /// The name to assign to the index. + /// An object that can be used to configure the index. + public virtual IndexBuilder HasIndex( + Expression> indexExpression, + string name) + => new( + DependentEntityType.Builder.HasIndex( + Check.NotNull(indexExpression, nameof(indexExpression)).GetMemberAccessList(), + name, + ConfigurationSource.Explicit)!.Metadata); + /// /// Configures an index on the specified properties. If there is an existing index on the given /// set of properties, then the existing index will be returned for configuration. @@ -211,6 +237,23 @@ public virtual IndexBuilder HasIndex(Expression + /// Configures an index on the specified properties with the given name. + /// If there is an existing index on the given list of properties and with + /// the given name, then the existing index will be returned for configuration. + /// + /// The names of the properties that make up the index. + /// The name to assign to the index. + /// An object that can be used to configure the index. + public new virtual IndexBuilder HasIndex( + string[] propertyNames, + string name) + => new( + DependentEntityType.Builder.HasIndex( + Check.NotEmpty(propertyNames, nameof(propertyNames)), + name, + ConfigurationSource.Explicit)!.Metadata); + /// /// Configures the relationship to the owner. /// diff --git a/src/EFCore/Metadata/Builders/TriggerBuilder.cs b/src/EFCore/Metadata/Builders/TriggerBuilder.cs index 82d30986b62..8265725be86 100644 --- a/src/EFCore/Metadata/Builders/TriggerBuilder.cs +++ b/src/EFCore/Metadata/Builders/TriggerBuilder.cs @@ -16,9 +16,7 @@ public class TriggerBuilder : IInfrastructure /// /// The to configure. public TriggerBuilder(IMutableTrigger trigger) - { - InternalBuilder = ((Trigger)trigger).Builder; - } + => InternalBuilder = ((Trigger)trigger).Builder; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/Metadata/Conventions/BackingFieldConvention.cs b/src/EFCore/Metadata/Conventions/BackingFieldConvention.cs index aee327f35c4..74626da6e30 100644 --- a/src/EFCore/Metadata/Conventions/BackingFieldConvention.cs +++ b/src/EFCore/Metadata/Conventions/BackingFieldConvention.cs @@ -36,9 +36,7 @@ public class BackingFieldConvention : /// /// Parameter object containing dependencies for this convention. public BackingFieldConvention(ProviderConventionSetBuilderDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Metadata/Conventions/BaseTypeDiscoveryConvention.cs b/src/EFCore/Metadata/Conventions/BaseTypeDiscoveryConvention.cs index bea393e4ab2..5eab1c2511f 100644 --- a/src/EFCore/Metadata/Conventions/BaseTypeDiscoveryConvention.cs +++ b/src/EFCore/Metadata/Conventions/BaseTypeDiscoveryConvention.cs @@ -21,9 +21,7 @@ public class BaseTypeDiscoveryConvention : /// /// Parameter object containing dependencies for this convention. public BaseTypeDiscoveryConvention(ProviderConventionSetBuilderDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Metadata/Conventions/CascadeDeleteConvention.cs b/src/EFCore/Metadata/Conventions/CascadeDeleteConvention.cs index 6b10d41473f..701e7cd11a5 100644 --- a/src/EFCore/Metadata/Conventions/CascadeDeleteConvention.cs +++ b/src/EFCore/Metadata/Conventions/CascadeDeleteConvention.cs @@ -17,9 +17,7 @@ public class CascadeDeleteConvention : IForeignKeyAddedConvention, IForeignKeyRe /// /// Parameter object containing dependencies for this convention. public CascadeDeleteConvention(ProviderConventionSetBuilderDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Metadata/Conventions/ChangeTrackingStrategyConvention.cs b/src/EFCore/Metadata/Conventions/ChangeTrackingStrategyConvention.cs index 0f2632ead48..b17543cbae7 100644 --- a/src/EFCore/Metadata/Conventions/ChangeTrackingStrategyConvention.cs +++ b/src/EFCore/Metadata/Conventions/ChangeTrackingStrategyConvention.cs @@ -19,9 +19,7 @@ public class ChangeTrackingStrategyConvention : IModelFinalizingConvention /// /// Parameter object containing dependencies for this convention. public ChangeTrackingStrategyConvention(ProviderConventionSetBuilderDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Metadata/Conventions/ComplexPropertyDiscoveryConvention.cs b/src/EFCore/Metadata/Conventions/ComplexPropertyDiscoveryConvention.cs index 773be8ba4f7..9340bd467bc 100644 --- a/src/EFCore/Metadata/Conventions/ComplexPropertyDiscoveryConvention.cs +++ b/src/EFCore/Metadata/Conventions/ComplexPropertyDiscoveryConvention.cs @@ -51,7 +51,7 @@ public ComplexPropertyDiscoveryConvention( protected virtual bool UseAttributes { get; } /// - /// Discovers complex properties on the given structural type. + /// Discovers complex properties on the given structural type. /// /// The type for which the properties will be discovered. /// Additional information associated with convention execution. @@ -86,7 +86,9 @@ private void TryConfigureComplexProperty(MemberInfo? candidateMember, IConventio /// The type for which the properties will be discovered. /// The complex type. protected virtual bool IsCandidateComplexProperty( - MemberInfo memberInfo, IConventionTypeBase structuralType, [NotNullWhen(true)] out Type? targetClrType) + MemberInfo memberInfo, + IConventionTypeBase structuralType, + [NotNullWhen(true)] out Type? targetClrType) { if (!structuralType.IsInModel || structuralType.IsIgnored(memberInfo.Name) @@ -127,7 +129,7 @@ protected virtual IEnumerable GetMembers(IConventionTypeBase structu => structuralType is IConventionComplexType ? structuralType.GetRuntimeProperties().Values.Cast() .Concat(structuralType.GetRuntimeFields().Values) - : structuralType.GetRuntimeProperties().Values.Cast(); + : structuralType.GetRuntimeProperties().Values; /// public virtual void ProcessEntityTypeAdded( diff --git a/src/EFCore/Metadata/Conventions/ComplexTypeAttributeConvention.cs b/src/EFCore/Metadata/Conventions/ComplexTypeAttributeConvention.cs index 8e0d7c37e5e..947b1b6af10 100644 --- a/src/EFCore/Metadata/Conventions/ComplexTypeAttributeConvention.cs +++ b/src/EFCore/Metadata/Conventions/ComplexTypeAttributeConvention.cs @@ -3,7 +3,6 @@ using System.ComponentModel.DataAnnotations.Schema; using Microsoft.EntityFrameworkCore.Internal; -using Microsoft.EntityFrameworkCore.Metadata.Internal; namespace Microsoft.EntityFrameworkCore.Metadata.Conventions; diff --git a/src/EFCore/Metadata/Conventions/ConstructorBindingConvention.cs b/src/EFCore/Metadata/Conventions/ConstructorBindingConvention.cs index 747ae75a02a..5b972055af3 100644 --- a/src/EFCore/Metadata/Conventions/ConstructorBindingConvention.cs +++ b/src/EFCore/Metadata/Conventions/ConstructorBindingConvention.cs @@ -24,9 +24,7 @@ public class ConstructorBindingConvention : IModelFinalizingConvention /// /// Parameter object containing dependencies for this convention. public ConstructorBindingConvention(ProviderConventionSetBuilderDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Metadata/Conventions/DbSetFindingConvention.cs b/src/EFCore/Metadata/Conventions/DbSetFindingConvention.cs index 83c767a09e3..4a60cae1e48 100644 --- a/src/EFCore/Metadata/Conventions/DbSetFindingConvention.cs +++ b/src/EFCore/Metadata/Conventions/DbSetFindingConvention.cs @@ -17,9 +17,7 @@ public class DbSetFindingConvention : IModelInitializedConvention /// /// Parameter object containing dependencies for this convention. public DbSetFindingConvention(ProviderConventionSetBuilderDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Metadata/Conventions/DiscriminatorConvention.cs b/src/EFCore/Metadata/Conventions/DiscriminatorConvention.cs index 3abe5c2a6b5..67b68bbfdb0 100644 --- a/src/EFCore/Metadata/Conventions/DiscriminatorConvention.cs +++ b/src/EFCore/Metadata/Conventions/DiscriminatorConvention.cs @@ -19,16 +19,14 @@ public class DiscriminatorConvention : /// /// Parameter object containing dependencies for this convention. public DiscriminatorConvention(ProviderConventionSetBuilderDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. /// protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } - /// + /// public virtual void ProcessEntityTypeBaseTypeChanged( IConventionEntityTypeBuilder entityTypeBuilder, IConventionEntityType? newBaseType, @@ -75,7 +73,7 @@ public virtual void ProcessEntityTypeBaseTypeChanged( } } - /// + /// public virtual void ProcessDiscriminatorPropertySet( IConventionEntityTypeBuilder entityTypeBuilder, string? name, @@ -93,7 +91,7 @@ public virtual void ProcessDiscriminatorPropertySet( } } - /// + /// public virtual void ProcessEntityTypeRemoved( IConventionModelBuilder modelBuilder, IConventionEntityType entityType, diff --git a/src/EFCore/Metadata/Conventions/ElementMappingConvention.cs b/src/EFCore/Metadata/Conventions/ElementMappingConvention.cs index db99c9607c4..bb02b589115 100644 --- a/src/EFCore/Metadata/Conventions/ElementMappingConvention.cs +++ b/src/EFCore/Metadata/Conventions/ElementMappingConvention.cs @@ -18,9 +18,7 @@ public class ElementMappingConvention : IModelFinalizingConvention /// /// Parameter object containing dependencies for this convention. public ElementMappingConvention(ProviderConventionSetBuilderDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Metadata/Conventions/ElementTypeChangedConvention.cs b/src/EFCore/Metadata/Conventions/ElementTypeChangedConvention.cs index 2139e9ee857..0fa4c791da8 100644 --- a/src/EFCore/Metadata/Conventions/ElementTypeChangedConvention.cs +++ b/src/EFCore/Metadata/Conventions/ElementTypeChangedConvention.cs @@ -9,16 +9,15 @@ namespace Microsoft.EntityFrameworkCore.Metadata.Conventions; /// /// See Model building conventions for more information and examples. /// -public class ElementTypeChangedConvention : IPropertyElementTypeChangedConvention, IForeignKeyAddedConvention +public class ElementTypeChangedConvention : + IPropertyElementTypeChangedConvention, IForeignKeyAddedConvention, IForeignKeyPropertiesChangedConvention { /// /// Creates a new instance of . /// /// Parameter object containing dependencies for this convention. public ElementTypeChangedConvention(ProviderConventionSetBuilderDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. @@ -46,7 +45,24 @@ public void ProcessPropertyElementTypeChanged( /// public void ProcessForeignKeyAdded( - IConventionForeignKeyBuilder foreignKeyBuilder, IConventionContext context) + IConventionForeignKeyBuilder foreignKeyBuilder, + IConventionContext context) + => ProcessForeignKey(foreignKeyBuilder); + + /// + public void ProcessForeignKeyPropertiesChanged( + IConventionForeignKeyBuilder relationshipBuilder, + IReadOnlyList oldDependentProperties, + IConventionKey oldPrincipalKey, + IConventionContext> context) + { + if (relationshipBuilder.Metadata.IsInModel) + { + ProcessForeignKey(relationshipBuilder); + } + } + + private static void ProcessForeignKey(IConventionForeignKeyBuilder foreignKeyBuilder) { var foreignKeyProperties = foreignKeyBuilder.Metadata.Properties; var principalKeyProperties = foreignKeyBuilder.Metadata.PrincipalKey.Properties; diff --git a/src/EFCore/Metadata/Conventions/ForeignKeyAttributeConvention.cs b/src/EFCore/Metadata/Conventions/ForeignKeyAttributeConvention.cs index 62a146c784b..ead05b7b706 100644 --- a/src/EFCore/Metadata/Conventions/ForeignKeyAttributeConvention.cs +++ b/src/EFCore/Metadata/Conventions/ForeignKeyAttributeConvention.cs @@ -34,9 +34,7 @@ public class ForeignKeyAttributeConvention : /// /// Parameter object containing dependencies for this convention. public ForeignKeyAttributeConvention(ProviderConventionSetBuilderDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Metadata/Conventions/ForeignKeyIndexConvention.cs b/src/EFCore/Metadata/Conventions/ForeignKeyIndexConvention.cs index 266d9445c73..08b6e1357aa 100644 --- a/src/EFCore/Metadata/Conventions/ForeignKeyIndexConvention.cs +++ b/src/EFCore/Metadata/Conventions/ForeignKeyIndexConvention.cs @@ -29,9 +29,7 @@ public class ForeignKeyIndexConvention : /// /// Parameter object containing dependencies for this convention. public ForeignKeyIndexConvention(ProviderConventionSetBuilderDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Metadata/Conventions/ForeignKeyPropertyDiscoveryConvention.cs b/src/EFCore/Metadata/Conventions/ForeignKeyPropertyDiscoveryConvention.cs index 54f4480f72a..167605a09d2 100644 --- a/src/EFCore/Metadata/Conventions/ForeignKeyPropertyDiscoveryConvention.cs +++ b/src/EFCore/Metadata/Conventions/ForeignKeyPropertyDiscoveryConvention.cs @@ -55,9 +55,7 @@ public class ForeignKeyPropertyDiscoveryConvention : /// /// Parameter object containing dependencies for this convention. public ForeignKeyPropertyDiscoveryConvention(ProviderConventionSetBuilderDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Metadata/Conventions/IModelEmbeddedDiscriminatorNameConvention.cs b/src/EFCore/Metadata/Conventions/IModelEmbeddedDiscriminatorNameConvention.cs index 6e8d03b1252..421326a767c 100644 --- a/src/EFCore/Metadata/Conventions/IModelEmbeddedDiscriminatorNameConvention.cs +++ b/src/EFCore/Metadata/Conventions/IModelEmbeddedDiscriminatorNameConvention.cs @@ -12,7 +12,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata.Conventions; public interface IModelEmbeddedDiscriminatorNameConvention : IConvention { /// - /// Called after has been called. + /// Called after has been called. /// /// The builder for the model. /// The new discriminator name. diff --git a/src/EFCore/Metadata/Conventions/IndexAttributeConvention.cs b/src/EFCore/Metadata/Conventions/IndexAttributeConvention.cs index 9e720f60550..121d029fb46 100644 --- a/src/EFCore/Metadata/Conventions/IndexAttributeConvention.cs +++ b/src/EFCore/Metadata/Conventions/IndexAttributeConvention.cs @@ -19,9 +19,7 @@ public class IndexAttributeConvention : /// /// Parameter object containing dependencies for this convention. public IndexAttributeConvention(ProviderConventionSetBuilderDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Metadata/Conventions/Infrastructure/ProviderConventionSetBuilder.cs b/src/EFCore/Metadata/Conventions/Infrastructure/ProviderConventionSetBuilder.cs index f535fb4ed2e..10175ebd642 100644 --- a/src/EFCore/Metadata/Conventions/Infrastructure/ProviderConventionSetBuilder.cs +++ b/src/EFCore/Metadata/Conventions/Infrastructure/ProviderConventionSetBuilder.cs @@ -37,9 +37,7 @@ public class ProviderConventionSetBuilder : IProviderConventionSetBuilder /// /// Parameter object containing dependencies for this service. public ProviderConventionSetBuilder(ProviderConventionSetBuilderDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Metadata/Conventions/Internal/ConventionContext.cs b/src/EFCore/Metadata/Conventions/Internal/ConventionContext.cs index 1f8da73cbf5..ff189043d64 100644 --- a/src/EFCore/Metadata/Conventions/Internal/ConventionContext.cs +++ b/src/EFCore/Metadata/Conventions/Internal/ConventionContext.cs @@ -22,9 +22,7 @@ public class ConventionContext : IConventionContext, IRead /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public ConventionContext(ConventionDispatcher dispatcher) - { - _dispatcher = dispatcher; - } + => _dispatcher = dispatcher; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/Metadata/Conventions/Internal/ConventionDispatcher.DelayedConventionScope.cs b/src/EFCore/Metadata/Conventions/Internal/ConventionDispatcher.DelayedConventionScope.cs index e0a7200e49b..e5195facd77 100644 --- a/src/EFCore/Metadata/Conventions/Internal/ConventionDispatcher.DelayedConventionScope.cs +++ b/src/EFCore/Metadata/Conventions/Internal/ConventionDispatcher.DelayedConventionScope.cs @@ -45,7 +45,10 @@ public override void Run(ConventionDispatcher dispatcher) return annotation; } - public override string? OnModelEmbeddedDiscriminatorNameChanged(IConventionModelBuilder modelBuilder, string? oldName, string? newName) + public override string? OnModelEmbeddedDiscriminatorNameChanged( + IConventionModelBuilder modelBuilder, + string? oldName, + string? newName) { Add(new OnModelEmbeddedDiscriminatorNameChangedNode(modelBuilder, oldName, newName)); return newName; diff --git a/src/EFCore/Metadata/Conventions/Internal/ConventionDispatcher.ImmediateConventionScope.cs b/src/EFCore/Metadata/Conventions/Internal/ConventionDispatcher.ImmediateConventionScope.cs index cd4abed2615..ca81bc4da76 100644 --- a/src/EFCore/Metadata/Conventions/Internal/ConventionDispatcher.ImmediateConventionScope.cs +++ b/src/EFCore/Metadata/Conventions/Internal/ConventionDispatcher.ImmediateConventionScope.cs @@ -1,8 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.EntityFrameworkCore.Metadata.Internal; - namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; public partial class ConventionDispatcher @@ -111,7 +109,9 @@ public IConventionModelBuilder OnModelInitialized(IConventionModelBuilder modelB } public override string? OnModelEmbeddedDiscriminatorNameChanged( - IConventionModelBuilder modelBuilder, string? oldName, string? newName) + IConventionModelBuilder modelBuilder, + string? oldName, + string? newName) { using (dispatcher.DelayConventions()) { diff --git a/src/EFCore/Metadata/Conventions/Internal/MetadataTracker.cs b/src/EFCore/Metadata/Conventions/Internal/MetadataTracker.cs index 9b0df0c6129..f1bcfd3e857 100644 --- a/src/EFCore/Metadata/Conventions/Internal/MetadataTracker.cs +++ b/src/EFCore/Metadata/Conventions/Internal/MetadataTracker.cs @@ -27,9 +27,8 @@ public virtual void Update(IConventionForeignKey oldForeignKey, IConventionForei !oldForeignKey.IsInModel && newForeignKey.IsInModel, $"{nameof(oldForeignKey)} is in the model or {nameof(newForeignKey)} isn't"); - if (_trackedForeignKeys.TryGetValue(oldForeignKey, out var reference)) + if (_trackedForeignKeys.Remove(oldForeignKey, out var reference)) { - _trackedForeignKeys.Remove(oldForeignKey); reference.Object = newForeignKey; _trackedForeignKeys.Add(newForeignKey, reference); } diff --git a/src/EFCore/Metadata/Conventions/KeyDiscoveryConvention.cs b/src/EFCore/Metadata/Conventions/KeyDiscoveryConvention.cs index f1bbd2303e9..36080ce2420 100644 --- a/src/EFCore/Metadata/Conventions/KeyDiscoveryConvention.cs +++ b/src/EFCore/Metadata/Conventions/KeyDiscoveryConvention.cs @@ -44,9 +44,7 @@ public class KeyDiscoveryConvention : /// /// Parameter object containing dependencies for this convention. public KeyDiscoveryConvention(ProviderConventionSetBuilderDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. @@ -81,9 +79,9 @@ protected virtual void TryConfigurePrimaryKey(IConventionEntityTypeBuilder entit /// Determines whether key properties should be discovered for the entity type. /// /// The entity type. - /// if key properties should be discovered, otherwise . - protected virtual bool ShouldDiscoverKeyProperties(IConventionEntityType entityType) => - entityType.BaseType == null + /// if key properties should be discovered, otherwise . + protected virtual bool ShouldDiscoverKeyProperties(IConventionEntityType entityType) + => entityType.BaseType == null && (!entityType.IsKeyless || entityType.GetIsKeylessConfigurationSource() == ConfigurationSource.Convention) && entityType.Builder.CanSetPrimaryKey((IReadOnlyList?)null); @@ -304,7 +302,7 @@ public virtual void ProcessForeignKeyPropertiesChanged( { var foreignKey = relationshipBuilder.Metadata; if ((foreignKey.IsOwnership - || foreignKey.GetReferencingSkipNavigations().Any(n => n.IsCollection)) + || foreignKey.GetReferencingSkipNavigations().Any(n => n.IsCollection)) && !foreignKey.Properties.SequenceEqual(oldDependentProperties) && relationshipBuilder.Metadata.IsInModel) { diff --git a/src/EFCore/Metadata/Conventions/ManyToManyJoinEntityTypeConvention.cs b/src/EFCore/Metadata/Conventions/ManyToManyJoinEntityTypeConvention.cs index 6966a4d3fcb..fcc99989153 100644 --- a/src/EFCore/Metadata/Conventions/ManyToManyJoinEntityTypeConvention.cs +++ b/src/EFCore/Metadata/Conventions/ManyToManyJoinEntityTypeConvention.cs @@ -24,9 +24,7 @@ public class ManyToManyJoinEntityTypeConvention : /// /// Parameter object containing dependencies for this convention. public ManyToManyJoinEntityTypeConvention(ProviderConventionSetBuilderDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Metadata/Conventions/ModelCleanupConvention.cs b/src/EFCore/Metadata/Conventions/ModelCleanupConvention.cs index 329ccd23cde..089c8bb4fb4 100644 --- a/src/EFCore/Metadata/Conventions/ModelCleanupConvention.cs +++ b/src/EFCore/Metadata/Conventions/ModelCleanupConvention.cs @@ -18,9 +18,7 @@ public class ModelCleanupConvention : /// /// Parameter object containing dependencies for this convention. public ModelCleanupConvention(ProviderConventionSetBuilderDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Metadata/Conventions/NavigationAttributeConventionBase.cs b/src/EFCore/Metadata/Conventions/NavigationAttributeConventionBase.cs index b67bf70a5e6..02ee777fa7b 100644 --- a/src/EFCore/Metadata/Conventions/NavigationAttributeConventionBase.cs +++ b/src/EFCore/Metadata/Conventions/NavigationAttributeConventionBase.cs @@ -22,9 +22,7 @@ public abstract class NavigationAttributeConventionBase /// /// Parameter object containing dependencies for this convention. protected NavigationAttributeConventionBase(ProviderConventionSetBuilderDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. @@ -311,7 +309,8 @@ public virtual void ProcessEntityTypeMemberIgnored( private Type? FindCandidateNavigationWithAttributePropertyType(PropertyInfo propertyInfo, IConventionModel model) { - var targetClrType = Dependencies.MemberClassifier.FindCandidateNavigationPropertyType(propertyInfo, model, useAttributes: true, out _); + var targetClrType = + Dependencies.MemberClassifier.FindCandidateNavigationPropertyType(propertyInfo, model, useAttributes: true, out _); return targetClrType != null && Attribute.IsDefined(propertyInfo, typeof(TAttribute), inherit: true) ? targetClrType diff --git a/src/EFCore/Metadata/Conventions/NavigationEagerLoadingConvention.cs b/src/EFCore/Metadata/Conventions/NavigationEagerLoadingConvention.cs index 14265037d4c..4a2b29afa81 100644 --- a/src/EFCore/Metadata/Conventions/NavigationEagerLoadingConvention.cs +++ b/src/EFCore/Metadata/Conventions/NavigationEagerLoadingConvention.cs @@ -16,9 +16,7 @@ public class NavigationEagerLoadingConvention : IForeignKeyOwnershipChangedConve /// /// Parameter object containing dependencies for this convention. public NavigationEagerLoadingConvention(ProviderConventionSetBuilderDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Metadata/Conventions/NonNullableConventionBase.cs b/src/EFCore/Metadata/Conventions/NonNullableConventionBase.cs index e5f26fd5084..78ddc34d8d9 100644 --- a/src/EFCore/Metadata/Conventions/NonNullableConventionBase.cs +++ b/src/EFCore/Metadata/Conventions/NonNullableConventionBase.cs @@ -21,9 +21,7 @@ public abstract class NonNullableConventionBase : IModelFinalizingConvention /// /// Parameter object containing dependencies for this convention. protected NonNullableConventionBase(ProviderConventionSetBuilderDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Metadata/Conventions/NonNullableNavigationConvention.cs b/src/EFCore/Metadata/Conventions/NonNullableNavigationConvention.cs index 977505f688a..e6549e692f9 100644 --- a/src/EFCore/Metadata/Conventions/NonNullableNavigationConvention.cs +++ b/src/EFCore/Metadata/Conventions/NonNullableNavigationConvention.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.EntityFrameworkCore.Internal; -using Microsoft.EntityFrameworkCore.Metadata.Internal; namespace Microsoft.EntityFrameworkCore.Metadata.Conventions; @@ -68,10 +67,11 @@ private void ProcessNavigation(IConventionNavigationBuilder navigationBuilder) if (navigation.IsOnDependent) { - if (foreignKey.Properties.All(p => - !p.IsNullable - || (p.IsShadowProperty() - && ConfigurationSource.Convention.Overrides(p.GetIsNullableConfigurationSource())))) + if (foreignKey.Properties.All( + p => + !p.IsNullable + || (p.IsShadowProperty() + && ConfigurationSource.Convention.Overrides(p.GetIsNullableConfigurationSource())))) { foreignKey.Builder.IsRequired(true); } diff --git a/src/EFCore/Metadata/Conventions/NotMappedMemberAttributeConvention.cs b/src/EFCore/Metadata/Conventions/NotMappedMemberAttributeConvention.cs index e0df1dda8cf..96ed21ab8ec 100644 --- a/src/EFCore/Metadata/Conventions/NotMappedMemberAttributeConvention.cs +++ b/src/EFCore/Metadata/Conventions/NotMappedMemberAttributeConvention.cs @@ -3,7 +3,6 @@ using System.ComponentModel.DataAnnotations.Schema; using Microsoft.EntityFrameworkCore.Internal; -using Microsoft.EntityFrameworkCore.Metadata.Internal; namespace Microsoft.EntityFrameworkCore.Metadata.Conventions; @@ -20,9 +19,7 @@ public class NotMappedMemberAttributeConvention : IEntityTypeAddedConvention, IC /// /// Parameter object containing dependencies for this convention. public NotMappedMemberAttributeConvention(ProviderConventionSetBuilderDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Metadata/Conventions/PropertyAttributeConventionBase.cs b/src/EFCore/Metadata/Conventions/PropertyAttributeConventionBase.cs index 49df1fafc6d..4ee388bb071 100644 --- a/src/EFCore/Metadata/Conventions/PropertyAttributeConventionBase.cs +++ b/src/EFCore/Metadata/Conventions/PropertyAttributeConventionBase.cs @@ -29,9 +29,7 @@ public abstract class PropertyAttributeConventionBase : /// /// Parameter object containing dependencies for this convention. protected PropertyAttributeConventionBase(ProviderConventionSetBuilderDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Metadata/Conventions/PropertyDiscoveryConvention.cs b/src/EFCore/Metadata/Conventions/PropertyDiscoveryConvention.cs index def59b8889f..74fd674b38a 100644 --- a/src/EFCore/Metadata/Conventions/PropertyDiscoveryConvention.cs +++ b/src/EFCore/Metadata/Conventions/PropertyDiscoveryConvention.cs @@ -68,7 +68,7 @@ public void ProcessComplexPropertyAdded( => DiscoverPrimitiveProperties(propertyBuilder.Metadata.ComplexType.Builder, context); /// - /// Discovers properties on the given structural type. + /// Discovers properties on the given structural type. /// /// The type for which the properties will be discovered. /// Additional information associated with convention execution. @@ -105,7 +105,7 @@ protected virtual IEnumerable GetMembers(IConventionTypeBase structu => structuralType is IConventionComplexType ? structuralType.GetRuntimeProperties().Values.Cast() .Concat(structuralType.GetRuntimeFields().Values) - : structuralType.GetRuntimeProperties().Values.Cast(); + : structuralType.GetRuntimeProperties().Values; /// /// Returns a value indicating whether the given member is a primitive property candidate. @@ -114,7 +114,9 @@ protected virtual IEnumerable GetMembers(IConventionTypeBase structu /// The type for which the properties will be discovered. /// The type mapping for the property. protected virtual bool IsCandidatePrimitiveProperty( - MemberInfo memberInfo, IConventionTypeBase structuralType, out CoreTypeMapping? mapping) + MemberInfo memberInfo, + IConventionTypeBase structuralType, + out CoreTypeMapping? mapping) => Dependencies.MemberClassifier.IsCandidatePrimitiveProperty(memberInfo, structuralType.Model, UseAttributes, out mapping) && ((Model)structuralType.Model).FindIsComplexConfigurationSource(memberInfo.GetMemberType().UnwrapNullableType()) == null; } diff --git a/src/EFCore/Metadata/Conventions/QueryFilterRewritingConvention.cs b/src/EFCore/Metadata/Conventions/QueryFilterRewritingConvention.cs index 6a2d5c18d96..8cc051d093c 100644 --- a/src/EFCore/Metadata/Conventions/QueryFilterRewritingConvention.cs +++ b/src/EFCore/Metadata/Conventions/QueryFilterRewritingConvention.cs @@ -64,9 +64,7 @@ protected class DbSetAccessRewritingExpressionVisitor : ExpressionVisitor /// /// The clr type of derived DbContext. public DbSetAccessRewritingExpressionVisitor(Type contextType) - { - _contextType = contextType; - } + => _contextType = contextType; /// /// Rewrites DbSet accesses encountered in the expression to . diff --git a/src/EFCore/Metadata/Conventions/RuntimeModelConvention.cs b/src/EFCore/Metadata/Conventions/RuntimeModelConvention.cs index d079e8fa618..110d239f076 100644 --- a/src/EFCore/Metadata/Conventions/RuntimeModelConvention.cs +++ b/src/EFCore/Metadata/Conventions/RuntimeModelConvention.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Collections; using Microsoft.EntityFrameworkCore.Metadata.Internal; namespace Microsoft.EntityFrameworkCore.Metadata.Conventions; @@ -21,9 +20,7 @@ public class RuntimeModelConvention : IModelFinalizedConvention /// Parameter object containing dependencies for this convention. public RuntimeModelConvention( ProviderConventionSetBuilderDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. @@ -863,9 +860,7 @@ protected class QueryRootRewritingExpressionVisitor : ExpressionVisitor /// /// The model to look for entity types. public QueryRootRewritingExpressionVisitor(IModel model) - { - _model = model; - } + => _model = model; /// /// Rewrites encountered in an expression to use a different entity type. diff --git a/src/EFCore/Metadata/Conventions/ServicePropertyDiscoveryConvention.cs b/src/EFCore/Metadata/Conventions/ServicePropertyDiscoveryConvention.cs index 366e040c1e0..d56941ab2d4 100644 --- a/src/EFCore/Metadata/Conventions/ServicePropertyDiscoveryConvention.cs +++ b/src/EFCore/Metadata/Conventions/ServicePropertyDiscoveryConvention.cs @@ -3,7 +3,6 @@ using System.Diagnostics.CodeAnalysis; using Microsoft.EntityFrameworkCore.Internal; -using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Metadata.Internal; namespace Microsoft.EntityFrameworkCore.Metadata.Conventions; @@ -71,7 +70,7 @@ public virtual void ProcessEntityTypeBaseTypeChanged( } /// - /// Discovers properties on the given structural type. + /// Discovers properties on the given structural type. /// /// The type for which the properties will be discovered. /// Additional information associated with convention execution. @@ -113,7 +112,9 @@ protected virtual IEnumerable GetMembers(IConventionTypeBase structu /// The type for which the properties will be discovered. /// The parameter binding factory for the property. protected virtual bool IsCandidateServiceProperty( - MemberInfo memberInfo, IConventionTypeBase structuralType, [NotNullWhen(true)] out IParameterBindingFactory? factory) + MemberInfo memberInfo, + IConventionTypeBase structuralType, + [NotNullWhen(true)] out IParameterBindingFactory? factory) { factory = null; var model = (Model)structuralType.Model; diff --git a/src/EFCore/Metadata/Conventions/TypeAttributeConventionBase.cs b/src/EFCore/Metadata/Conventions/TypeAttributeConventionBase.cs index 1a9d1b96730..8ca3a9c1e8f 100644 --- a/src/EFCore/Metadata/Conventions/TypeAttributeConventionBase.cs +++ b/src/EFCore/Metadata/Conventions/TypeAttributeConventionBase.cs @@ -20,9 +20,7 @@ public abstract class TypeAttributeConventionBase : IEntityTypeAdded /// /// Parameter object containing dependencies for this convention. protected TypeAttributeConventionBase(ProviderConventionSetBuilderDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Metadata/Conventions/ValueGenerationConvention.cs b/src/EFCore/Metadata/Conventions/ValueGenerationConvention.cs index 62cf79ef669..794241acfb4 100644 --- a/src/EFCore/Metadata/Conventions/ValueGenerationConvention.cs +++ b/src/EFCore/Metadata/Conventions/ValueGenerationConvention.cs @@ -23,9 +23,7 @@ public class ValueGenerationConvention : /// /// Parameter object containing dependencies for this convention. public ValueGenerationConvention(ProviderConventionSetBuilderDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Metadata/IEntityType.cs b/src/EFCore/Metadata/IEntityType.cs index 8074cd115b9..9bd3499963f 100644 --- a/src/EFCore/Metadata/IEntityType.cs +++ b/src/EFCore/Metadata/IEntityType.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics.CodeAnalysis; -using Microsoft.EntityFrameworkCore.Metadata.Internal; namespace Microsoft.EntityFrameworkCore.Metadata; @@ -428,6 +427,7 @@ IEnumerable GetNavigationsInHierarchy() new IEnumerable GetIndexes(); // The following methods are needed for binary compatibility + #region DO NOT DELETE /// diff --git a/src/EFCore/Metadata/Internal/ClrPropertyGetterFactory.cs b/src/EFCore/Metadata/Internal/ClrPropertyGetterFactory.cs index 91a8bb560bf..f1042cdebe8 100644 --- a/src/EFCore/Metadata/Internal/ClrPropertyGetterFactory.cs +++ b/src/EFCore/Metadata/Internal/ClrPropertyGetterFactory.cs @@ -45,8 +45,10 @@ protected override IClrPropertyGetter CreateGeneric(memberInfo, propertyBase, - out var getterExpression, out var hasSentinelExpression, out var structuralGetterExpression, out var hasStructuralSentinelExpression); + CreateExpressions( + memberInfo, propertyBase, + out var getterExpression, out var hasSentinelExpression, out var structuralGetterExpression, + out var hasStructuralSentinelExpression); return new ClrPropertyGetter( getterExpression.Compile(), hasSentinelExpression.Compile(), @@ -125,7 +127,8 @@ private void CreateExpressions( getterExpression = Expression.Lambda>(readExpression, entityParameter); hasSentinelExpression = Expression.Lambda>(hasSentinelValueExpression, entityParameter); structuralGetterExpression = Expression.Lambda>(structuralReadExpression, structuralParameter); - hasStructuralSentinelExpression = Expression.Lambda>(hasStructuralSentinelValueExpression, structuralParameter); + hasStructuralSentinelExpression = + Expression.Lambda>(hasStructuralSentinelValueExpression, structuralParameter); Expression CreateReadExpression(ParameterExpression parameter, bool fromContainingType) { diff --git a/src/EFCore/Metadata/Internal/ClrPropertySetter.cs b/src/EFCore/Metadata/Internal/ClrPropertySetter.cs index 00655ef9546..d5852660ebf 100644 --- a/src/EFCore/Metadata/Internal/ClrPropertySetter.cs +++ b/src/EFCore/Metadata/Internal/ClrPropertySetter.cs @@ -24,9 +24,7 @@ public sealed class ClrPropertySetter : IClrPropertySetter /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public ClrPropertySetter(Action setter) - { - _setter = setter; - } + => _setter = setter; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/Metadata/Internal/ClrPropertySetterFactory.cs b/src/EFCore/Metadata/Internal/ClrPropertySetterFactory.cs index 3993a064981..845ad9dc74f 100644 --- a/src/EFCore/Metadata/Internal/ClrPropertySetterFactory.cs +++ b/src/EFCore/Metadata/Internal/ClrPropertySetterFactory.cs @@ -96,7 +96,8 @@ private static readonly MethodInfo GenericCreateExpression private void CreateExpression( MemberInfo memberInfo, IPropertyBase? propertyBase, - out Expression> setter) where TEntity : class + out Expression> setter) + where TEntity : class { var entityClrType = propertyBase?.DeclaringType.ContainingEntityType.ClrType ?? typeof(TEntity); var entityParameter = Expression.Parameter(entityClrType, "entity"); diff --git a/src/EFCore/Metadata/Internal/ComplexPropertyConfiguration.cs b/src/EFCore/Metadata/Internal/ComplexPropertyConfiguration.cs index 3912cc0e635..c72fe3e7033 100644 --- a/src/EFCore/Metadata/Internal/ComplexPropertyConfiguration.cs +++ b/src/EFCore/Metadata/Internal/ComplexPropertyConfiguration.cs @@ -18,9 +18,7 @@ public class ComplexPropertyConfiguration : AnnotatableBase /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public ComplexPropertyConfiguration(Type clrType) - { - ClrType = clrType; - } + => ClrType = clrType; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/Metadata/Internal/ComplexPropertyExtensions.cs b/src/EFCore/Metadata/Internal/ComplexPropertyExtensions.cs index 1a2c8de0ee2..59b017436ba 100644 --- a/src/EFCore/Metadata/Internal/ComplexPropertyExtensions.cs +++ b/src/EFCore/Metadata/Internal/ComplexPropertyExtensions.cs @@ -21,7 +21,7 @@ public static IReadOnlyList GetChainToComplexProperty(this ICo { var chain = property.DeclaringType is IComplexType complexType ? (List)complexType.ComplexProperty.GetChainToComplexProperty() - : new(); + : new List(); chain.Add(property); return chain; diff --git a/src/EFCore/Metadata/Internal/ConventionAnnotation.cs b/src/EFCore/Metadata/Internal/ConventionAnnotation.cs index ff156cc7942..9409866caad 100644 --- a/src/EFCore/Metadata/Internal/ConventionAnnotation.cs +++ b/src/EFCore/Metadata/Internal/ConventionAnnotation.cs @@ -21,9 +21,7 @@ public class ConventionAnnotation : Annotation, IConventionAnnotation /// public ConventionAnnotation(string name, object? value, ConfigurationSource configurationSource) : base(name, value) - { - _configurationSource = configurationSource; - } + => _configurationSource = configurationSource; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/Metadata/Internal/DesignTimeModel.cs b/src/EFCore/Metadata/Internal/DesignTimeModel.cs index 4f764fdd3b2..ba643b7b976 100644 --- a/src/EFCore/Metadata/Internal/DesignTimeModel.cs +++ b/src/EFCore/Metadata/Internal/DesignTimeModel.cs @@ -22,9 +22,7 @@ public class DesignTimeModel : IDesignTimeModel /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public DesignTimeModel(IDbContextServices contextServices) - { - _contextServices = contextServices; - } + => _contextServices = contextServices; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/Metadata/Internal/ElementType.cs b/src/EFCore/Metadata/Internal/ElementType.cs index df5941febc8..1cc3e906426 100644 --- a/src/EFCore/Metadata/Internal/ElementType.cs +++ b/src/EFCore/Metadata/Internal/ElementType.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics.CodeAnalysis; -using System.Xml.Linq; using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Storage.Json; diff --git a/src/EFCore/Metadata/Internal/EntityType.cs b/src/EFCore/Metadata/Internal/EntityType.cs index 02bfeb623da..7cadc45f845 100644 --- a/src/EFCore/Metadata/Internal/EntityType.cs +++ b/src/EFCore/Metadata/Internal/EntityType.cs @@ -817,9 +817,7 @@ public virtual IEnumerable GetDeclaredKeys() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual Key? FindDeclaredKey(IReadOnlyList properties) - => _keys.TryGetValue(Check.NotEmpty(properties, nameof(properties)), out var key) - ? key - : null; + => _keys.GetValueOrDefault(Check.NotEmpty(properties, nameof(properties))); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -992,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"); } @@ -1031,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"); } } @@ -1373,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(); @@ -1385,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 @@ -1529,9 +1527,7 @@ public virtual Navigation AddNavigation(MemberIdentity navigationMember, Foreign /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual Navigation? FindDeclaredNavigation(string name) - => _navigations.TryGetValue(Check.NotEmpty(name, nameof(name)), out var navigation) - ? navigation - : null; + => _navigations.GetValueOrDefault(Check.NotEmpty(name, nameof(name))); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -1677,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"); } @@ -1720,9 +1716,7 @@ public virtual IEnumerable GetNavigations() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual SkipNavigation? FindDeclaredSkipNavigation(string name) - => _skipNavigations.TryGetValue(Check.NotEmpty(name, nameof(name)), out var navigation) - ? navigation - : null; + => _skipNavigations.GetValueOrDefault(Check.NotEmpty(name, nameof(name))); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -1832,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(); @@ -1861,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(); @@ -1873,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 @@ -1886,7 +1880,7 @@ public virtual IEnumerable GetDerivedReferencingSkipNavigations( ? Enumerable.Empty() : GetDerivedTypes().SelectMany(et => et.GetDeclaredReferencingSkipNavigations()); - private SortedSet? DeclaredReferencingSkipNavigations { get; set; } + private SortedSet? _declaredReferencingSkipNavigations; #endregion @@ -2084,9 +2078,7 @@ public virtual IEnumerable GetDerivedIndexes() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual Index? FindDeclaredIndex(IReadOnlyList properties) - => _unnamedIndexes.TryGetValue(Check.NotEmpty(properties, nameof(properties)), out var index) - ? index - : null; + => _unnamedIndexes.GetValueOrDefault(Check.NotEmpty(properties, nameof(properties))); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -2095,9 +2087,7 @@ public virtual IEnumerable GetDerivedIndexes() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual Index? FindDeclaredIndex(string name) - => _namedIndexes.TryGetValue(Check.NotEmpty(name, nameof(name)), out var index) - ? index - : null; + => _namedIndexes.GetValueOrDefault(Check.NotEmpty(name, nameof(name))); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -2455,9 +2445,7 @@ public virtual ServiceProperty AddServiceProperty( /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual ServiceProperty? FindDeclaredServiceProperty(string name) - => _serviceProperties.TryGetValue(Check.NotEmpty(name, nameof(name)), out var property) - ? property - : null; + => _serviceProperties.GetValueOrDefault(Check.NotEmpty(name, nameof(name))); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -2627,9 +2615,7 @@ public virtual IEnumerable GetDerivedServiceProperties() { Check.NotEmpty(modelName, nameof(modelName)); - return _triggers.TryGetValue(modelName, out var trigger) - ? trigger - : null; + return _triggers.GetValueOrDefault(modelName); } /// @@ -2653,13 +2639,11 @@ public virtual IEnumerable GetDeclaredTriggers() Check.DebugAssert(IsInModel, "The entity type has been removed from the model"); EnsureMutable(); - if (!_triggers.TryGetValue(modelName, out var trigger)) + if (!_triggers.Remove(modelName, out var trigger)) { return null; } - _triggers.Remove(modelName); - trigger.SetRemovedFromModel(); return (Trigger?)Model.ConventionDispatcher.OnTriggerRemoved(Builder, trigger); @@ -2947,8 +2931,8 @@ public virtual PropertyAccessMode GetNavigationAccessMode() SetAnnotation(CoreAnnotationNames.DiscriminatorProperty, property?.Name, configurationSource); return Model.ConventionDispatcher.OnDiscriminatorPropertySet(Builder, property?.Name) == property?.Name - ? property - : (Property?)((IReadOnlyEntityType)this).FindDiscriminatorProperty(); + ? property + : (Property?)((IReadOnlyEntityType)this).FindDiscriminatorProperty(); } private void CheckDiscriminatorProperty(Property? property) @@ -4111,7 +4095,8 @@ IEnumerable IEntityType.GetSkipNavigations() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// [DebuggerStepThrough] - IProperty? IEntityType.FindProperty(string name) => FindProperty(name); + IProperty? IEntityType.FindProperty(string name) + => FindProperty(name); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -4120,7 +4105,8 @@ IEnumerable IEntityType.GetSkipNavigations() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// [DebuggerStepThrough] - IProperty? IEntityType.FindDeclaredProperty(string name) => FindDeclaredProperty(name); + IProperty? IEntityType.FindDeclaredProperty(string name) + => FindDeclaredProperty(name); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -4129,7 +4115,8 @@ IEnumerable IEntityType.GetSkipNavigations() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// [DebuggerStepThrough] - IEnumerable IEntityType.GetDeclaredProperties() => GetDeclaredProperties(); + IEnumerable IEntityType.GetDeclaredProperties() + => GetDeclaredProperties(); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -4138,7 +4125,8 @@ IEnumerable IEntityType.GetSkipNavigations() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// [DebuggerStepThrough] - IEnumerable IEntityType.GetProperties() => GetProperties(); + IEnumerable IEntityType.GetProperties() + => GetProperties(); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/Metadata/Internal/ForeignKey.cs b/src/EFCore/Metadata/Internal/ForeignKey.cs index 9c918c8c172..f1970324321 100644 --- a/src/EFCore/Metadata/Internal/ForeignKey.cs +++ b/src/EFCore/Metadata/Internal/ForeignKey.cs @@ -117,8 +117,10 @@ public ForeignKey( public virtual InternalForeignKeyBuilder Builder { [DebuggerStepThrough] - get => _builder ?? throw new InvalidOperationException(CoreStrings.ObjectRemovedFromModel( - Property.Format(Properties.Select(p => p.Name)))); + get => _builder + ?? throw new InvalidOperationException( + CoreStrings.ObjectRemovedFromModel( + Property.Format(Properties.Select(p => p.Name)))); } /// diff --git a/src/EFCore/Metadata/Internal/IMemberClassifier.cs b/src/EFCore/Metadata/Internal/IMemberClassifier.cs index 152dd32154b..9751e68a545 100644 --- a/src/EFCore/Metadata/Internal/IMemberClassifier.cs +++ b/src/EFCore/Metadata/Internal/IMemberClassifier.cs @@ -1,9 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Collections.Immutable; -using System.Diagnostics.CodeAnalysis; - namespace Microsoft.EntityFrameworkCore.Metadata.Internal; /// diff --git a/src/EFCore/Metadata/Internal/IRuntimeModel.cs b/src/EFCore/Metadata/Internal/IRuntimeModel.cs index 32a5c570494..7cfde75dda6 100644 --- a/src/EFCore/Metadata/Internal/IRuntimeModel.cs +++ b/src/EFCore/Metadata/Internal/IRuntimeModel.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Reflection.Metadata; using Microsoft.EntityFrameworkCore.Design.Internal; namespace Microsoft.EntityFrameworkCore.Metadata.Internal; diff --git a/src/EFCore/Metadata/Internal/Index.cs b/src/EFCore/Metadata/Internal/Index.cs index aef2b455e1d..a6a901892c7 100644 --- a/src/EFCore/Metadata/Internal/Index.cs +++ b/src/EFCore/Metadata/Internal/Index.cs @@ -56,9 +56,7 @@ public Index( EntityType declaringEntityType, ConfigurationSource configurationSource) : this(properties, declaringEntityType, configurationSource) - { - Name = name; - } + => Name = name; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -93,8 +91,10 @@ public Index( public virtual InternalIndexBuilder Builder { [DebuggerStepThrough] - get => _builder ?? throw new InvalidOperationException(CoreStrings.ObjectRemovedFromModel( - Property.Format(Properties.Select(p => p.Name)))); + get => _builder + ?? throw new InvalidOperationException( + CoreStrings.ObjectRemovedFromModel( + Property.Format(Properties.Select(p => p.Name)))); } /// diff --git a/src/EFCore/Metadata/Internal/InternalEntityTypeBuilder.cs b/src/EFCore/Metadata/Internal/InternalEntityTypeBuilder.cs index ed24a661d84..dfeeb09c785 100644 --- a/src/EFCore/Metadata/Internal/InternalEntityTypeBuilder.cs +++ b/src/EFCore/Metadata/Internal/InternalEntityTypeBuilder.cs @@ -441,12 +441,14 @@ public static (InternalKeyBuilder, ConfigurationSource?) DetachKey(Key keyToDeta continue; } - if (foreignKey.DependentToPrincipal != null && foreignKey.GetDependentToPrincipalConfigurationSource() == ConfigurationSource.Explicit) + if (foreignKey.DependentToPrincipal != null + && foreignKey.GetDependentToPrincipalConfigurationSource() == ConfigurationSource.Explicit) { throw new InvalidOperationException( CoreStrings.NavigationToKeylessType(foreignKey.DependentToPrincipal.Name, Metadata.DisplayName())); } - else if ((foreignKey.IsUnique || foreignKey.GetIsUniqueConfigurationSource() != ConfigurationSource.Explicit) + + if ((foreignKey.IsUnique || foreignKey.GetIsUniqueConfigurationSource() != ConfigurationSource.Explicit) && foreignKey.GetPrincipalEndConfigurationSource() != ConfigurationSource.Explicit && foreignKey.Builder.CanSetEntityTypes( foreignKey.DeclaringEntityType, @@ -3644,6 +3646,7 @@ private static bool Contains(IReadOnlyForeignKey? inheritedFk, IReadOnlyForeignK { return null; } + break; } diff --git a/src/EFCore/Metadata/Internal/InternalForeignKeyBuilder.cs b/src/EFCore/Metadata/Internal/InternalForeignKeyBuilder.cs index a6e8f89d517..23acdd229fd 100644 --- a/src/EFCore/Metadata/Internal/InternalForeignKeyBuilder.cs +++ b/src/EFCore/Metadata/Internal/InternalForeignKeyBuilder.cs @@ -1391,8 +1391,8 @@ private bool CanSetIsUnique(bool? unique, ConfigurationSource? configurationSour return null; } - var dependentProperties = (IReadOnlyList)[]; - var principalProperties = (IReadOnlyList)[]; + var dependentProperties = (IReadOnlyList) []; + var principalProperties = (IReadOnlyList) []; var builder = this; if (shouldInvert) { @@ -3198,10 +3198,10 @@ private static InternalForeignKeyBuilder MergeFacetsFrom(Navigation newNavigatio var candidateFk = candidateRelationship.Metadata; if (principalEndConfigurationSource.OverridesStrictly( candidateFk.GetDependentToPrincipalConfigurationSource()) - && (principalEntityType != candidateFk.PrincipalEntityType - || dependentEntityType != candidateFk.DeclaringEntityType) - && (principalEntityType.IsAssignableFrom(dependentEntityType) - || dependentEntityType.IsAssignableFrom(principalEntityType))) + && (principalEntityType != candidateFk.PrincipalEntityType + || dependentEntityType != candidateFk.DeclaringEntityType) + && (principalEntityType.IsAssignableFrom(dependentEntityType) + || dependentEntityType.IsAssignableFrom(principalEntityType))) { // Favor the intra-hierarchical relationship with higher configuration source continue; diff --git a/src/EFCore/Metadata/Internal/InternalModelBuilder.cs b/src/EFCore/Metadata/Internal/InternalModelBuilder.cs index 4358cfffdf3..8f32abaa469 100644 --- a/src/EFCore/Metadata/Internal/InternalModelBuilder.cs +++ b/src/EFCore/Metadata/Internal/InternalModelBuilder.cs @@ -387,7 +387,8 @@ public virtual bool CanHaveEntity( /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual InternalModelBuilder? RemoveImplicitJoinEntity( - EntityType joinEntityType, ConfigurationSource configurationSource = ConfigurationSource.Convention) + EntityType joinEntityType, + ConfigurationSource configurationSource = ConfigurationSource.Convention) => !Check.NotNull(joinEntityType, nameof(joinEntityType)).IsInModel ? this : !joinEntityType.IsImplicitlyCreatedJoinEntityType @@ -686,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/InternalPropertyBuilder.cs b/src/EFCore/Metadata/Internal/InternalPropertyBuilder.cs index 6f68c0d2d26..2b5e128dbbb 100644 --- a/src/EFCore/Metadata/Internal/InternalPropertyBuilder.cs +++ b/src/EFCore/Metadata/Internal/InternalPropertyBuilder.cs @@ -1,10 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Diagnostics.CodeAnalysis; using System.Globalization; -using System.Reflection; using Microsoft.EntityFrameworkCore.Internal; namespace Microsoft.EntityFrameworkCore.Metadata.Internal; @@ -186,22 +184,19 @@ public virtual bool CanSetSentinel(object? sentinel, ConfigurationSource? config { return Equals(Metadata.Sentinel, sentinel); } - else + + try { - try - { - return Equals(Metadata.Sentinel, Convert.ChangeType(sentinel, Metadata.ClrType, CultureInfo.InvariantCulture)); - } - catch - { - throw new InvalidOperationException( - CoreStrings.IncompatibleSentinelValue( - sentinel, Metadata.DeclaringType.DisplayName(), Metadata.Name, Metadata.ClrType.ShortDisplayName())); - } + return Equals(Metadata.Sentinel, Convert.ChangeType(sentinel, Metadata.ClrType, CultureInfo.InvariantCulture)); + } + catch + { + throw new InvalidOperationException( + CoreStrings.IncompatibleSentinelValue( + sentinel, Metadata.DeclaringType.DisplayName(), Metadata.Name, Metadata.ClrType.ShortDisplayName())); } } - /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in @@ -528,6 +523,7 @@ public virtual bool CanSetValueGeneratorFactory( { Metadata.SetElementType(null, configurationSource); } + Metadata.SetProviderClrType(null, configurationSource); Metadata.SetValueConverter(converter, configurationSource); @@ -568,6 +564,7 @@ public virtual bool CanSetConversion( { Metadata.SetElementType(null, configurationSource); } + Metadata.SetValueConverter((ValueConverter?)null, configurationSource); Metadata.SetProviderClrType(providerClrType, configurationSource); @@ -606,6 +603,7 @@ public virtual bool CanSetConversion(Type? providerClrType, ConfigurationSource? { Metadata.SetElementType(null, configurationSource); } + Metadata.SetProviderClrType(null, configurationSource); Metadata.SetValueConverter(converterType, configurationSource); @@ -626,8 +624,8 @@ public virtual bool CanSetConverter( Type? converterType, ConfigurationSource? configurationSource) => (configurationSource.Overrides(Metadata.GetValueConverterConfigurationSource()) - || (Metadata[CoreAnnotationNames.ValueConverter] == null - && (Type?)Metadata[CoreAnnotationNames.ValueConverterType] == converterType)) + || (Metadata[CoreAnnotationNames.ValueConverter] == null + && (Type?)Metadata[CoreAnnotationNames.ValueConverterType] == converterType)) && (converterType == null || CanSetElementType(null, configurationSource)); /// @@ -827,6 +825,13 @@ public virtual bool CanSetProviderValueComparer( { Metadata.SetValueConverter((Type?)null, configurationSource); } + + if (elementType == null + && CanSetConversion((Type?)null, configurationSource)) + { + Metadata.RemoveAnnotation(CoreAnnotationNames.ValueConverter); + } + return new InternalElementTypeBuilder(Metadata.GetElementType()!, ModelBuilder); } @@ -841,7 +846,7 @@ public virtual bool CanSetProviderValueComparer( /// public virtual bool CanSetElementType(Type? elementType, ConfigurationSource? configurationSource) => (configurationSource.Overrides(Metadata.GetElementTypeConfigurationSource()) - && (elementType == null || CanSetConversion((Type?)null, configurationSource))) + && (elementType == null || CanSetConversion((Type?)null, configurationSource))) || elementType == Metadata.GetElementType()?.ClrType; /// diff --git a/src/EFCore/Metadata/Internal/InternalTypeBaseBuilder.cs b/src/EFCore/Metadata/Internal/InternalTypeBaseBuilder.cs index 0c48a9cc9c8..0e889e243f4 100644 --- a/src/EFCore/Metadata/Internal/InternalTypeBaseBuilder.cs +++ b/src/EFCore/Metadata/Internal/InternalTypeBaseBuilder.cs @@ -205,6 +205,7 @@ public static bool IsCompatible(MemberInfo? newMemberInfo, PropertyBase existing || (memberInfo is PropertyInfo propertyInfo && propertyInfo.IsIndexerProperty())) { if (existingProperty.GetTypeConfigurationSource() is ConfigurationSource existingTypeConfigurationSource + && typeConfigurationSource != null && !typeConfigurationSource.Overrides(existingTypeConfigurationSource)) { return null; @@ -224,8 +225,10 @@ public static bool IsCompatible(MemberInfo? newMemberInfo, PropertyBase existing else { if (configurationSource != ConfigurationSource.Explicit - && (!configurationSource.HasValue || !CanAddProperty(propertyType ?? memberInfo?.GetMemberType(), - propertyName, configurationSource.Value, skipTypeCheck: skipTypeCheck))) + && (!configurationSource.HasValue + || !CanAddProperty( + propertyType ?? memberInfo?.GetMemberType(), + propertyName, configurationSource.Value, skipTypeCheck: skipTypeCheck))) { return null; } @@ -648,7 +651,7 @@ public virtual (bool, IReadOnlyList?) TryCreateUniqueProperties( return properties; } - for (var i = 0; ; i++) + for (var i = 0;; i++) { var property = properties[i]; if (!property.IsInModel || !property.DeclaringType.IsAssignableFrom(Metadata)) @@ -669,7 +672,7 @@ public virtual (bool, IReadOnlyList?) TryCreateUniqueProperties( var typeConfigurationSource = property.GetTypeConfigurationSource(); var builder = Property( typeConfigurationSource.Overrides(ConfigurationSource.DataAnnotation) - || (property.IsInModel && Metadata.IsAssignableFrom(property.DeclaringType)) + || (property.IsInModel && Metadata.IsAssignableFrom(property.DeclaringType)) ? property.ClrType : null, property.Name, @@ -771,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); } } @@ -808,7 +811,8 @@ public virtual bool CanHaveProperty( || typeConfigurationSource.Overrides(existingTypeConfigurationSource))) || configurationSource.Overrides(existingProperty.GetConfigurationSource()) : configurationSource.HasValue - && CanAddProperty(propertyType ?? memberInfo?.GetMemberType(), + && CanAddProperty( + propertyType ?? memberInfo?.GetMemberType(), propertyName, configurationSource.Value, checkClrProperty: checkClrProperty); } diff --git a/src/EFCore/Metadata/Internal/Key.cs b/src/EFCore/Metadata/Internal/Key.cs index d191cda9b24..c8a574d86a3 100644 --- a/src/EFCore/Metadata/Internal/Key.cs +++ b/src/EFCore/Metadata/Internal/Key.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; using Microsoft.EntityFrameworkCore.Internal; @@ -66,8 +65,10 @@ public virtual EntityType DeclaringEntityType public virtual InternalKeyBuilder Builder { [DebuggerStepThrough] - get => _builder ?? throw new InvalidOperationException(CoreStrings.ObjectRemovedFromModel( - Property.Format(Properties.Select(p => p.Name)))); + get => _builder + ?? throw new InvalidOperationException( + CoreStrings.ObjectRemovedFromModel( + Property.Format(Properties.Select(p => p.Name)))); } /// diff --git a/src/EFCore/Metadata/Internal/MemberClassifier.cs b/src/EFCore/Metadata/Internal/MemberClassifier.cs index b5f64ee791e..ee456c5b785 100644 --- a/src/EFCore/Metadata/Internal/MemberClassifier.cs +++ b/src/EFCore/Metadata/Internal/MemberClassifier.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Collections.Immutable; using System.Diagnostics.CodeAnalysis; using Microsoft.EntityFrameworkCore.Infrastructure.Internal; using Microsoft.EntityFrameworkCore.Internal; @@ -55,7 +54,7 @@ public MemberClassifier( return navigationCandidates; } - navigationCandidates = new(); + navigationCandidates = new OrderedDictionary(); var model = entityType.Model; if (model.FindAnnotation(inverseAnnotationName)?.Value @@ -169,9 +168,9 @@ private bool IsCandidateNavigationPropertyType( var memberType = memberInfo.GetMemberType(); return isConfiguredAsEntityType == true || targetType != typeof(object) - && (memberType != targetType - || (_parameterBindingFactories.FindFactory(memberType, memberInfo.GetSimpleMemberName()) == null - && _typeMappingSource.FindMapping(memberInfo, model, useAttributes) == null)); + && (memberType != targetType + || (_parameterBindingFactories.FindFactory(memberType, memberInfo.GetSimpleMemberName()) == null + && _typeMappingSource.FindMapping(memberInfo, model, useAttributes) == null)); } /// @@ -181,7 +180,10 @@ private bool IsCandidateNavigationPropertyType( /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual bool IsCandidatePrimitiveProperty( - MemberInfo memberInfo, IConventionModel model, bool useAttributes, out CoreTypeMapping? typeMapping) + MemberInfo memberInfo, + IConventionModel model, + bool useAttributes, + out CoreTypeMapping? typeMapping) { typeMapping = null; if (!memberInfo.IsCandidateProperty()) diff --git a/src/EFCore/Metadata/Internal/Model.cs b/src/EFCore/Metadata/Internal/Model.cs index 7bf8d3eae99..dc0326864e8 100644 --- a/src/EFCore/Metadata/Internal/Model.cs +++ b/src/EFCore/Metadata/Internal/Model.cs @@ -53,9 +53,7 @@ public class Model : ConventionAnnotatable, IMutableModel, IConventionModel, IRu /// public Model(Guid? modelId = null) : this(new ConventionSet()) - { - ModelId = modelId ?? Guid.NewGuid(); - } + => ModelId = modelId ?? Guid.NewGuid(); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -845,12 +843,7 @@ public virtual void RemoveComplexType(ComplexType complexType) return null; } - if (_propertiesByType.TryGetValue(unwrappedType, out var properties)) - { - return properties; - } - - return null; + return _propertiesByType.GetValueOrDefault(unwrappedType); } /// diff --git a/src/EFCore/Metadata/Internal/ModelConfiguration.cs b/src/EFCore/Metadata/Internal/ModelConfiguration.cs index 380b6ca4409..192c97e604a 100644 --- a/src/EFCore/Metadata/Internal/ModelConfiguration.cs +++ b/src/EFCore/Metadata/Internal/ModelConfiguration.cs @@ -273,9 +273,7 @@ public virtual PropertyConfiguration GetOrAddProperty(Type type) /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual PropertyConfiguration? FindProperty(Type type) - => _properties.TryGetValue(type, out var property) - ? property - : null; + => _properties.GetValueOrDefault(type); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -322,9 +320,7 @@ public virtual PropertyConfiguration GetOrAddTypeMapping(Type type) /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual PropertyConfiguration? FindTypeMapping(Type type) - => _typeMappings.TryGetValue(type, out var property) - ? property - : null; + => _typeMappings.GetValueOrDefault(type); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -353,9 +349,7 @@ public virtual ComplexPropertyConfiguration GetOrAddComplexProperty(Type type) /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual ComplexPropertyConfiguration? FindComplexProperty(Type type) - => _complexProperties.TryGetValue(type, out var property) - ? property - : null; + => _complexProperties.GetValueOrDefault(type); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/Metadata/Internal/Property.cs b/src/EFCore/Metadata/Internal/Property.cs index 8908d632230..860fedd8f1d 100644 --- a/src/EFCore/Metadata/Internal/Property.cs +++ b/src/EFCore/Metadata/Internal/Property.cs @@ -822,6 +822,7 @@ private object? DefaultSentinel : GetConversion(throwOnValueConverterConflict: FindAnnotation(CoreAnnotationNames.ValueConverter) == null) .ProviderClrType; } + /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in @@ -882,9 +883,11 @@ public virtual (ValueConverter? ValueConverter, Type? ValueConverterType, Type? if (currentNode != null) { useQueue = true; - queue = new(); + queue = + new Queue<(Property CurrentProperty, Property CycleBreakingProperty, int CyclePosition, int MaxCycleLength + )>(); queue.Enqueue(currentNode.Value); - visitedProperties = new() { property }; + visitedProperties = new HashSet { property }; } if (visitedProperties?.Contains(principalProperty) == true) @@ -909,6 +912,7 @@ public virtual (ValueConverter? ValueConverter, Type? ValueConverterType, Type? currentNode = null; } } + break; } } @@ -917,12 +921,12 @@ public virtual (ValueConverter? ValueConverter, Type? ValueConverterType, Type? return (valueConverter, valueConverterType, providerClrType); bool GetConversion( - Property principalProperty, - bool throwOnValueConverterConflict, - bool throwOnProviderClrTypeConflict, - ref ValueConverter? valueConverter, - ref Type? valueConverterType, - ref Type? providerClrType) + Property principalProperty, + bool throwOnValueConverterConflict, + bool throwOnProviderClrTypeConflict, + ref ValueConverter? valueConverter, + ref Type? valueConverterType, + ref Type? providerClrType) { var annotationFound = false; var valueConverterAnnotation = principalProperty.FindAnnotation(CoreAnnotationNames.ValueConverter); @@ -960,6 +964,7 @@ bool GetConversion( valueConverter = annotationValue; } + annotationFound = true; } @@ -998,6 +1003,7 @@ bool GetConversion( valueConverterType = annotationValue; } + annotationFound = true; } @@ -1036,6 +1042,7 @@ bool GetConversion( providerClrType = annotationValue; } + annotationFound = true; } diff --git a/src/EFCore/Metadata/Internal/PropertyAccessorsFactory.cs b/src/EFCore/Metadata/Internal/PropertyAccessorsFactory.cs index 617f7f9c520..42a412f99b2 100644 --- a/src/EFCore/Metadata/Internal/PropertyAccessorsFactory.cs +++ b/src/EFCore/Metadata/Internal/PropertyAccessorsFactory.cs @@ -206,8 +206,8 @@ private static Expression> CreateCurrentVal } return Expression.Lambda>( - currentValueExpression, - entryParameter); + currentValueExpression, + entryParameter); } private static Expression> CreateOriginalValueGetter(IProperty property) @@ -216,19 +216,19 @@ private static Expression> CreateOriginalVa var originalValuesIndex = property.GetOriginalValueIndex(); return Expression.Lambda>( - originalValuesIndex >= 0 - ? Expression.Call( - entryParameter, - InternalEntityEntry.MakeReadOriginalValueMethod(typeof(TProperty)), - Expression.Constant(property), - Expression.Constant(originalValuesIndex)) - : Expression.Block( - Expression.Throw( - Expression.Constant( - new InvalidOperationException( - CoreStrings.OriginalValueNotTracked(property.Name, property.DeclaringType.DisplayName())))), - Expression.Constant(default(TProperty), typeof(TProperty))), - entryParameter); + originalValuesIndex >= 0 + ? Expression.Call( + entryParameter, + InternalEntityEntry.MakeReadOriginalValueMethod(typeof(TProperty)), + Expression.Constant(property), + Expression.Constant(originalValuesIndex)) + : Expression.Block( + Expression.Throw( + Expression.Constant( + new InvalidOperationException( + CoreStrings.OriginalValueNotTracked(property.Name, property.DeclaringType.DisplayName())))), + Expression.Constant(default(TProperty), typeof(TProperty))), + entryParameter); } private static Expression> CreateRelationshipSnapshotGetter(IPropertyBase propertyBase) @@ -237,17 +237,17 @@ private static Expression> CreateRelationsh var relationshipIndex = (propertyBase as IProperty)?.GetRelationshipIndex() ?? -1; return Expression.Lambda>( - relationshipIndex >= 0 - ? Expression.Call( - entryParameter, - InternalEntityEntry.MakeReadRelationshipSnapshotValueMethod(typeof(TProperty)), - Expression.Constant(propertyBase), - Expression.Constant(relationshipIndex)) - : Expression.Call( - entryParameter, - InternalEntityEntry.MakeGetCurrentValueMethod(typeof(TProperty)), - Expression.Constant(propertyBase)), - entryParameter); + relationshipIndex >= 0 + ? Expression.Call( + entryParameter, + InternalEntityEntry.MakeReadRelationshipSnapshotValueMethod(typeof(TProperty)), + Expression.Constant(propertyBase), + Expression.Constant(relationshipIndex)) + : Expression.Call( + entryParameter, + InternalEntityEntry.MakeGetCurrentValueMethod(typeof(TProperty)), + Expression.Constant(propertyBase)), + entryParameter); } private static Expression> CreateValueBufferGetter(IProperty property) @@ -255,11 +255,11 @@ private static Expression> CreateValueBufferGetter(IPr var valueBufferParameter = Expression.Parameter(typeof(ValueBuffer), "valueBuffer"); return Expression.Lambda>( - Expression.Call( - valueBufferParameter, - ValueBuffer.GetValueMethod, - Expression.Constant(property.GetIndex())), - valueBufferParameter); + Expression.Call( + valueBufferParameter, + ValueBuffer.GetValueMethod, + Expression.Constant(property.GetIndex())), + valueBufferParameter); } /// @@ -313,9 +313,9 @@ public static Expression CreateMemberAccess( || instanceExpression.Type.IsNullableValueType()) { return Expression.Condition( - Expression.Equal(instanceExpression, Expression.Constant(null)), - Expression.Default(memberInfo.GetMemberType()), - Expression.MakeMemberAccess(instanceExpression, memberInfo)); + Expression.Equal(instanceExpression, Expression.Constant(null)), + Expression.Default(memberInfo.GetMemberType()), + Expression.MakeMemberAccess(instanceExpression, memberInfo)); } } diff --git a/src/EFCore/Metadata/Internal/PropertyConfiguration.cs b/src/EFCore/Metadata/Internal/PropertyConfiguration.cs index e5b9af38378..e4940e27f1b 100644 --- a/src/EFCore/Metadata/Internal/PropertyConfiguration.cs +++ b/src/EFCore/Metadata/Internal/PropertyConfiguration.cs @@ -20,9 +20,7 @@ public class PropertyConfiguration : AnnotatableBase, ITypeMappingConfiguration /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public PropertyConfiguration(Type clrType) - { - ClrType = clrType; - } + => ClrType = clrType; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/Metadata/Internal/PropertyNameComparer.cs b/src/EFCore/Metadata/Internal/PropertyNameComparer.cs index 86bb84303ff..f22dacee4ea 100644 --- a/src/EFCore/Metadata/Internal/PropertyNameComparer.cs +++ b/src/EFCore/Metadata/Internal/PropertyNameComparer.cs @@ -20,9 +20,7 @@ public sealed class PropertyNameComparer : IComparer, IEqualityComparer< /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public PropertyNameComparer(IReadOnlyTypeBase typeBase) - { - _entityType = typeBase as IReadOnlyEntityType; - } + => _entityType = typeBase as IReadOnlyEntityType; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/Metadata/Internal/Trigger.cs b/src/EFCore/Metadata/Internal/Trigger.cs index 639b219f270..d6b2db28ced 100644 --- a/src/EFCore/Metadata/Internal/Trigger.cs +++ b/src/EFCore/Metadata/Internal/Trigger.cs @@ -1,8 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Xml.Linq; - namespace Microsoft.EntityFrameworkCore.Metadata.Internal; /// diff --git a/src/EFCore/Metadata/Internal/TypeBase.cs b/src/EFCore/Metadata/Internal/TypeBase.cs index 7b0209c193a..720db7259b9 100644 --- a/src/EFCore/Metadata/Internal/TypeBase.cs +++ b/src/EFCore/Metadata/Internal/TypeBase.cs @@ -516,9 +516,7 @@ public virtual void UpdateConfigurationSource(ConfigurationSource configurationS /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual Property? FindDeclaredProperty(string name) - => _properties.TryGetValue(Check.NotEmpty(name, nameof(name)), out var property) - ? property - : null; + => _properties.GetValueOrDefault(Check.NotEmpty(name, nameof(name))); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -956,9 +954,7 @@ public virtual IReadOnlyDictionary GetRuntimeFields() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual ComplexProperty? FindDeclaredComplexProperty(string name) - => _complexProperties.TryGetValue(Check.NotEmpty(name, nameof(name)), out var property) - ? property - : null; + => _complexProperties.GetValueOrDefault(Check.NotEmpty(name, nameof(name))); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/Metadata/LazyLoaderParameterBindingFactory.cs b/src/EFCore/Metadata/LazyLoaderParameterBindingFactory.cs index f5db6fb713a..c2ffb1df028 100644 --- a/src/EFCore/Metadata/LazyLoaderParameterBindingFactory.cs +++ b/src/EFCore/Metadata/LazyLoaderParameterBindingFactory.cs @@ -29,9 +29,7 @@ public class LazyLoaderParameterBindingFactory : ServiceParameterBindingFactory /// The service dependencies to use. public LazyLoaderParameterBindingFactory(LazyLoaderParameterBindingFactoryDependencies dependencies) : base(typeof(ILazyLoader)) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Metadata/MemberIdentity.cs b/src/EFCore/Metadata/MemberIdentity.cs index 2abc2332612..dc421b05129 100644 --- a/src/EFCore/Metadata/MemberIdentity.cs +++ b/src/EFCore/Metadata/MemberIdentity.cs @@ -36,9 +36,7 @@ public MemberIdentity(MemberInfo memberInfo) [DebuggerStepThrough] private MemberIdentity(object? nameOrMember) - { - _nameOrMember = nameOrMember; - } + => _nameOrMember = nameOrMember; /// /// A instance that does not represent any member. diff --git a/src/EFCore/Metadata/ObjectArrayParameterBinding.cs b/src/EFCore/Metadata/ObjectArrayParameterBinding.cs index 159705145de..ed6cbad4633 100644 --- a/src/EFCore/Metadata/ObjectArrayParameterBinding.cs +++ b/src/EFCore/Metadata/ObjectArrayParameterBinding.cs @@ -24,9 +24,7 @@ public ObjectArrayParameterBinding(IReadOnlyList bindings) : base( typeof(object[]), Check.NotNull(bindings, nameof(bindings)).SelectMany(b => b.ConsumedProperties).ToArray()) - { - _bindings = bindings; - } + => _bindings = bindings; /// /// Creates an expression tree representing the binding of the value of a property from a diff --git a/src/EFCore/Metadata/RuntimeAnnotatableBase.cs b/src/EFCore/Metadata/RuntimeAnnotatableBase.cs index cc7d6429d5e..16244e26a2a 100644 --- a/src/EFCore/Metadata/RuntimeAnnotatableBase.cs +++ b/src/EFCore/Metadata/RuntimeAnnotatableBase.cs @@ -103,7 +103,7 @@ public virtual void SetAnnotation(string name, object? value) string name, Annotation annotation) { - _annotations ??= new(StringComparer.Ordinal); + _annotations ??= new Dictionary(StringComparer.Ordinal); _annotations[name] = annotation; return annotation; @@ -121,8 +121,8 @@ public virtual void SetAnnotation(string name, object? value) Check.NotEmpty(name, nameof(name)); return _annotations != null && _annotations.TryGetValue(name, out var annotation) - ? annotation - : null; + ? annotation + : null; } /// @@ -318,11 +318,7 @@ public virtual TValue GetOrAddRuntimeAnnotationValue( { Check.NotEmpty(name, nameof(name)); - return _runtimeAnnotations == null - ? null - : _runtimeAnnotations.TryGetValue(name, out var annotation) - ? annotation - : null; + return _runtimeAnnotations?.GetValueOrDefault(name); } /// diff --git a/src/EFCore/Metadata/RuntimeComplexType.cs b/src/EFCore/Metadata/RuntimeComplexType.cs index a46e7f3d3de..0fd2c553b67 100644 --- a/src/EFCore/Metadata/RuntimeComplexType.cs +++ b/src/EFCore/Metadata/RuntimeComplexType.cs @@ -36,7 +36,8 @@ public RuntimeComplexType( bool propertyBag, int propertyCount, int complexPropertyCount) - : base(name, type, complexProperty.DeclaringType.Model, null, changeTrackingStrategy, indexerPropertyInfo, propertyBag, + : base( + name, type, complexProperty.DeclaringType.Model, null, changeTrackingStrategy, indexerPropertyInfo, propertyBag, derivedTypesCount: 0, propertyCount: propertyCount, complexPropertyCount: complexPropertyCount) diff --git a/src/EFCore/Metadata/RuntimeEntityType.cs b/src/EFCore/Metadata/RuntimeEntityType.cs index 2eedb86e771..a219886a8bf 100644 --- a/src/EFCore/Metadata/RuntimeEntityType.cs +++ b/src/EFCore/Metadata/RuntimeEntityType.cs @@ -74,7 +74,8 @@ public RuntimeEntityType( int namedIndexCount, int keyCount, int triggerCount) - : base(name, type, model, baseType, changeTrackingStrategy, indexerPropertyInfo, propertyBag, + : base( + name, type, model, baseType, changeTrackingStrategy, indexerPropertyInfo, propertyBag, derivedTypesCount: derivedTypesCount, propertyCount: propertyCount, complexPropertyCount: complexPropertyCount) @@ -83,25 +84,29 @@ public RuntimeEntityType( SetAnnotation(CoreAnnotationNames.DiscriminatorProperty, discriminatorProperty); _discriminatorValue = discriminatorValue; - _foreignKeys = new(foreignKeyCount); - _navigations = new(navigationCount, StringComparer.Ordinal); + _foreignKeys = new List(foreignKeyCount); + _navigations = new OrderedDictionary(navigationCount, StringComparer.Ordinal); if (skipNavigationCount > 0) { - _skipNavigations = new(skipNavigationCount, StringComparer.Ordinal); + _skipNavigations = new OrderedDictionary(skipNavigationCount, StringComparer.Ordinal); } + if (servicePropertyCount > 0) { - _serviceProperties = new(servicePropertyCount, StringComparer.Ordinal); + _serviceProperties = new OrderedDictionary(servicePropertyCount, StringComparer.Ordinal); } - _unnamedIndexes = new(unnamedIndexCount, PropertyListComparer.Instance); + + _unnamedIndexes = + new OrderedDictionary, RuntimeIndex>(unnamedIndexCount, PropertyListComparer.Instance); if (namedIndexCount > 0) { - _namedIndexes = new(namedIndexCount, StringComparer.Ordinal); + _namedIndexes = new OrderedDictionary(namedIndexCount, StringComparer.Ordinal); } - _keys = new(keyCount, PropertyListComparer.Instance); + + _keys = new OrderedDictionary, RuntimeKey>(keyCount, PropertyListComparer.Instance); if (triggerCount > 0) { - _triggers = new(triggerCount, StringComparer.Ordinal); + _triggers = new OrderedDictionary(triggerCount, StringComparer.Ordinal); } } @@ -290,7 +295,8 @@ private IEnumerable FindForeignKeys(IReadOnlyList to also return foreign keys declared on base types. /// /// Declared foreign keys. - public virtual List GetDeclaredForeignKeys() => _foreignKeys; + public virtual List GetDeclaredForeignKeys() + => _foreignKeys; private IEnumerable GetDerivedForeignKeys() => !HasDirectlyDerivedTypes @@ -397,9 +403,7 @@ public virtual RuntimeNavigation AddNavigation( => (RuntimeNavigation?)((IReadOnlyEntityType)this).FindNavigation(name); private RuntimeNavigation? FindDeclaredNavigation(string name) - => _navigations.TryGetValue(name, out var navigation) - ? navigation - : null; + => _navigations.GetValueOrDefault(name); private IEnumerable GetDeclaredNavigations() => _navigations.Values; @@ -472,7 +476,7 @@ public virtual RuntimeSkipNavigation AddSkipNavigation( eagerLoaded, lazyLoadingEnabled); - _skipNavigations ??= new(StringComparer.Ordinal); + _skipNavigations ??= new OrderedDictionary(StringComparer.Ordinal); _skipNavigations.Add(name, skipNavigation); return skipNavigation; @@ -543,7 +547,7 @@ public virtual RuntimeIndex AddIndex( var index = new RuntimeIndex(properties, this, name, unique); if (name != null) { - (_namedIndexes ??= new(StringComparer.Ordinal)).Add(name, index); + (_namedIndexes ??= new OrderedDictionary(StringComparer.Ordinal)).Add(name, index); } else { @@ -642,7 +646,8 @@ public virtual RuntimeServiceProperty AddServiceProperty( this, propertyAccessMode); - (_serviceProperties ??= new(StringComparer.Ordinal))[serviceProperty.Name] = serviceProperty; + (_serviceProperties ??= new OrderedDictionary(StringComparer.Ordinal))[serviceProperty.Name] = + serviceProperty; return serviceProperty; } @@ -770,7 +775,7 @@ public virtual RuntimeTrigger AddTrigger(string modelName) { var trigger = new RuntimeTrigger(this, modelName); - (_triggers ??= new(StringComparer.Ordinal)).Add(modelName, trigger); + (_triggers ??= new OrderedDictionary(StringComparer.Ordinal)).Add(modelName, trigger); return trigger; } @@ -852,8 +857,9 @@ public virtual InstantiationBinding? ServiceOnlyConstructorBinding [EntityFrameworkInternal] public virtual PropertyCounts Counts { - get => NonCapturingLazyInitializer.EnsureInitialized(ref _counts, this, static entityType => - entityType.CalculateCounts()); + get => NonCapturingLazyInitializer.EnsureInitialized( + ref _counts, this, static entityType => + entityType.CalculateCounts()); [DebuggerStepThrough] set => _counts = value; @@ -1306,7 +1312,8 @@ IEnumerable IEntityType.GetDeclaredTriggers() /// [DebuggerStepThrough] - IProperty? IEntityType.FindProperty(string name) => FindProperty(name); + IProperty? IEntityType.FindProperty(string name) + => FindProperty(name); /// [DebuggerStepThrough] @@ -1315,15 +1322,18 @@ IEnumerable IEntityType.GetDeclaredTriggers() /// [DebuggerStepThrough] - IProperty? IEntityType.FindDeclaredProperty(string name) => FindDeclaredProperty(name); + IProperty? IEntityType.FindDeclaredProperty(string name) + => FindDeclaredProperty(name); /// [DebuggerStepThrough] - IEnumerable IEntityType.GetDeclaredProperties() => GetDeclaredProperties(); + IEnumerable IEntityType.GetDeclaredProperties() + => GetDeclaredProperties(); /// [DebuggerStepThrough] - IEnumerable IEntityType.GetProperties() => GetProperties(); + IEnumerable IEntityType.GetProperties() + => GetProperties(); /// [DebuggerStepThrough] diff --git a/src/EFCore/Metadata/RuntimeKey.cs b/src/EFCore/Metadata/RuntimeKey.cs index eeaffb69cd3..90e3c14d2e0 100644 --- a/src/EFCore/Metadata/RuntimeKey.cs +++ b/src/EFCore/Metadata/RuntimeKey.cs @@ -27,9 +27,7 @@ public class RuntimeKey : RuntimeAnnotatableBase, IRuntimeKey /// [EntityFrameworkInternal] public RuntimeKey(IReadOnlyList properties) - { - Properties = properties; - } + => Properties = properties; /// /// Gets the properties that make up the key. diff --git a/src/EFCore/Metadata/RuntimeModel.cs b/src/EFCore/Metadata/RuntimeModel.cs index f4271a0ed1a..3b52e587521 100644 --- a/src/EFCore/Metadata/RuntimeModel.cs +++ b/src/EFCore/Metadata/RuntimeModel.cs @@ -50,10 +50,9 @@ public class RuntimeModel : RuntimeAnnotatableBase, IRuntimeModel [EntityFrameworkInternal] [Obsolete("Use a constructor with parameters")] public RuntimeModel() - : base() { - _entityTypes = new(StringComparer.Ordinal); - _typeConfigurations = new(); + _entityTypes = new Dictionary(StringComparer.Ordinal); + _typeConfigurations = new Dictionary(); } /// @@ -71,8 +70,8 @@ public RuntimeModel( { _skipDetectChanges = skipDetectChanges; _modelId = modelId; - _entityTypes = new(entityTypeCount, StringComparer.Ordinal); - _typeConfigurations = new(typeConfigurationCount); + _entityTypes = new Dictionary(entityTypeCount, StringComparer.Ordinal); + _typeConfigurations = new Dictionary(typeConfigurationCount); } /// @@ -212,9 +211,7 @@ public virtual IEnumerable GetAdHocEntityTypes() /// The name of the entity type to find. /// The entity type, or if none is found. public virtual RuntimeEntityType? FindEntityType(string name) - => _entityTypes.TryGetValue(name, out var entityType) - ? entityType - : null; + => _entityTypes.GetValueOrDefault(name); /// /// Gets the entity type with the given name. Returns if no entity type with the given name has been @@ -223,9 +220,7 @@ public virtual IEnumerable GetAdHocEntityTypes() /// The CLR type of the entity type to find. /// The entity type, or if none is found. public virtual RuntimeEntityType? FindAdHocEntityType(Type clrType) - => _adHocEntityTypes.TryGetValue(clrType, out var entityType) - ? entityType - : null; + => _adHocEntityTypes.GetValueOrDefault(clrType); private RuntimeEntityType? FindEntityType(Type type) => FindEntityType(GetDisplayName(type)); diff --git a/src/EFCore/Metadata/RuntimeProperty.cs b/src/EFCore/Metadata/RuntimeProperty.cs index 28a964f75f4..52f382e4e5c 100644 --- a/src/EFCore/Metadata/RuntimeProperty.cs +++ b/src/EFCore/Metadata/RuntimeProperty.cs @@ -3,7 +3,6 @@ using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; -using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata.Internal; @@ -23,10 +22,11 @@ public class RuntimeProperty : RuntimePropertyBase, IProperty private readonly ValueGenerated _valueGenerated; private readonly bool _isConcurrencyToken; private object? _sentinel; + private object? _sentinelFromProviderValue; private readonly PropertySaveBehavior _beforeSaveBehavior; private readonly PropertySaveBehavior _afterSaveBehavior; private readonly Func? _valueGeneratorFactory; - private readonly ValueConverter? _valueConverter; + private ValueConverter? _valueConverter; private readonly ValueComparer? _customValueComparer; private ValueComparer? _valueComparer; private ValueComparer? _keyValueComparer; @@ -113,11 +113,11 @@ public RuntimeProperty( } /// - /// Sets the value, converting from the provider type if needed. + /// Sets the value, converting from the provider type if needed. /// /// The value, as a provider value if a value converter is being used. public virtual void SetSentinelFromProviderValue(object? providerValue) - => _sentinel = _typeMapping?.Converter?.ConvertFromProvider(providerValue) ?? providerValue; + => _sentinelFromProviderValue = providerValue; /// /// Sets the element type for this property. @@ -241,6 +241,16 @@ public virtual CoreTypeMapping TypeMapping set => _typeMapping = value; } + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + [EntityFrameworkInternal] + public virtual void SetValueConverter(ValueConverter converter) + => _valueConverter = converter; + /// public virtual ValueComparer GetValueComparer() => NonCapturingLazyInitializer.EnsureInitialized( @@ -283,7 +293,7 @@ public virtual ValueComparer GetValueComparer() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// [EntityFrameworkInternal] - public virtual ValueComparer SetValueComparer(ValueComparer valueComparer) + public virtual ValueComparer SetComparer(ValueComparer valueComparer) => _valueComparer = valueComparer; /// @@ -300,7 +310,7 @@ public virtual ValueComparer GetKeyValueComparer() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// [EntityFrameworkInternal] - public virtual ValueComparer SetKeyValueComparer(ValueComparer valueComparer) + public virtual ValueComparer SetKeyComparer(ValueComparer valueComparer) => _keyValueComparer = valueComparer; private ValueComparer GetProviderValueComparer() @@ -321,7 +331,19 @@ public virtual ValueComparer SetProviderValueComparer(ValueComparer valueCompare /// public override object? Sentinel - => _sentinel; + { + get + { + if (_sentinelFromProviderValue != null) + { + var providerValue = _sentinelFromProviderValue; + _sentinelFromProviderValue = null; + _sentinel = TypeMapping.Converter!.ConvertFromProvider(providerValue); + } + + return _sentinel; + } + } /// /// Gets the for this property, or if none is set. diff --git a/src/EFCore/Metadata/RuntimePropertyBase.cs b/src/EFCore/Metadata/RuntimePropertyBase.cs index 0d98622b493..4ac3d20206a 100644 --- a/src/EFCore/Metadata/RuntimePropertyBase.cs +++ b/src/EFCore/Metadata/RuntimePropertyBase.cs @@ -93,8 +93,13 @@ PropertyAccessMode IReadOnlyPropertyBase.GetPropertyAccessMode() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// [EntityFrameworkInternal] - public virtual void SetPropertyIndexes(int index, int originalValueIndex, int shadowIndex, int relationshipIndex, int storeGenerationIndex) - => _indexes = new(index, originalValueIndex, shadowIndex, relationshipIndex, storeGenerationIndex); + public virtual void SetPropertyIndexes( + int index, + int originalValueIndex, + int shadowIndex, + int relationshipIndex, + int storeGenerationIndex) + => _indexes = new PropertyIndexes(index, originalValueIndex, shadowIndex, relationshipIndex, storeGenerationIndex); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -109,7 +114,7 @@ public virtual void SetAccessors( Func? originalValueGetter, Func relationshipSnapshotGetter, Func? valueBufferGetter) - => _accessors = new( + => _accessors = new PropertyAccessors( currentValueGetter, preStoreGeneratedCurrentValueGetter, originalValueGetter, diff --git a/src/EFCore/Metadata/RuntimeSkipNavigation.cs b/src/EFCore/Metadata/RuntimeSkipNavigation.cs index 73eb8d5ef17..93d3fff5673 100644 --- a/src/EFCore/Metadata/RuntimeSkipNavigation.cs +++ b/src/EFCore/Metadata/RuntimeSkipNavigation.cs @@ -209,7 +209,7 @@ bool IReadOnlyNavigationBase.IsCollection ICollectionLoader IRuntimeSkipNavigation.GetManyToManyLoader() => NonCapturingLazyInitializer.EnsureInitialized( ref _manyToManyLoader, this, static navigation => - RuntimeFeature.IsDynamicCodeSupported - ? ManyToManyLoaderFactory.Instance.Create(navigation) - : throw new InvalidOperationException(CoreStrings.NativeAotNoCompiledModel)); + RuntimeFeature.IsDynamicCodeSupported + ? ManyToManyLoaderFactory.Instance.Create(navigation) + : throw new InvalidOperationException(CoreStrings.NativeAotNoCompiledModel)); } diff --git a/src/EFCore/Metadata/RuntimeTypeBase.cs b/src/EFCore/Metadata/RuntimeTypeBase.cs index e6f6dc88923..017cfefa55e 100644 --- a/src/EFCore/Metadata/RuntimeTypeBase.cs +++ b/src/EFCore/Metadata/RuntimeTypeBase.cs @@ -55,7 +55,7 @@ protected RuntimeTypeBase( if (baseType != null) { _baseType = baseType; - (baseType._directlyDerivedTypes ??= new(TypeBaseNameComparer.Instance)).Add(this); + (baseType._directlyDerivedTypes ??= new SortedSet(TypeBaseNameComparer.Instance)).Add(this); } _changeTrackingStrategy = changeTrackingStrategy; @@ -64,7 +64,7 @@ protected RuntimeTypeBase( _properties = new OrderedDictionary(propertyCount, new PropertyNameComparer(this)); if (complexPropertyCount > 0) { - _complexProperties = new(complexPropertyCount, StringComparer.Ordinal); + _complexProperties = new OrderedDictionary(complexPropertyCount, StringComparer.Ordinal); } } @@ -106,7 +106,7 @@ protected virtual IEnumerable DirectlyDerivedTypes [EntityFrameworkInternal] protected virtual bool HasDirectlyDerivedTypes => _directlyDerivedTypes != null - && _directlyDerivedTypes.Count > 0; + && _directlyDerivedTypes.Count > 0; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -255,9 +255,7 @@ public virtual RuntimeProperty AddProperty( /// [EntityFrameworkInternal] protected virtual RuntimeProperty? FindDeclaredProperty(string name) - => _properties.TryGetValue(name, out var property) - ? property - : null; + => _properties.GetValueOrDefault(name); /// /// Gets all scalar properties declared on this type. @@ -401,7 +399,7 @@ public virtual RuntimeComplexProperty AddComplexProperty( propertyCount: propertyCount, complexPropertyCount: complexPropertyCount); - _complexProperties ??= new(StringComparer.Ordinal); + _complexProperties ??= new OrderedDictionary(StringComparer.Ordinal); _complexProperties.Add(property.Name, property); return property; @@ -418,8 +416,8 @@ public virtual RuntimeComplexProperty AddComplexProperty( private RuntimeComplexProperty? FindDeclaredComplexProperty(string name) => _complexProperties != null && _complexProperties.TryGetValue(name, out var property) - ? property - : null; + ? property + : null; /// /// Gets the complex properties declared on this type. diff --git a/src/EFCore/Metadata/ServiceParameterBindingFactory.cs b/src/EFCore/Metadata/ServiceParameterBindingFactory.cs index 7c20d030afb..2a70b6f7830 100644 --- a/src/EFCore/Metadata/ServiceParameterBindingFactory.cs +++ b/src/EFCore/Metadata/ServiceParameterBindingFactory.cs @@ -27,9 +27,7 @@ public class ServiceParameterBindingFactory : IParameterBindingFactory /// /// The service type. public ServiceParameterBindingFactory(Type serviceType) - { - _serviceType = serviceType; - } + => _serviceType = serviceType; /// /// Checks whether or not this factory can bind a parameter with the given type and name. diff --git a/src/EFCore/ModelBuilder.cs b/src/EFCore/ModelBuilder.cs index 594632ed51a..7527ab2eca1 100644 --- a/src/EFCore/ModelBuilder.cs +++ b/src/EFCore/ModelBuilder.cs @@ -52,9 +52,7 @@ public ModelBuilder(ConventionSet conventions) /// The dependencies object for the model. public ModelBuilder(ConventionSet conventions, ModelDependencies modelDependencies) : this(conventions, modelDependencies, null) - { - Check.NotNull(modelDependencies, nameof(modelDependencies)); - } + => Check.NotNull(modelDependencies, nameof(modelDependencies)); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -85,9 +83,7 @@ public ModelBuilder(ConventionSet conventions, ModelDependencies? modelDependenc /// EF Core model-building conventions for more information and examples. /// public ModelBuilder() - { - _builder = new Model().Builder; - } + => _builder = new Model().Builder; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -97,9 +93,7 @@ public ModelBuilder() /// [EntityFrameworkInternal] public ModelBuilder(IMutableModel model) - { - _builder = ((Model)model).Builder; - } + => _builder = ((Model)model).Builder; /// /// The model being configured. diff --git a/src/EFCore/Properties/CoreStrings.Designer.cs b/src/EFCore/Properties/CoreStrings.Designer.cs index 1a9d3320fa9..1aa731b3728 100644 --- a/src/EFCore/Properties/CoreStrings.Designer.cs +++ b/src/EFCore/Properties/CoreStrings.Designer.cs @@ -1155,7 +1155,7 @@ public static string ErrorMaterializingPropertyInvalidCast(object? entityType, o entityType, property, expectedType, actualType); /// - /// The methods '{methodName}' and '{asyncMethodName}' are not supported by the current database provider. Please contact the publisher of the database provider for more information. + /// The methods '{methodName}' and '{asyncMethodName}' are not supported by the current database provider. Please contact the publisher of the database provider for more information. /// public static string ExecuteQueriesNotSupported(object? methodName, object? asyncMethodName) => string.Format( @@ -1827,6 +1827,12 @@ public static string MemberListBindingNotSupported public static string MemberMemberBindingNotSupported => GetString("MemberMemberBindingNotSupported"); + /// + /// An asynchronous store managment operation was performed and no asynchronous seed delegate has been provided, however a synchronous seed delegate was. Set 'UseAsyncSeeding' option with a delegate equivalent to the one supplied in 'UseSeeding'. + /// + public static string MissingAsyncSeeder + => GetString("MissingAsyncSeeder"); + /// /// The specified field '{field}' could not be found for property '{2_entityType}.{1_property}'. /// @@ -1835,6 +1841,12 @@ public static string MissingBackingField(object? field, object? property, object GetString("MissingBackingField", nameof(field), "1_property", "2_entityType"), field, property, entityType); + /// + /// A synchronous store managment operation was performed and no synchronous seed delegate has been provided, however an asynchronous seed delegate was. Set 'UseSeeding' option with a delegate equivalent to the one supplied in 'UseAsyncSeeding'. + /// + public static string MissingSeeder + => GetString("MissingSeeder"); + /// /// Runtime metadata changes are not allowed when the model hasn't been marked as read-only. /// @@ -2159,14 +2171,6 @@ public static string NonIndexerEntityType(object? property, object? entityType, GetString("NonIndexerEntityType", nameof(property), nameof(entityType), nameof(type)), property, entityType, type); - /// - /// The LINQ expression '{expression}' could not be translated. Additional information: {details} See https://go.microsoft.com/fwlink/?linkid=2101038 for more information. - /// - public static string NonQueryTranslationFailedWithDetails(object? expression, object? details) - => string.Format( - GetString("NonQueryTranslationFailedWithDetails", nameof(expression), nameof(details)), - expression, details); - /// /// The collection type '{2_collectionType}' being used for navigation '{1_entityType}.{0_navigation}' does not implement 'INotifyCollectionChanged'. Any entity type configured to use the '{changeTrackingStrategy}' change tracking strategy must use collections that implement 'INotifyCollectionChanged'. Consider using 'ObservableCollection<T>' for this. /// @@ -2175,6 +2179,14 @@ public static string NonNotifyingCollection(object? navigation, object? entityTy GetString("NonNotifyingCollection", "0_navigation", "1_entityType", "2_collectionType", nameof(changeTrackingStrategy)), navigation, entityType, collectionType, changeTrackingStrategy); + /// + /// The LINQ expression '{expression}' could not be translated. Additional information: {details} See https://go.microsoft.com/fwlink/?linkid=2101038 for more information. + /// + public static string NonQueryTranslationFailedWithDetails(object? expression, object? details) + => string.Format( + GetString("NonQueryTranslationFailedWithDetails", nameof(expression), nameof(details)), + expression, details); + /// /// The foreign key {foreignKeyProperties} on the entity type '{declaringEntityType}' cannot have a required dependent end since it is not unique. /// diff --git a/src/EFCore/Properties/CoreStrings.resx b/src/EFCore/Properties/CoreStrings.resx index 41d62da4122..4849feeeac3 100644 --- a/src/EFCore/Properties/CoreStrings.resx +++ b/src/EFCore/Properties/CoreStrings.resx @@ -1,17 +1,17 @@  - @@ -1139,9 +1139,15 @@ EF Core does not support MemberMemberBinding: 'new Blog { Data = { Name = "hello world" } }'. + + An asynchronous store managment operation was performed and no asynchronous seed delegate has been provided, however a synchronous seed delegate was. Set 'UseAsyncSeeding' option with a delegate equivalent to the one supplied in 'UseSeeding'. + The specified field '{field}' could not be found for property '{2_entityType}.{1_property}'. + + A synchronous store managment operation was performed and no synchronous seed delegate has been provided, however an asynchronous seed delegate was. Set 'UseSeeding' option with a delegate equivalent to the one supplied in 'UseAsyncSeeding'. + Runtime metadata changes are not allowed when the model hasn't been marked as read-only. diff --git a/src/EFCore/Properties/TypeForwards.cs b/src/EFCore/Properties/TypeForwards.cs index cb6700c69f9..6908949ff3c 100644 --- a/src/EFCore/Properties/TypeForwards.cs +++ b/src/EFCore/Properties/TypeForwards.cs @@ -4,8 +4,10 @@ using System.Runtime.CompilerServices; using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; +#pragma warning disable EF1001 [assembly: TypeForwardedTo(typeof(ObservableBackedBindingList<>))] [assembly: TypeForwardedTo(typeof(ObservableCollectionExtensions))] [assembly: TypeForwardedTo(typeof(ObservableCollectionListSource<>))] [assembly: TypeForwardedTo(typeof(SortableBindingList<>))] [assembly: TypeForwardedTo(typeof(DeleteBehavior))] +#pragma warning restore EF1001 diff --git a/src/EFCore/Query/CompiledQueryCacheKeyGenerator.cs b/src/EFCore/Query/CompiledQueryCacheKeyGenerator.cs index afbcf6ae9f9..12154bddd84 100644 --- a/src/EFCore/Query/CompiledQueryCacheKeyGenerator.cs +++ b/src/EFCore/Query/CompiledQueryCacheKeyGenerator.cs @@ -11,9 +11,7 @@ public class CompiledQueryCacheKeyGenerator : ICompiledQueryCacheKeyGenerator /// /// Parameter object containing dependencies for this service. public CompiledQueryCacheKeyGenerator(CompiledQueryCacheKeyGeneratorDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Query/EntityQueryRootExpression.cs b/src/EFCore/Query/EntityQueryRootExpression.cs index be23b87c175..8fdc91b73d0 100644 --- a/src/EFCore/Query/EntityQueryRootExpression.cs +++ b/src/EFCore/Query/EntityQueryRootExpression.cs @@ -26,9 +26,7 @@ public class EntityQueryRootExpression : QueryRootExpression, IPrintableExpressi /// The entity type this query root represents. public EntityQueryRootExpression(IAsyncQueryProvider asyncQueryProvider, IEntityType entityType) : base(asyncQueryProvider, entityType.ClrType) - { - EntityType = entityType; - } + => EntityType = entityType; /// /// Creates a new instance of the class without any query provider. @@ -36,9 +34,7 @@ public EntityQueryRootExpression(IAsyncQueryProvider asyncQueryProvider, IEntity /// The entity type this query root represents. public EntityQueryRootExpression(IEntityType entityType) : base(entityType.ClrType) - { - EntityType = entityType; - } + => EntityType = entityType; /// /// The entity type represented by this query root. diff --git a/src/EFCore/Query/EvaluatableExpressionFilter.cs b/src/EFCore/Query/EvaluatableExpressionFilter.cs index 0a8d1312598..917df7f8514 100644 --- a/src/EFCore/Query/EvaluatableExpressionFilter.cs +++ b/src/EFCore/Query/EvaluatableExpressionFilter.cs @@ -47,9 +47,7 @@ private static readonly MethodInfo RandomNextTwoArgs /// The dependencies to use. public EvaluatableExpressionFilter( EvaluatableExpressionFilterDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Query/EvaluatableExpressionFilterDependencies.cs b/src/EFCore/Query/EvaluatableExpressionFilterDependencies.cs index df94a6b49f9..575164f4433 100644 --- a/src/EFCore/Query/EvaluatableExpressionFilterDependencies.cs +++ b/src/EFCore/Query/EvaluatableExpressionFilterDependencies.cs @@ -45,9 +45,7 @@ public sealed record EvaluatableExpressionFilterDependencies /// [EntityFrameworkInternal] public EvaluatableExpressionFilterDependencies(IEnumerable plugins) - { - Plugins = plugins; - } + => Plugins = plugins; /// /// Gets the plugins. diff --git a/src/EFCore/Query/InlineQueryRootExpression.cs b/src/EFCore/Query/InlineQueryRootExpression.cs index 79dd5db9113..3626cf8d22c 100644 --- a/src/EFCore/Query/InlineQueryRootExpression.cs +++ b/src/EFCore/Query/InlineQueryRootExpression.cs @@ -26,9 +26,7 @@ public class InlineQueryRootExpression : QueryRootExpression /// The element type this query root represents. public InlineQueryRootExpression(IAsyncQueryProvider asyncQueryProvider, IReadOnlyList values, Type elementType) : base(asyncQueryProvider, elementType) - { - Values = values; - } + => Values = values; /// /// Creates a new instance of the class. @@ -37,9 +35,7 @@ public InlineQueryRootExpression(IAsyncQueryProvider asyncQueryProvider, IReadOn /// The element type this query root represents. public InlineQueryRootExpression(IReadOnlyList values, Type elementType) : base(elementType) - { - Values = values; - } + => Values = values; /// public override Expression DetachQueryProvider() diff --git a/src/EFCore/Query/Internal/CallForwardingExpressionVisitor.cs b/src/EFCore/Query/Internal/CallForwardingExpressionVisitor.cs index c66ee8df224..3b767410937 100644 --- a/src/EFCore/Query/Internal/CallForwardingExpressionVisitor.cs +++ b/src/EFCore/Query/Internal/CallForwardingExpressionVisitor.cs @@ -425,10 +425,7 @@ public class CallForwardingExpressionVisitor : ExpressionVisitor typeof(float).GetRuntimeMethod(nameof(float.Truncate), [typeof(float)])!, typeof(MathF).GetRuntimeMethod(nameof(MathF.Truncate), [typeof(float)])! }, - { - typeof(int).GetRuntimeMethod(nameof(int.Abs), [typeof(int)])!, - typeof(Math).GetRuntimeMethod(nameof(Math.Abs), [typeof(int)])! - }, + { typeof(int).GetRuntimeMethod(nameof(int.Abs), [typeof(int)])!, typeof(Math).GetRuntimeMethod(nameof(Math.Abs), [typeof(int)])! }, { typeof(int).GetRuntimeMethod(nameof(int.Clamp), [typeof(int), typeof(int), typeof(int)])!, typeof(Math).GetRuntimeMethod(nameof(Math.Clamp), [typeof(int), typeof(int), typeof(int)])! @@ -442,8 +439,7 @@ public class CallForwardingExpressionVisitor : ExpressionVisitor typeof(Math).GetRuntimeMethod(nameof(Math.Min), [typeof(int), typeof(int)])! }, { - typeof(int).GetRuntimeMethod(nameof(int.Sign), [typeof(int)])!, - typeof(Math).GetRuntimeMethod(nameof(Math.Sign), [typeof(int)])! + typeof(int).GetRuntimeMethod(nameof(int.Sign), [typeof(int)])!, typeof(Math).GetRuntimeMethod(nameof(Math.Sign), [typeof(int)])! }, { typeof(long).GetRuntimeMethod(nameof(long.Abs), [typeof(long)])!, diff --git a/src/EFCore/Query/Internal/CompiledQueryBase.cs b/src/EFCore/Query/Internal/CompiledQueryBase.cs index c550afd44b7..179fee35b3c 100644 --- a/src/EFCore/Query/Internal/CompiledQueryBase.cs +++ b/src/EFCore/Query/Internal/CompiledQueryBase.cs @@ -31,9 +31,7 @@ private sealed class ExecutorAndModel(Func executor, IMod /// doing so can result in application failures when updating to a new Entity Framework Core release. /// protected CompiledQueryBase(LambdaExpression queryExpression) - { - _queryExpression = queryExpression; - } + => _queryExpression = queryExpression; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/Query/Internal/CompiledQueryCache.cs b/src/EFCore/Query/Internal/CompiledQueryCache.cs index cae804057aa..decbedbe097 100644 --- a/src/EFCore/Query/Internal/CompiledQueryCache.cs +++ b/src/EFCore/Query/Internal/CompiledQueryCache.cs @@ -25,9 +25,7 @@ public class CompiledQueryCache : ICompiledQueryCache /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public CompiledQueryCache(IMemoryCache memoryCache) - { - _memoryCache = memoryCache; - } + => _memoryCache = memoryCache; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/Query/Internal/EntityMaterializerSource.cs b/src/EFCore/Query/Internal/EntityMaterializerSource.cs index 9f61be3c437..ff491ef339b 100644 --- a/src/EFCore/Query/Internal/EntityMaterializerSource.cs +++ b/src/EFCore/Query/Internal/EntityMaterializerSource.cs @@ -255,9 +255,9 @@ private static readonly ConstructorInfo MaterializationInterceptionDataConstruct = typeof(MaterializationInterceptionData).GetDeclaredConstructor( [ typeof(MaterializationContext), - typeof(IEntityType), - typeof(QueryTrackingBehavior?), - typeof(Dictionary)>) + typeof(IEntityType), + typeof(QueryTrackingBehavior?), + typeof(Dictionary)>) ])!; private static readonly MethodInfo CreatingInstanceMethod diff --git a/src/EFCore/Query/Internal/EntityMaterializerSourceDependencies.cs b/src/EFCore/Query/Internal/EntityMaterializerSourceDependencies.cs index 7ea9054cf60..d59b5840c5a 100644 --- a/src/EFCore/Query/Internal/EntityMaterializerSourceDependencies.cs +++ b/src/EFCore/Query/Internal/EntityMaterializerSourceDependencies.cs @@ -45,9 +45,7 @@ public sealed record EntityMaterializerSourceDependencies /// [EntityFrameworkInternal] public EntityMaterializerSourceDependencies(IEnumerable singletonInterceptors) - { - SingletonInterceptors = singletonInterceptors; - } + => SingletonInterceptors = singletonInterceptors; /// /// Registered singleton interceptors. diff --git a/src/EFCore/Query/Internal/EntityQueryProvider.cs b/src/EFCore/Query/Internal/EntityQueryProvider.cs index ee0f2331915..8f4b5a9ae85 100644 --- a/src/EFCore/Query/Internal/EntityQueryProvider.cs +++ b/src/EFCore/Query/Internal/EntityQueryProvider.cs @@ -22,9 +22,7 @@ public class EntityQueryProvider : IAsyncQueryProvider /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public EntityQueryProvider(IQueryCompiler queryCompiler) - { - _queryCompiler = queryCompiler; - } + => _queryCompiler = queryCompiler; private static MethodInfo GenericCreateQueryMethod => _genericCreateQueryMethod ??= typeof(EntityQueryProvider) diff --git a/src/EFCore/Query/Internal/ExpressionTreeFuncletizer.cs b/src/EFCore/Query/Internal/ExpressionTreeFuncletizer.cs index 492635b383d..a763327fbef 100644 --- a/src/EFCore/Query/Internal/ExpressionTreeFuncletizer.cs +++ b/src/EFCore/Query/Internal/ExpressionTreeFuncletizer.cs @@ -5,8 +5,8 @@ using System.Collections.ObjectModel; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; -using Microsoft.EntityFrameworkCore.Internal; using static System.Linq.Expressions.Expression; +using ElementInit = System.Linq.Expressions.ElementInit; namespace Microsoft.EntityFrameworkCore.Query.Internal; @@ -252,10 +252,10 @@ public virtual void ResetPathCalculation() { _ = Evaluate(root, out var parameterName, out _); - state = new() + state = new State { StateType = StateType.ContainsEvaluatable, - Path = new() + Path = new PathNode { ExpressionType = state.ExpressionType!, ParameterName = parameterName, @@ -290,10 +290,10 @@ public virtual void ResetPathCalculation() { _ = Evaluate(root, out var parameterName, out _); - state = new() + state = new State { StateType = StateType.ContainsEvaluatable, - Path = new() + Path = new PathNode { ExpressionType = state.ExpressionType!, ParameterName = parameterName, @@ -481,7 +481,7 @@ protected override Expression VisitBinary(BinaryExpression binary) if (rightState.ContainsEvaluatable) { - children ??= new(); + children ??= new List(); children.Add(rightState.Path! with { PathFromParent = static e => Property(e, nameof(BinaryExpression.Right)) }); } } @@ -556,21 +556,21 @@ protected override Expression VisitConditional(ConditionalExpression conditional { if (testState.ContainsEvaluatable) { - children ??= new(); + children ??= new List(); children.Add( testState.Path! with { PathFromParent = static e => Property(e, nameof(ConditionalExpression.Test)) }); } if (ifTrueState.ContainsEvaluatable) { - children ??= new(); + children ??= new List(); children.Add( ifTrueState.Path! with { PathFromParent = static e => Property(e, nameof(ConditionalExpression.IfTrue)) }); } if (ifFalseState.ContainsEvaluatable) { - children ??= new(); + children ??= new List(); children.Add( ifFalseState.Path! with { PathFromParent = static e => Property(e, nameof(ConditionalExpression.IfFalse)) }); } @@ -944,9 +944,9 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCall) } argumentState = argumentState with { StateType = StateType.EvaluatableWithCapturedVariable }; - var evaluatedArgument = ProcessEvaluatableRoot(argument, ref argumentState); + var evaluatedArgument = ProcessEvaluatableRoot(argument, ref argumentState, forceEvaluation: true); _state = argumentState; - return evaluatedArgument; + return Call(method, evaluatedArgument); } } } @@ -1446,7 +1446,7 @@ visitedInitializersArguments is null Property(e, nameof(ListInitExpression.Initializers)), ReadOnlyElementInitCollectionIndexerGetter, arguments: [Constant(initializerIndex)]), - nameof(System.Linq.Expressions.ElementInit.Arguments)), + nameof(ElementInit.Arguments)), ReadOnlyCollectionIndexerGetter, arguments: [Constant(j)])); @@ -1827,7 +1827,7 @@ private static StateType CombineStateTypes(StateType stateType1, StateType state } [return: NotNullIfNotNull(nameof(evaluatableRoot))] - private Expression? ProcessEvaluatableRoot(Expression? evaluatableRoot, ref State state) + private Expression? ProcessEvaluatableRoot(Expression? evaluatableRoot, ref State state, bool forceEvaluation = false) { if (evaluatableRoot is null) { @@ -1849,7 +1849,7 @@ private static StateType CombineStateTypes(StateType stateType1, StateType state // We have some cases where a node is evaluatable, but only as part of a larger subtree, and should not be evaluated as a tree root. // For these cases, the node's state has a notEvaluatableAsRootHandler lambda, which we can invoke to make evaluate the node's // children (as needed), but not itself. - if (TryHandleNonEvaluatableAsRoot(evaluatableRoot, state, evaluateAsParameter, out var result)) + if (!forceEvaluation && TryHandleNonEvaluatableAsRoot(evaluatableRoot, state, evaluateAsParameter, out var result)) { return result; } @@ -1887,10 +1887,10 @@ private static StateType CombineStateTypes(StateType stateType1, StateType state if (_calculatingPath) { - state = new() + state = new State { StateType = StateType.ContainsEvaluatable, - Path = new() + Path = new PathNode { ExpressionType = state.ExpressionType!, ParameterName = parameterName, @@ -2114,12 +2114,12 @@ private bool IsParameterParameterizable(MethodInfo method, ParameterInfo paramet private enum StateType { /// - /// A temporary initial state, before any children have been examined. + /// A temporary initial state, before any children have been examined. /// Unknown, /// - /// Means that the current node is neither evaluatable, nor does it contains an evaluatable node. + /// Means that the current node is neither evaluatable, nor does it contains an evaluatable node. /// NoEvaluatability, @@ -2136,7 +2136,7 @@ private enum StateType EvaluatableWithCapturedVariable, /// - /// Whether the current node contains (parameterizable) evaluatable nodes anywhere within its children. + /// Whether the current node contains (parameterizable) evaluatable nodes anywhere within its children. /// ContainsEvaluatable } @@ -2159,13 +2159,12 @@ public static State CreateEvaluatable( public static State CreateContainsEvaluatable(Type expressionType, IReadOnlyList children) => new() { - StateType = StateType.ContainsEvaluatable, - Path = new() { ExpressionType = expressionType, Children = children } + StateType = StateType.ContainsEvaluatable, Path = new PathNode { ExpressionType = expressionType, Children = children } }; /// - /// Means that we're neither within an evaluatable subtree, nor on a node which contains one (and therefore needs to track the - /// path to it). + /// Means that we're neither within an evaluatable subtree, nor on a node which contains one (and therefore needs to track the + /// path to it). /// public static readonly State NoEvaluatability = new() { StateType = StateType.NoEvaluatability }; @@ -2174,7 +2173,7 @@ public static State CreateContainsEvaluatable(Type expressionType, IReadOnlyList public Type? ExpressionType { get; init; } /// - /// A tree containing information on reaching all evaluatable nodes contained within this node. + /// A tree containing information on reaching all evaluatable nodes contained within this node. /// public PathNode? Path { get; init; } diff --git a/src/EFCore/Query/Internal/IParameterValues.cs b/src/EFCore/Query/Internal/IParameterValues.cs index e9ba4c5a770..8d52ce91f32 100644 --- a/src/EFCore/Query/Internal/IParameterValues.cs +++ b/src/EFCore/Query/Internal/IParameterValues.cs @@ -1,8 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; - namespace Microsoft.EntityFrameworkCore.Query.Internal; /// diff --git a/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.ExpressionVisitors.cs b/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.ExpressionVisitors.cs index 83e3a731da2..7781adad5c3 100644 --- a/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.ExpressionVisitors.cs +++ b/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.ExpressionVisitors.cs @@ -183,9 +183,7 @@ protected Expression ExpandSkipNavigation( bool derivedTypeConversion) { var inverseNavigation = navigation.Inverse; - var includeTree = entityReference.IncludePaths.TryGetValue(navigation, out var tree) - ? tree - : null; + var includeTree = entityReference.IncludePaths.GetValueOrDefault(navigation); var primaryExpansion = ExpandForeignKey( root, @@ -498,8 +496,11 @@ private sealed class IncludeExpandingExpressionVisitor( private readonly bool _queryStateManager = navigationExpandingExpressionVisitor._queryCompilationContext.QueryTrackingBehavior is QueryTrackingBehavior.TrackAll or QueryTrackingBehavior.NoTrackingWithIdentityResolution; + private readonly bool _ignoreAutoIncludes = navigationExpandingExpressionVisitor._queryCompilationContext.IgnoreAutoIncludes; - private readonly IDiagnosticsLogger _logger = navigationExpandingExpressionVisitor._queryCompilationContext.Logger; + + private readonly IDiagnosticsLogger _logger = navigationExpandingExpressionVisitor._queryCompilationContext + .Logger; protected override Expression VisitBinary(BinaryExpression binaryExpression) { diff --git a/src/EFCore/Query/Internal/QueryCompilationContextFactory.cs b/src/EFCore/Query/Internal/QueryCompilationContextFactory.cs index 6ab3373a5b3..8a2670c0c06 100644 --- a/src/EFCore/Query/Internal/QueryCompilationContextFactory.cs +++ b/src/EFCore/Query/Internal/QueryCompilationContextFactory.cs @@ -20,9 +20,7 @@ public class QueryCompilationContextFactory : IQueryCompilationContextFactory /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public QueryCompilationContextFactory(QueryCompilationContextDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Query/Internal/QueryOptimizingExpressionVisitor.cs b/src/EFCore/Query/Internal/QueryOptimizingExpressionVisitor.cs index 8cc22d0c087..030663bfdcc 100644 --- a/src/EFCore/Query/Internal/QueryOptimizingExpressionVisitor.cs +++ b/src/EFCore/Query/Internal/QueryOptimizingExpressionVisitor.cs @@ -14,22 +14,6 @@ namespace Microsoft.EntityFrameworkCore.Query.Internal; /// public class QueryOptimizingExpressionVisitor : ExpressionVisitor { - private static readonly List SingleResultMethodInfos = - [ - QueryableMethods.FirstWithPredicate, - QueryableMethods.FirstWithoutPredicate, - QueryableMethods.FirstOrDefaultWithPredicate, - QueryableMethods.FirstOrDefaultWithoutPredicate, - QueryableMethods.SingleWithPredicate, - QueryableMethods.SingleWithoutPredicate, - QueryableMethods.SingleOrDefaultWithPredicate, - QueryableMethods.SingleOrDefaultWithoutPredicate, - QueryableMethods.LastWithPredicate, - QueryableMethods.LastWithoutPredicate, - QueryableMethods.LastOrDefaultWithPredicate, - QueryableMethods.LastOrDefaultWithoutPredicate - ]; - private static readonly MethodInfo StringCompareWithComparisonMethod = typeof(string).GetRuntimeMethod(nameof(string.Compare), [typeof(string), typeof(string), typeof(StringComparison)])!; @@ -378,11 +362,17 @@ when unaryExpression.IsLogicalNot(): var (conditional, convert) = inner switch { ConditionalExpression c => (c, null), - UnaryExpression { NodeType: ExpressionType.Convert or ExpressionType.ConvertChecked, Operand: ConditionalExpression cond } conv => (cond, conv), + UnaryExpression + { + NodeType: ExpressionType.Convert or ExpressionType.ConvertChecked, Operand: ConditionalExpression cond + } conv => (cond, conv), _ => (null, null) }; - if (conditional is { Test: BinaryExpression { NodeType: ExpressionType.Equal or ExpressionType.NotEqual } binaryTest } conditionalExpression + if (conditional is + { + Test: BinaryExpression { NodeType: ExpressionType.Equal or ExpressionType.NotEqual } binaryTest + } conditionalExpression && !(conditionalExpression.Type.IsNullableValueType() && visitedMemberExpression.Member.Name is nameof(Nullable.HasValue) or nameof(Nullable.Value))) { diff --git a/src/EFCore/Query/Internal/QueryTranslationPostprocessorFactory.cs b/src/EFCore/Query/Internal/QueryTranslationPostprocessorFactory.cs index dda1b804796..2ecf73545f0 100644 --- a/src/EFCore/Query/Internal/QueryTranslationPostprocessorFactory.cs +++ b/src/EFCore/Query/Internal/QueryTranslationPostprocessorFactory.cs @@ -18,9 +18,7 @@ public class QueryTranslationPostprocessorFactory : IQueryTranslationPostprocess /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public QueryTranslationPostprocessorFactory(QueryTranslationPostprocessorDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/Query/Internal/QueryTranslationPreprocessorFactory.cs b/src/EFCore/Query/Internal/QueryTranslationPreprocessorFactory.cs index b8f320ce29e..c28ced7b457 100644 --- a/src/EFCore/Query/Internal/QueryTranslationPreprocessorFactory.cs +++ b/src/EFCore/Query/Internal/QueryTranslationPreprocessorFactory.cs @@ -18,9 +18,7 @@ public class QueryTranslationPreprocessorFactory : IQueryTranslationPreprocessor /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public QueryTranslationPreprocessorFactory(QueryTranslationPreprocessorDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/Query/Internal/QueryableMethodNormalizingExpressionVisitor.cs b/src/EFCore/Query/Internal/QueryableMethodNormalizingExpressionVisitor.cs index 140637f03cf..493a95e91b5 100644 --- a/src/EFCore/Query/Internal/QueryableMethodNormalizingExpressionVisitor.cs +++ b/src/EFCore/Query/Internal/QueryableMethodNormalizingExpressionVisitor.cs @@ -51,8 +51,8 @@ public virtual Expression Normalize(Expression expression) /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - protected override Expression VisitBinary(BinaryExpression binaryExpression) => - binaryExpression switch + protected override Expression VisitBinary(BinaryExpression binaryExpression) + => binaryExpression switch { // Convert array[x] to array.ElementAt(x) { NodeType: ExpressionType.ArrayIndex, Left: var source, Right: var index } @@ -112,17 +112,29 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp return expression; } - if (method.DeclaringType == typeof(EF) - && method.Name == nameof(EF.Constant)) + if (method.DeclaringType == typeof(EF)) { - if (!_isEfConstantSupported) + switch (method.Name) { - throw new InvalidOperationException(CoreStrings.EFConstantNotSupported); - } + case nameof(EF.Constant): + { + if (!_isEfConstantSupported) + { + throw new InvalidOperationException(CoreStrings.EFConstantNotSupported); + } - var parameterExpression = (ParameterExpression)Visit(methodCallExpression.Arguments[0]); - _queryCompilationContext.ParametersToConstantize.Add(parameterExpression.Name!); - return parameterExpression; + var parameterExpression = (ParameterExpression)Visit(methodCallExpression.Arguments[0]); + _queryCompilationContext.ParametersToConstantize.Add(parameterExpression.Name!); + return parameterExpression; + } + + case nameof(EF.Parameter): + { + var parameterExpression = (ParameterExpression)Visit(methodCallExpression.Arguments[0]); + _queryCompilationContext.ParametersToNotConstantize.Add(parameterExpression.Name!); + return parameterExpression; + } + } } // Normalize list[x] to list.ElementAt(x) @@ -213,7 +225,10 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp && visitedMethodCall.Method.DeclaringType == typeof(Queryable) && visitedMethodCall.Method.IsGenericMethod) { - return TryFlattenGroupJoinSelectMany(visitedMethodCall); + visitedMethodCall = TryNormalizeOrderAndOrderDescending(visitedMethodCall); + visitedMethodCall = TryFlattenGroupJoinSelectMany(visitedMethodCall); + + return visitedMethodCall; } return visitedExpression; @@ -505,25 +520,55 @@ private static bool CanConvertEnumerableToQueryable(Type enumerableType, Type qu || enumerableType == typeof(IOrderedEnumerable<>) && queryableType == typeof(IOrderedQueryable<>); } - private MethodCallExpression TryFlattenGroupJoinSelectMany(MethodCallExpression methodCallExpression) + private MethodCallExpression TryNormalizeOrderAndOrderDescending(MethodCallExpression methodCallExpression) { var genericMethod = methodCallExpression.Method.GetGenericMethodDefinition(); - if (genericMethod == QueryableMethods.SelectManyWithCollectionSelector) + if (genericMethod == QueryableMethods.Order + || genericMethod == QueryableMethods.OrderDescending) + { + var sourceType = methodCallExpression.Method.GetGenericArguments()[0]; + var parameter = Expression.Parameter(sourceType); + + return Expression.Call( + genericMethod == QueryableMethods.Order + ? QueryableMethods.OrderBy.MakeGenericMethod(sourceType, sourceType) + : QueryableMethods.OrderByDescending.MakeGenericMethod(sourceType, sourceType), + methodCallExpression.Arguments[0], + Expression.Quote(Expression.Lambda(parameter, parameter))); + } + + return methodCallExpression; + } + + private MethodCallExpression TryFlattenGroupJoinSelectMany(MethodCallExpression methodCallExpression) + { + switch (methodCallExpression) { - // SelectMany - var selectManySource = methodCallExpression.Arguments[0]; - if (selectManySource is MethodCallExpression { Method.IsGenericMethod: true } groupJoinMethod - && groupJoinMethod.Method.GetGenericMethodDefinition() == QueryableMethods.GroupJoin) + case + { + Method: { Name: nameof(Queryable.SelectMany), IsGenericMethod: true } selectManyMethod, + Arguments: + [ + MethodCallExpression + { + Method: { Name: nameof(QueryableMethods.GroupJoin), IsGenericMethod: true } groupJoinMethod, + Arguments: { Count: 5 } groupJoinArguments + }, + _, + _ + ] selectManyArguments + } + when selectManyMethod.GetGenericMethodDefinition() == QueryableMethods.SelectManyWithCollectionSelector + && groupJoinMethod.GetGenericMethodDefinition() == QueryableMethods.GroupJoin: { - // GroupJoin - var outer = groupJoinMethod.Arguments[0]; - var inner = groupJoinMethod.Arguments[1]; - var outerKeySelector = groupJoinMethod.Arguments[2].UnwrapLambdaFromQuote(); - var innerKeySelector = groupJoinMethod.Arguments[3].UnwrapLambdaFromQuote(); - var groupJoinResultSelector = groupJoinMethod.Arguments[4].UnwrapLambdaFromQuote(); + var outer = groupJoinArguments[0]; + var inner = groupJoinArguments[1]; + var outerKeySelector = groupJoinArguments[2].UnwrapLambdaFromQuote(); + var innerKeySelector = groupJoinArguments[3].UnwrapLambdaFromQuote(); + var groupJoinResultSelector = groupJoinArguments[4].UnwrapLambdaFromQuote(); - var selectManyCollectionSelector = methodCallExpression.Arguments[1].UnwrapLambdaFromQuote(); - var selectManyResultSelector = methodCallExpression.Arguments[2].UnwrapLambdaFromQuote(); + var selectManyCollectionSelector = selectManyArguments[1].UnwrapLambdaFromQuote(); + var selectManyResultSelector = selectManyArguments[2].UnwrapLambdaFromQuote(); var collectionSelectorBody = selectManyCollectionSelector.Body; var defaultIfEmpty = false; @@ -568,7 +613,7 @@ private MethodCallExpression TryFlattenGroupJoinSelectMany(MethodCallExpression resultSelectorBody, groupJoinResultSelector.Parameters[0], selectManyResultSelector.Parameters[1]); - var genericArguments = groupJoinMethod.Method.GetGenericArguments(); + var genericArguments = groupJoinMethod.GetGenericArguments(); genericArguments[^1] = resultSelector.ReturnType; return Expression.Call( @@ -576,6 +621,8 @@ private MethodCallExpression TryFlattenGroupJoinSelectMany(MethodCallExpression genericArguments), outer, inner, outerKeySelector, innerKeySelector, resultSelector); } + + break; // TODO: Convert correlated patterns to SelectMany //else //{ @@ -608,22 +655,30 @@ private MethodCallExpression TryFlattenGroupJoinSelectMany(MethodCallExpression // selectManyResultSelector.Parameters[1]); //} } - } - else if (genericMethod == QueryableMethods.SelectManyWithoutCollectionSelector) - { - // SelectMany - var selectManySource = methodCallExpression.Arguments[0]; - if (selectManySource is MethodCallExpression { Method.IsGenericMethod: true } groupJoinMethod - && groupJoinMethod.Method.GetGenericMethodDefinition() == QueryableMethods.GroupJoin) + + case + { + Method: { Name: nameof(Queryable.SelectMany), IsGenericMethod: true } selectManyMethod, + Arguments: + [ + MethodCallExpression + { + Method: { Name: nameof(QueryableMethods.GroupJoin), IsGenericMethod: true } groupJoinMethod, + Arguments: { Count: 5 } groupJoinArguments + }, + _ + ] selectManyArguments + } + when selectManyMethod.GetGenericMethodDefinition() == QueryableMethods.SelectManyWithoutCollectionSelector + && groupJoinMethod.GetGenericMethodDefinition() == QueryableMethods.GroupJoin: { - // GroupJoin - var outer = groupJoinMethod.Arguments[0]; - var inner = groupJoinMethod.Arguments[1]; - var outerKeySelector = groupJoinMethod.Arguments[2].UnwrapLambdaFromQuote(); - var innerKeySelector = groupJoinMethod.Arguments[3].UnwrapLambdaFromQuote(); - var groupJoinResultSelector = groupJoinMethod.Arguments[4].UnwrapLambdaFromQuote(); + var outer = groupJoinArguments[0]; + var inner = groupJoinArguments[1]; + var outerKeySelector = groupJoinArguments[2].UnwrapLambdaFromQuote(); + var innerKeySelector = groupJoinArguments[3].UnwrapLambdaFromQuote(); + var groupJoinResultSelector = groupJoinArguments[4].UnwrapLambdaFromQuote(); - var selectManyResultSelector = methodCallExpression.Arguments[1].UnwrapLambdaFromQuote(); + var selectManyResultSelector = selectManyArguments[1].UnwrapLambdaFromQuote(); var groupJoinResultSelectorBody = groupJoinResultSelector.Body; var defaultIfEmpty = false; @@ -658,7 +713,7 @@ private MethodCallExpression TryFlattenGroupJoinSelectMany(MethodCallExpression groupJoinResultSelector.Parameters[0], innerKeySelector.Parameters[0]); - var genericArguments = groupJoinMethod.Method.GetGenericArguments(); + var genericArguments = groupJoinMethod.GetGenericArguments(); genericArguments[^1] = resultSelector.ReturnType; return Expression.Call( @@ -666,6 +721,8 @@ private MethodCallExpression TryFlattenGroupJoinSelectMany(MethodCallExpression genericArguments), outer, inner, outerKeySelector, innerKeySelector, resultSelector); } + + break; } } diff --git a/src/EFCore/Query/Internal/SubqueryMemberPushdownExpressionVisitor.cs b/src/EFCore/Query/Internal/SubqueryMemberPushdownExpressionVisitor.cs index 8287b8e2c74..d61494b2650 100644 --- a/src/EFCore/Query/Internal/SubqueryMemberPushdownExpressionVisitor.cs +++ b/src/EFCore/Query/Internal/SubqueryMemberPushdownExpressionVisitor.cs @@ -48,9 +48,7 @@ public class SubqueryMemberPushdownExpressionVisitor : ExpressionVisitor /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SubqueryMemberPushdownExpressionVisitor(IModel model) - { - _model = model; - } + => _model = model; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/Query/LiftableConstantExpressionHelpers.cs b/src/EFCore/Query/LiftableConstantExpressionHelpers.cs index b7b6759fd41..36bb49df8d7 100644 --- a/src/EFCore/Query/LiftableConstantExpressionHelpers.cs +++ b/src/EFCore/Query/LiftableConstantExpressionHelpers.cs @@ -52,13 +52,14 @@ public static bool IsLiteral(object? value) { return value switch { - int or long or uint or ulong or short or sbyte or ushort or byte or double or float or decimal or string or char or bool => true, + int or long or uint or ulong or short or sbyte or ushort or byte or double or float or decimal or string or char + or bool => true, null or Type or Enum => true, TimeSpan or DateTime or DateTimeOffset or DateOnly or TimeOnly or Guid => true, ITuple tuple when tuple.GetType() is { IsGenericType: true } tupleType - && tupleType.Name.StartsWith("ValueTuple`", StringComparison.Ordinal) - && tupleType.Namespace == "System" + && tupleType.Name.StartsWith("ValueTuple`", StringComparison.Ordinal) + && tupleType.Namespace == "System" => IsTupleLiteral(tuple), Array array => IsCollectionOfLiterals(array), @@ -99,7 +100,9 @@ bool IsCollectionOfLiterals(IEnumerable enumerable) /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public static Expression BuildMemberAccessForEntityOrComplexType(ITypeBase targetType, ParameterExpression liftableConstantContextParameter) + public static Expression BuildMemberAccessForEntityOrComplexType( + ITypeBase targetType, + ParameterExpression liftableConstantContextParameter) { var (rootEntityType, complexTypes) = FindPathForEntityOrComplexType(targetType); @@ -117,7 +120,6 @@ public static Expression BuildMemberAccessForEntityOrComplexType(ITypeBase targe typeof(RuntimeModel)), RuntimeModelFindAdHocEntiyTypeMethod, Constant(rootEntityType.ClrType)); - } else { @@ -148,7 +150,8 @@ public static Expression BuildMemberAccessForEntityOrComplexType(ITypeBase targe /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public static Expression> BuildMemberAccessLambdaForEntityOrComplexType(ITypeBase type) + public static Expression> BuildMemberAccessLambdaForEntityOrComplexType( + ITypeBase type) { var prm = Parameter(typeof(MaterializerLiftableConstantContext)); var body = BuildMemberAccessForEntityOrComplexType(type, prm); @@ -255,7 +258,8 @@ public static Expression BuildClrCollectionAccessor(INavigationBase? navigation, /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public static Expression> BuildClrCollectionAccessorLambda(INavigationBase? navigation) + public static Expression> BuildClrCollectionAccessorLambda( + INavigationBase? navigation) { var prm = Parameter(typeof(MaterializerLiftableConstantContext)); var body = BuildClrCollectionAccessor(navigation, prm); diff --git a/src/EFCore/Query/LiftableConstantProcessor.cs b/src/EFCore/Query/LiftableConstantProcessor.cs index ce54ece9eb0..54388417604 100644 --- a/src/EFCore/Query/LiftableConstantProcessor.cs +++ b/src/EFCore/Query/LiftableConstantProcessor.cs @@ -21,7 +21,10 @@ public class LiftableConstantProcessor : ExpressionVisitor, ILiftableConstantPro private readonly UnsupportedConstantChecker _unsupportedConstantChecker; private readonly MaterializerLiftableConstantContext _materializerLiftableConstantContext; - private sealed record LiftedConstant(ParameterExpression Parameter, Expression Expression, ParameterExpression? ReplacingParameter = null); + private sealed record LiftedConstant( + ParameterExpression Parameter, + Expression Expression, + ParameterExpression? ReplacingParameter = null); private readonly List _liftedConstants = new(); private readonly LiftedExpressionProcessor _liftedExpressionProcessor = new(); @@ -42,8 +45,8 @@ private sealed record LiftedConstant(ParameterExpression Parameter, Expression E public LiftableConstantProcessor(ShapedQueryCompilingExpressionVisitorDependencies dependencies) { - _materializerLiftableConstantContext = new(dependencies); - _unsupportedConstantChecker = new(this); + _materializerLiftableConstantContext = new MaterializerLiftableConstantContext(dependencies); + _unsupportedConstantChecker = new UnsupportedConstantChecker(this); _liftedConstants.Clear(); } @@ -116,7 +119,8 @@ public virtual Expression LiftConstants(Expression expression, ParameterExpressi { // This lifted constant is being removed, since it's a duplicate of another with the same expression. // We still need to remap the parameter in the expression, but no uniquification etc. - replacedParameters.Add(liftedConstant.Parameter, + replacedParameters.Add( + liftedConstant.Parameter, replacedParameters.TryGetValue(liftedConstant.ReplacingParameter, out var replacedReplacingParameter) ? replacedReplacingParameter : liftedConstant.ReplacingParameter); @@ -155,6 +159,7 @@ public virtual Expression LiftConstants(Expression expression, ParameterExpressi newParameters[index] = newParameter; index++; } + var remappedExpression = ReplacingExpressionVisitor.Replace(originalParameters, newParameters, expressionAfterLifting); for (var i = 0; i < _liftedConstants.Count; i++) @@ -226,7 +231,7 @@ protected virtual ParameterExpression LiftConstant(LiftableConstantExpression li // Register the lifted constant; note that the name will be uniquified later var variableParameter = Expression.Parameter(liftableConstant.Type, liftableConstant.VariableName); - _liftedConstants.Add(new(variableParameter, body)); + _liftedConstants.Add(new LiftedConstant(variableParameter, body)); return variableParameter; } @@ -239,8 +244,8 @@ protected override Expression VisitBinary(BinaryExpression binaryExpression) return binaryExpression.NodeType is ExpressionType.Assign && left is MemberExpression { Member: FieldInfo { IsInitOnly: true } } initFieldMember - ? initFieldMember.Assign(right) - : binaryExpression.Update(left, conversion, right); + ? initFieldMember.Assign(right) + : binaryExpression.Update(left, conversion, right); } #if DEBUG @@ -274,17 +279,16 @@ protected override Expression VisitConstant(ConstantExpression node) if (LiftableConstantExpressionHelpers.IsLiteral(node.Value) // TODO: this part is temporary - we can't inline these constants but we need proper way to deal with them, // without risk breaking existing scenarios - || node.Value is ParameterBindingInfo or RuntimeServiceProperty or IMaterializationInterceptor or IInstantiationBindingInterceptor + || node.Value is ParameterBindingInfo or RuntimeServiceProperty or IMaterializationInterceptor + or IInstantiationBindingInterceptor || node.Type.Name is "ProxyFactory" or "Point") { return node; } - else - { - throw new InvalidOperationException( - $"Shaper expression contains a non-literal constant of type '{node.Value!.GetType().Name}'. " + - $"Use a {nameof(LiftableConstantExpression)} to reference any non-literal constants."); - } + + throw new InvalidOperationException( + $"Shaper expression contains a non-literal constant of type '{node.Value!.GetType().Name}'. " + + $"Use a {nameof(LiftableConstantExpression)} to reference any non-literal constants."); } } @@ -293,6 +297,7 @@ private sealed class LiftedConstantOptimizer : ExpressionVisitor private List _liftedConstants = null!; private sealed record ExpressionInfo(ExpressionStatus Status, ParameterExpression? Parameter = null, string? PreferredName = null); + private readonly Dictionary _indexedExpressions = new(ExpressionEqualityComparer.Instance); private LiftedConstant _currentLiftedConstant = null!; private bool _firstPass; @@ -322,7 +327,8 @@ public void Optimize(List liftedConstants) continue; } - Check.DebugAssert(expressionInfo.Status == ExpressionStatus.SeenMultipleTimes, + Check.DebugAssert( + expressionInfo.Status == ExpressionStatus.SeenMultipleTimes, "expressionInfo.Status == ExpressionStatus.SeenMultipleTimes"); } @@ -370,7 +376,7 @@ public void Optimize(List liftedConstants) if (!_indexedExpressions.TryGetValue(node, out var expressionInfo)) { // Unseen expression, add it to the dictionary with a null value, to indicate it's only a candidate at this point. - _indexedExpressions[node] = new(ExpressionStatus.SeenOnce, PreferredName: preferredName); + _indexedExpressions[node] = new ExpressionInfo(ExpressionStatus.SeenOnce, PreferredName: preferredName); return base.Visit(node); } @@ -381,8 +387,7 @@ public void Optimize(List liftedConstants) // This is the 2nd time we're seeing the expression - mark it as a common denominator _indexedExpressions[node] = _indexedExpressions[node] with { - Status = ExpressionStatus.SeenMultipleTimes, - PreferredName = preferredName + Status = ExpressionStatus.SeenMultipleTimes, PreferredName = preferredName }; } @@ -403,24 +408,25 @@ public void Optimize(List liftedConstants) // use that as the "extracted" parameter further down. if (ReferenceEquals(node, _currentLiftedConstant.Expression)) { - _indexedExpressions[node] = new(ExpressionStatus.Extracted, _currentLiftedConstant.Parameter); + _indexedExpressions[node] = new ExpressionInfo(ExpressionStatus.Extracted, _currentLiftedConstant.Parameter); return base.Visit(node); } // Otherwise, we need to extract a new variable, integrating it just before this one. - var parameter = Expression.Parameter(node.Type, node switch - { - _ when expressionInfo.PreferredName is not null => expressionInfo.PreferredName, - MemberExpression me => char.ToLowerInvariant(me.Member.Name[0]) + me.Member.Name[1..], - MethodCallExpression mce => char.ToLowerInvariant(mce.Method.Name[0]) + mce.Method.Name[1..], - _ => "unknown" - }); + var parameter = Expression.Parameter( + node.Type, node switch + { + _ when expressionInfo.PreferredName is not null => expressionInfo.PreferredName, + MemberExpression me => char.ToLowerInvariant(me.Member.Name[0]) + me.Member.Name[1..], + MethodCallExpression mce => char.ToLowerInvariant(mce.Method.Name[0]) + mce.Method.Name[1..], + _ => "unknown" + }); var visitedNode = base.Visit(node); - _liftedConstants.Insert(_index++, new(parameter, visitedNode)); + _liftedConstants.Insert(_index++, new LiftedConstant(parameter, visitedNode)); // Mark this node as having been extracted, to prevent it from getting extracted again - expressionInfo = _indexedExpressions[node] = new(ExpressionStatus.Extracted, parameter); + expressionInfo = _indexedExpressions[node] = new ExpressionInfo(ExpressionStatus.Extracted, parameter); } Check.DebugAssert(expressionInfo.Parameter is not null, "expressionInfo.Parameter is not null"); diff --git a/src/EFCore/Query/NavigationExpansionExtensibilityHelper.cs b/src/EFCore/Query/NavigationExpansionExtensibilityHelper.cs index 742cdd944f0..fe6d5fa5f8c 100644 --- a/src/EFCore/Query/NavigationExpansionExtensibilityHelper.cs +++ b/src/EFCore/Query/NavigationExpansionExtensibilityHelper.cs @@ -11,9 +11,7 @@ public class NavigationExpansionExtensibilityHelper : INavigationExpansionExtens /// /// Parameter object containing dependencies for this class. public NavigationExpansionExtensibilityHelper(NavigationExpansionExtensibilityHelperDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Query/ParameterQueryRootExpression.cs b/src/EFCore/Query/ParameterQueryRootExpression.cs index 63038a28099..ffb2ad27cab 100644 --- a/src/EFCore/Query/ParameterQueryRootExpression.cs +++ b/src/EFCore/Query/ParameterQueryRootExpression.cs @@ -30,9 +30,7 @@ public ParameterQueryRootExpression( Type elementType, ParameterExpression parameterExpression) : base(asyncQueryProvider, elementType) - { - ParameterExpression = parameterExpression; - } + => ParameterExpression = parameterExpression; /// /// Creates a new instance of the class. @@ -41,9 +39,7 @@ public ParameterQueryRootExpression( /// The parameter expression representing the values for this query root. public ParameterQueryRootExpression(Type elementType, ParameterExpression parameterExpression) : base(elementType) - { - ParameterExpression = parameterExpression; - } + => ParameterExpression = parameterExpression; /// public override Expression DetachQueryProvider() diff --git a/src/EFCore/Query/ProjectionMember.cs b/src/EFCore/Query/ProjectionMember.cs index 4d79151679a..78f59a2730e 100644 --- a/src/EFCore/Query/ProjectionMember.cs +++ b/src/EFCore/Query/ProjectionMember.cs @@ -24,14 +24,10 @@ public sealed class ProjectionMember /// Creates a new instance of the class with empty MemberInfo chain. /// public ProjectionMember() - { - _memberChain = new List(); - } + => _memberChain = new List(); private ProjectionMember(IList memberChain) - { - _memberChain = memberChain; - } + => _memberChain = memberChain; /// /// Append given MemberInfo to existing chain at the end. diff --git a/src/EFCore/Query/QueryCompilationContext.cs b/src/EFCore/Query/QueryCompilationContext.cs index 4c1784f9721..651cefa1341 100644 --- a/src/EFCore/Query/QueryCompilationContext.cs +++ b/src/EFCore/Query/QueryCompilationContext.cs @@ -62,7 +62,19 @@ public class QueryCompilationContext /// not used in application code. /// /// - public virtual HashSet ParametersToConstantize { get; } = new(StringComparer.Ordinal); + public virtual ISet ParametersToConstantize { get; } = new HashSet(StringComparer.Ordinal); + + /// + /// + /// Names of parameters on which was used. Such parameters are later not transformed into + /// constants even when parameterized collection constantization is configured as the default. + /// + /// + /// This property is typically used by database providers (and other extensions). It is generally + /// not used in application code. + /// + /// + public virtual ISet ParametersToNotConstantize { get; } = new HashSet(StringComparer.Ordinal); private static readonly IReadOnlySet EmptySet = new HashSet(); @@ -117,7 +129,7 @@ public QueryCompilationContext( _queryableMethodTranslatingExpressionVisitorFactory = dependencies.QueryableMethodTranslatingExpressionVisitorFactory; _queryTranslationPostprocessorFactory = dependencies.QueryTranslationPostprocessorFactory; _shapedQueryCompilingExpressionVisitorFactory = dependencies.ShapedQueryCompilingExpressionVisitorFactory; - _runtimeParameterConstantLifter = new(dependencies.LiftableConstantFactory); + _runtimeParameterConstantLifter = new RuntimeParameterConstantLifter(dependencies.LiftableConstantFactory); } /// @@ -194,10 +206,12 @@ public virtual void AddTag(string tag) => Tags.Add(tag); /// - /// A value indicating whether the provider supports precompiled query. Default value is . Providers that do support this feature should opt-in by setting this value to . + /// A value indicating whether the provider supports precompiled query. Default value is . Providers that do + /// support this feature should opt-in by setting this value to . /// [Experimental(EFDiagnostics.PrecompiledQueryExperimental)] - public virtual bool SupportsPrecompiledQuery => false; + public virtual bool SupportsPrecompiledQuery + => false; /// /// Creates the query executor func which gives results for this query. @@ -214,7 +228,8 @@ public virtual Func CreateQueryExecutor(Expressi // In normal mode, these nodes should simply be evaluated, and a ConstantExpression to those instances embedded directly in the // tree (for precompiled queries we generate C# code for resolving those instances instead). var queryExecutorAfterLiftingExpression = - (Expression>)Dependencies.LiftableConstantProcessor.InlineConstants(queryExecutorExpression, SupportsPrecompiledQuery); + (Expression>)Dependencies.LiftableConstantProcessor.InlineConstants( + queryExecutorExpression, SupportsPrecompiledQuery); try { @@ -312,7 +327,8 @@ void IPrintableExpression.Print(ExpressionPrinter expressionPrinter) private sealed class RuntimeParameterConstantLifter(ILiftableConstantFactory liftableConstantFactory) : ExpressionVisitor { - private static readonly MethodInfo ComplexPropertyListElementAddMethod = typeof(List).GetMethod(nameof(List.Add))!; + private static readonly MethodInfo ComplexPropertyListElementAddMethod = + typeof(List).GetMethod(nameof(List.Add))!; protected override Expression VisitConstant(ConstantExpression constantExpression) { @@ -335,7 +351,8 @@ protected override Expression VisitConstant(ConstantExpression constantExpressio for (var i = 0; i < complexPropertyChain.Count; i++) { var complexType = complexPropertyChain[i].ComplexType; - var complexTypeExpression = LiftableConstantExpressionHelpers.BuildMemberAccessForEntityOrComplexType(complexType, prm); + var complexTypeExpression = + LiftableConstantExpressionHelpers.BuildMemberAccessForEntityOrComplexType(complexType, prm); elementInitExpressions[i] = Expression.ElementInit( ComplexPropertyListElementAddMethod, Expression.Property(complexTypeExpression, nameof(IComplexType.ComplexProperty))); diff --git a/src/EFCore/Query/QueryCompilationContextDependencies.cs b/src/EFCore/Query/QueryCompilationContextDependencies.cs index 3df7db3a297..77ff8589d13 100644 --- a/src/EFCore/Query/QueryCompilationContextDependencies.cs +++ b/src/EFCore/Query/QueryCompilationContextDependencies.cs @@ -119,7 +119,7 @@ public QueryTrackingBehavior QueryTrackingBehavior public IShapedQueryCompilingExpressionVisitorFactory ShapedQueryCompilingExpressionVisitorFactory { get; init; } /// - /// TODO + /// TODO /// public ILiftableConstantFactory LiftableConstantFactory { get; init; } diff --git a/src/EFCore/Query/QueryContext.cs b/src/EFCore/Query/QueryContext.cs index ef368d3a2f2..9237d7ff653 100644 --- a/src/EFCore/Query/QueryContext.cs +++ b/src/EFCore/Query/QueryContext.cs @@ -125,10 +125,10 @@ public virtual void InitializeStateManager(bool standAlone = false) /// [EntityFrameworkInternal] public virtual InternalEntityEntry? TryGetEntry( - IKey key, - object[] keyValues, - bool throwOnNullKey, - out bool hasNullKey) + IKey key, + object[] keyValues, + bool throwOnNullKey, + out bool hasNullKey) // InitializeStateManager will populate the field before calling here => _stateManager!.TryGetEntry(key, keyValues, throwOnNullKey, out hasNullKey); diff --git a/src/EFCore/Query/QueryHelpers.cs b/src/EFCore/Query/QueryHelpers.cs new file mode 100644 index 00000000000..023544f3098 --- /dev/null +++ b/src/EFCore/Query/QueryHelpers.cs @@ -0,0 +1,63 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics.CodeAnalysis; + +namespace Microsoft.EntityFrameworkCore.Query; + +/// +/// Various helpers for query translation. +/// +public static class QueryHelpers +{ + /// + /// Returns whether the given expression represents a member access and if so, returns the decomposed base expression and the member + /// identity. + /// + /// The expression to check. + /// The model being used. + /// The given expression, with the top-level member access node removed. + /// + /// if represents a member access, otherwise. + /// + public static bool IsMemberAccess( + Expression expression, + IModel model, + [NotNullWhen(true)] out Expression? baseExpression) + => IsMemberAccess(expression, model, out baseExpression, out _); + + /// + /// Returns whether the given expression represents a member access and if so, returns the decomposed base expression and the member + /// identity. + /// + /// The expression to check. + /// The model being used. + /// The given expression, with the top-level member access node removed. + /// A representing the member being accessed. + /// + /// if represents a member access, otherwise. + /// + public static bool IsMemberAccess( + Expression expression, + IModel model, + [NotNullWhen(true)] out Expression? baseExpression, + out MemberIdentity memberIdentity) + { + switch (expression) + { + case MemberExpression { Expression: not null } member: + baseExpression = member.Expression; + memberIdentity = MemberIdentity.Create(member.Member); + return true; + case MethodCallExpression methodCall + when methodCall.TryGetEFPropertyArguments(out baseExpression, out var propertyName) + || methodCall.TryGetIndexerArguments(model, out baseExpression, out propertyName): + memberIdentity = MemberIdentity.Create(propertyName); + return true; + default: + memberIdentity = MemberIdentity.None; + baseExpression = null; + return false; + } + } +} diff --git a/src/EFCore/Query/QueryRootProcessor.cs b/src/EFCore/Query/QueryRootProcessor.cs index eecb4f70089..ec87a57f35d 100644 --- a/src/EFCore/Query/QueryRootProcessor.cs +++ b/src/EFCore/Query/QueryRootProcessor.cs @@ -21,9 +21,7 @@ public class QueryRootProcessor : ExpressionVisitor public QueryRootProcessor( QueryTranslationPreprocessorDependencies dependencies, QueryCompilationContext queryCompilationContext) - { - _queryCompilationContext = queryCompilationContext; - } + => _queryCompilationContext = queryCompilationContext; /// protected override Expression VisitMethodCall(MethodCallExpression methodCallExpression) diff --git a/src/EFCore/Query/QueryTranslationPreprocessor.cs b/src/EFCore/Query/QueryTranslationPreprocessor.cs index 1047b540020..7b3978c1795 100644 --- a/src/EFCore/Query/QueryTranslationPreprocessor.cs +++ b/src/EFCore/Query/QueryTranslationPreprocessor.cs @@ -95,7 +95,7 @@ protected virtual Expression ProcessQueryRoots(Expression expression) => new QueryRootProcessor(Dependencies, QueryCompilationContext).Visit(expression); /// - /// A value indicating whether 'EF.Constant' are handled appropriately in postprocessing of query. + /// A value indicating whether 'EF.Constant' are handled appropriately in postprocessing of query. /// [Experimental(EFDiagnostics.ProviderExperimentalApi)] protected virtual bool IsEfConstantSupported diff --git a/src/EFCore/Query/QueryableMethodTranslatingExpressionVisitor.cs b/src/EFCore/Query/QueryableMethodTranslatingExpressionVisitor.cs index 4b33dfe6311..664b9496532 100644 --- a/src/EFCore/Query/QueryableMethodTranslatingExpressionVisitor.cs +++ b/src/EFCore/Query/QueryableMethodTranslatingExpressionVisitor.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.EntityFrameworkCore.Internal; +using static Microsoft.EntityFrameworkCore.Query.QueryHelpers; namespace Microsoft.EntityFrameworkCore.Query; @@ -558,9 +559,8 @@ Expression CheckTranslated(ShapedQueryExpression? translated) // The method isn't a LINQ operator on Queryable/QueryableExtensions. // Identify property access, e.g. primitive collection property (context.Blogs.Where(b => b.Tags.Contains(...))) - if ((methodCallExpression.TryGetEFPropertyArguments(out var propertyAccessSource, out var propertyName) - || methodCallExpression.TryGetIndexerArguments(QueryCompilationContext.Model, out propertyAccessSource, out propertyName)) - && TranslateMemberAccess(propertyAccessSource, MemberIdentity.Create(propertyName)) is ShapedQueryExpression translation) + if (IsMemberAccess(methodCallExpression, QueryCompilationContext.Model, out var propertyAccessSource, out var propertyName) + && TranslateMemberAccess(propertyAccessSource, propertyName) is ShapedQueryExpression translation) { return translation; } @@ -569,7 +569,8 @@ Expression CheckTranslated(ShapedQueryExpression? translated) ? QueryCompilationContext.NotTranslatedExpression : TranslationErrorDetails is null ? throw new InvalidOperationException(CoreStrings.TranslationFailed(methodCallExpression.Print())) - : throw new InvalidOperationException(CoreStrings.TranslationFailedWithDetails(methodCallExpression.Print(), TranslationErrorDetails)); + : throw new InvalidOperationException( + CoreStrings.TranslationFailedWithDetails(methodCallExpression.Print(), TranslationErrorDetails)); } private sealed class EntityShaperNullableMarkingExpressionVisitor : ExpressionVisitor @@ -673,7 +674,7 @@ protected virtual Expression MarkShaperNullable(Expression shaperExpression) /// The shaped query on which the operator is applied. /// The predicate supplied in the call. /// The shaped query after translation. - protected abstract ShapedQueryExpression? TranslateCount(ShapedQueryExpression source, LambdaExpression? predicate); + protected abstract ShapedQueryExpression? TranslateCount(ShapedQueryExpression source, LambdaExpression? predicate); /// /// Translates method and other overloads over the given source. diff --git a/src/EFCore/Query/QueryableMethods.cs b/src/EFCore/Query/QueryableMethods.cs index 6d0c6a74950..07c60caa9e4 100644 --- a/src/EFCore/Query/QueryableMethods.cs +++ b/src/EFCore/Query/QueryableMethods.cs @@ -238,6 +238,11 @@ public static class QueryableMethods /// public static MethodInfo OfType { get; } + /// + /// The for + /// + public static MethodInfo Order { get; } + /// /// The for /// @@ -253,6 +258,11 @@ public static class QueryableMethods //public static MethodInfo OrderByDescendingWithComparer { get; } + /// + /// The for + /// + public static MethodInfo OrderDescending { get; } + /// /// The for /// @@ -656,6 +666,13 @@ static QueryableMethods() OfType = GetMethod(nameof(Queryable.OfType), 1, types => [typeof(IQueryable)]); + Order = GetMethod( + nameof(Queryable.Order), 1, + types => + [ + typeof(IQueryable<>).MakeGenericType(types[0]) + ]); + OrderBy = GetMethod( nameof(Queryable.OrderBy), 2, types => @@ -672,6 +689,13 @@ static QueryableMethods() typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(types[0], types[1])) ]); + OrderDescending = GetMethod( + nameof(Queryable.OrderDescending), 1, + types => + [ + typeof(IQueryable<>).MakeGenericType(types[0]) + ]); + Reverse = GetMethod(nameof(Queryable.Reverse), 1, types => [typeof(IQueryable<>).MakeGenericType(types[0])]); Select = GetMethod( diff --git a/src/EFCore/Query/ReplacingExpressionVisitor.cs b/src/EFCore/Query/ReplacingExpressionVisitor.cs index 618ab4e98fa..c78375f11fc 100644 --- a/src/EFCore/Query/ReplacingExpressionVisitor.cs +++ b/src/EFCore/Query/ReplacingExpressionVisitor.cs @@ -58,7 +58,8 @@ public ReplacingExpressionVisitor(IReadOnlyList originals, IReadOnly [return: NotNullIfNotNull(nameof(expression))] public override Expression? Visit(Expression? expression) { - if (expression is null or ShapedQueryExpression or StructuralTypeShaperExpression or GroupByShaperExpression or LiftableConstantExpression) + if (expression is null or ShapedQueryExpression or StructuralTypeShaperExpression or GroupByShaperExpression + or LiftableConstantExpression) { return expression; } diff --git a/src/EFCore/Query/ShapedQueryCompilingExpressionVisitor.cs b/src/EFCore/Query/ShapedQueryCompilingExpressionVisitor.cs index 20fbae9e593..fbc596366bf 100644 --- a/src/EFCore/Query/ShapedQueryCompilingExpressionVisitor.cs +++ b/src/EFCore/Query/ShapedQueryCompilingExpressionVisitor.cs @@ -1,11 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; -using Microsoft.EntityFrameworkCore.Diagnostics.Internal; -using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata.Internal; using static System.Linq.Expressions.Expression; @@ -63,8 +60,8 @@ protected ShapedQueryCompilingExpressionVisitor( queryCompilationContext.QueryTrackingBehavior, queryCompilationContext.SupportsPrecompiledQuery); - _constantVerifyingExpressionVisitor = new(dependencies.TypeMappingSource); - _materializationConditionConstantLifter = new(dependencies.LiftableConstantFactory); + _constantVerifyingExpressionVisitor = new ConstantVerifyingExpressionVisitor(dependencies.TypeMappingSource); + _materializationConditionConstantLifter = new MaterializationConditionConstantLifter(dependencies.LiftableConstantFactory); if (queryCompilationContext.IsAsync) { @@ -253,8 +250,8 @@ protected override Expression VisitBinary(BinaryExpression binaryExpression) return binaryExpression.NodeType is ExpressionType.Assign && left is MemberExpression { Member: FieldInfo { IsInitOnly: true } } initFieldMember - ? initFieldMember.Assign(right) - : binaryExpression.Update(left, conversion, right); + ? initFieldMember.Assign(right) + : binaryExpression.Update(left, conversion, right); } protected override Expression VisitExtension(Expression node) @@ -391,7 +388,9 @@ private static readonly MethodInfo CreateNullKeyValueInNoTrackingQueryMethod private static readonly MethodInfo EntityTypeFindPrimaryKeyMethod = typeof(IEntityType).GetMethod(nameof(IEntityType.FindPrimaryKey), [])!; - private readonly bool _queryStateManager = queryTrackingBehavior is QueryTrackingBehavior.TrackAll or QueryTrackingBehavior.NoTrackingWithIdentityResolution; + private readonly bool _queryStateManager = + queryTrackingBehavior is QueryTrackingBehavior.TrackAll or QueryTrackingBehavior.NoTrackingWithIdentityResolution; + private readonly ISet _visitedEntityTypes = new HashSet(); private readonly MaterializationConditionConstantLifter _materializationConditionConstantLifter = new(liftableConstantFactory); private int _currentEntityIndex; @@ -474,16 +473,17 @@ private Expression ProcessEntityShaper(StructuralTypeShaperExpression shaper) QueryCompilationContext.QueryContextParameter, TryGetEntryMethodInfo, supportsPrecompiledQuery - ? liftableConstantFactory.CreateLiftableConstant( - primaryKey, - Lambda>( - Call( - LiftableConstantExpressionHelpers.BuildMemberAccessForEntityOrComplexType(typeBase, resolverPrm), - EntityTypeFindPrimaryKeyMethod), - resolverPrm), - /*typeBase.Name +*/ "key", - typeof(IKey)) - : Constant(primaryKey), + ? liftableConstantFactory.CreateLiftableConstant( + primaryKey, + Lambda>( + Call( + LiftableConstantExpressionHelpers.BuildMemberAccessForEntityOrComplexType( + typeBase, resolverPrm), + EntityTypeFindPrimaryKeyMethod), + resolverPrm), + /*typeBase.Name +*/ "key", + typeof(IKey)) + : Constant(primaryKey), NewArrayInit( typeof(object), primaryKey.Properties @@ -556,25 +556,26 @@ private Expression ProcessEntityShaper(StructuralTypeShaperExpression shaper) Call( CreateNullKeyValueInNoTrackingQueryMethod, supportsPrecompiledQuery - ? liftableConstantFactory.CreateLiftableConstant( - typeBase, - LiftableConstantExpressionHelpers.BuildMemberAccessLambdaForEntityOrComplexType(typeBase), - typeBase.Name + "EntityType", - typeof(IEntityType)) - : Constant(typeBase), + ? liftableConstantFactory.CreateLiftableConstant( + typeBase, + LiftableConstantExpressionHelpers.BuildMemberAccessLambdaForEntityOrComplexType(typeBase), + typeBase.Name + "EntityType", + typeof(IEntityType)) + : Constant(typeBase), supportsPrecompiledQuery - ? liftableConstantFactory.CreateLiftableConstant( - primaryKey.Properties, - Lambda>( - Property( - Call( - LiftableConstantExpressionHelpers.BuildMemberAccessForEntityOrComplexType(typeBase, resolverPrm), - EntityTypeFindPrimaryKeyMethod), - nameof(IKey.Properties)), - resolverPrm), - typeBase.Name + "PrimaryKeyProperties", - typeof(IReadOnlyList)) - : Constant(primaryKey.Properties), + ? liftableConstantFactory.CreateLiftableConstant( + primaryKey.Properties, + Lambda>( + Property( + Call( + LiftableConstantExpressionHelpers.BuildMemberAccessForEntityOrComplexType( + typeBase, resolverPrm), + EntityTypeFindPrimaryKeyMethod), + nameof(IKey.Properties)), + resolverPrm), + typeBase.Name + "PrimaryKeyProperties", + typeof(IReadOnlyList)) + : Constant(primaryKey.Properties), keyValuesVariable)))); } } @@ -611,12 +612,12 @@ private Expression MaterializeEntity( Assign( shadowValuesVariable, supportsPrecompiledQuery - ? liftableConstantFactory.CreateLiftableConstant( - Snapshot.Empty, - static _ => Snapshot.Empty, - "emptySnapshot", - typeof(ISnapshot)) - : Constant(Snapshot.Empty, typeof(ISnapshot)))); + ? liftableConstantFactory.CreateLiftableConstant( + Snapshot.Empty, + static _ => Snapshot.Empty, + "emptySnapshot", + typeof(ISnapshot)) + : Constant(Snapshot.Empty, typeof(ISnapshot)))); var returnType = typeBase.ClrType; var valueBufferExpression = Call(materializationContextVariable, MaterializationContext.GetValueBufferMethod); @@ -640,12 +641,12 @@ private Expression MaterializeEntity( switchCases[i] = SwitchCase( CreateFullMaterializeExpression(concreteEntityTypes[i], expressionContext), supportsPrecompiledQuery - ? liftableConstantFactory.CreateLiftableConstant( - concreteEntityTypes[i], - LiftableConstantExpressionHelpers.BuildMemberAccessLambdaForEntityOrComplexType(concreteEntityType), - concreteEntityType.ShortName() + (typeBase is IEntityType ? "EntityType" : "ComplexType"), - typeBase is IEntityType ? typeof(IEntityType) : typeof(IComplexType)) - : Constant(concreteEntityTypes[i], typeBase is IEntityType ? typeof(IEntityType) : typeof(IComplexType))); + ? liftableConstantFactory.CreateLiftableConstant( + concreteEntityTypes[i], + LiftableConstantExpressionHelpers.BuildMemberAccessLambdaForEntityOrComplexType(concreteEntityType), + concreteEntityType.ShortName() + (typeBase is IEntityType ? "EntityType" : "ComplexType"), + typeBase is IEntityType ? typeof(IEntityType) : typeof(IComplexType)) + : Constant(concreteEntityTypes[i], typeBase is IEntityType ? typeof(IEntityType) : typeof(IComplexType))); } var materializationExpression = Switch( @@ -722,12 +723,15 @@ private BlockExpression CreateFullMaterializeExpression( blockExpressions.Add( Assign( shadowValuesVariable, - ShadowValuesFactoryFactory.Instance.CreateConstructorExpression(runtimeEntityType, + ShadowValuesFactoryFactory.Instance.CreateConstructorExpression( + runtimeEntityType, NewArrayInit( typeof(object), - shadowProperties.Select(p => - Convert(valueBufferExpression.CreateValueBufferReadValueExpression( - p.ClrType, p.GetIndex(), p), typeof(object))))))); + shadowProperties.Select( + p => + Convert( + valueBufferExpression.CreateValueBufferReadValueExpression( + p.ClrType, p.GetIndex(), p), typeof(object))))))); } materializer = materializer.Type == returnType diff --git a/src/EFCore/Query/ShapedQueryCompilingExpressionVisitorDependencies.cs b/src/EFCore/Query/ShapedQueryCompilingExpressionVisitorDependencies.cs index a8eb8153921..df3c9d39bbb 100644 --- a/src/EFCore/Query/ShapedQueryCompilingExpressionVisitorDependencies.cs +++ b/src/EFCore/Query/ShapedQueryCompilingExpressionVisitorDependencies.cs @@ -111,7 +111,7 @@ public ShapedQueryCompilingExpressionVisitorDependencies( public IEnumerable SingletonInterceptors { get; init; } /// - /// TODO + /// TODO /// public IDbContextServices ContextServices { get; init; } } diff --git a/src/EFCore/Query/StructuralTypeShaperExpression.cs b/src/EFCore/Query/StructuralTypeShaperExpression.cs index 03d9ebde198..5a41c40663e 100644 --- a/src/EFCore/Query/StructuralTypeShaperExpression.cs +++ b/src/EFCore/Query/StructuralTypeShaperExpression.cs @@ -161,14 +161,14 @@ protected virtual LambdaExpression GenerateMaterializationCondition(ITypeBase ty discriminatorComparer.ExtractEqualsBody( discriminatorValueVariable, LiftableConstantExpressionHelpers.IsLiteral(discriminatorValueObject) - ? Constant( - discriminatorValueObject, - discriminatorProperty.ClrType) - : Convert( - Call( - Constant(concreteEntityTypes[i], typeof(IEntityType)), - GetDiscriminatorValueMethod), - discriminatorProperty.ClrType)), + ? Constant( + discriminatorValueObject, + discriminatorProperty.ClrType) + : Convert( + Call( + Constant(concreteEntityTypes[i], typeof(IEntityType)), + GetDiscriminatorValueMethod), + discriminatorProperty.ClrType)), Constant(concreteEntityTypes[i], typeof(IEntityType)), conditions); } diff --git a/src/EFCore/SaveChangesEventArgs.cs b/src/EFCore/SaveChangesEventArgs.cs index 7b8dd8ec591..9901e8995b5 100644 --- a/src/EFCore/SaveChangesEventArgs.cs +++ b/src/EFCore/SaveChangesEventArgs.cs @@ -18,9 +18,7 @@ public abstract class SaveChangesEventArgs : EventArgs /// /// The value passed to SaveChanges. protected SaveChangesEventArgs(bool acceptAllChangesOnSuccess) - { - AcceptAllChangesOnSuccess = acceptAllChangesOnSuccess; - } + => AcceptAllChangesOnSuccess = acceptAllChangesOnSuccess; /// /// The value passed to or . diff --git a/src/EFCore/SaveChangesFailedEventArgs.cs b/src/EFCore/SaveChangesFailedEventArgs.cs index 0ca88f139c9..694107febe8 100644 --- a/src/EFCore/SaveChangesFailedEventArgs.cs +++ b/src/EFCore/SaveChangesFailedEventArgs.cs @@ -19,9 +19,7 @@ public class SaveChangesFailedEventArgs : SaveChangesEventArgs /// The exception thrown. public SaveChangesFailedEventArgs(bool acceptAllChangesOnSuccess, Exception exception) : base(acceptAllChangesOnSuccess) - { - Exception = exception; - } + => Exception = exception; /// /// The exception thrown during or . diff --git a/src/EFCore/SavedChangesEventArgs.cs b/src/EFCore/SavedChangesEventArgs.cs index 488379073af..c892d33ff75 100644 --- a/src/EFCore/SavedChangesEventArgs.cs +++ b/src/EFCore/SavedChangesEventArgs.cs @@ -19,9 +19,7 @@ public class SavedChangesEventArgs : SaveChangesEventArgs /// The number of entities saved. public SavedChangesEventArgs(bool acceptAllChangesOnSuccess, int entitiesSavedCount) : base(acceptAllChangesOnSuccess) - { - EntitiesSavedCount = entitiesSavedCount; - } + => EntitiesSavedCount = entitiesSavedCount; /// /// The number of entities saved. diff --git a/src/EFCore/Storage/Database.cs b/src/EFCore/Storage/Database.cs index 9614e156bf5..6941247ec39 100644 --- a/src/EFCore/Storage/Database.cs +++ b/src/EFCore/Storage/Database.cs @@ -33,9 +33,7 @@ public abstract class Database : IDatabase /// /// Parameter object containing dependencies for this service. protected Database(DatabaseDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Storage/DatabaseProvider.cs b/src/EFCore/Storage/DatabaseProvider.cs index 85b027d2f46..fb2a34ceed1 100644 --- a/src/EFCore/Storage/DatabaseProvider.cs +++ b/src/EFCore/Storage/DatabaseProvider.cs @@ -35,9 +35,7 @@ public class DatabaseProvider : IDatabaseProvider /// /// Parameter object containing dependencies for this service. public DatabaseProvider(DatabaseProviderDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Storage/Json/JsonBoolReaderWriter.cs b/src/EFCore/Storage/Json/JsonBoolReaderWriter.cs index 6d444233f3a..d0ba2327c60 100644 --- a/src/EFCore/Storage/Json/JsonBoolReaderWriter.cs +++ b/src/EFCore/Storage/Json/JsonBoolReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Text.Json; namespace Microsoft.EntityFrameworkCore.Storage.Json; @@ -27,5 +26,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, bool value) => writer.WriteBooleanValue(value); /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore/Storage/Json/JsonByteArrayReaderWriter.cs b/src/EFCore/Storage/Json/JsonByteArrayReaderWriter.cs index 647d90d65ab..36adcb00cd2 100644 --- a/src/EFCore/Storage/Json/JsonByteArrayReaderWriter.cs +++ b/src/EFCore/Storage/Json/JsonByteArrayReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Text.Json; namespace Microsoft.EntityFrameworkCore.Storage.Json; @@ -31,5 +30,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, byte[] value) => writer.WriteBase64StringValue(value); /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore/Storage/Json/JsonByteReaderWriter.cs b/src/EFCore/Storage/Json/JsonByteReaderWriter.cs index be2f9c91d15..3364e436c21 100644 --- a/src/EFCore/Storage/Json/JsonByteReaderWriter.cs +++ b/src/EFCore/Storage/Json/JsonByteReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Text.Json; namespace Microsoft.EntityFrameworkCore.Storage.Json; @@ -31,5 +30,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, byte value) => writer.WriteNumberValue(value); /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore/Storage/Json/JsonCastValueReaderWriter.cs b/src/EFCore/Storage/Json/JsonCastValueReaderWriter.cs index 54fb8abd301..0998b03916d 100644 --- a/src/EFCore/Storage/Json/JsonCastValueReaderWriter.cs +++ b/src/EFCore/Storage/Json/JsonCastValueReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Text.Json; using Microsoft.EntityFrameworkCore.Storage.Internal; @@ -21,9 +20,7 @@ public class JsonCastValueReaderWriter : /// /// The underlying provider type reader/writer. public JsonCastValueReaderWriter(JsonValueReaderWriter providerReaderWriter) - { - _providerReaderWriter = providerReaderWriter; - } + => _providerReaderWriter = providerReaderWriter; /// public override TConverted FromJsonTyped(ref Utf8JsonReaderManager manager, object? existingObject = null) @@ -36,9 +33,10 @@ public override void ToJsonTyped(Utf8JsonWriter writer, TConverted value) JsonValueReaderWriter ICompositeJsonValueReaderWriter.InnerReaderWriter => _providerReaderWriter; - private readonly ConstructorInfo _constructorInfo = typeof(JsonCastValueReaderWriter).GetConstructor([typeof(JsonValueReaderWriter)])!; + private readonly ConstructorInfo _constructorInfo = + typeof(JsonCastValueReaderWriter).GetConstructor([typeof(JsonValueReaderWriter)])!; /// - public override Expression ConstructorExpression => - Expression.New(_constructorInfo, ((ICompositeJsonValueReaderWriter)this).InnerReaderWriter.ConstructorExpression); + public override Expression ConstructorExpression + => Expression.New(_constructorInfo, ((ICompositeJsonValueReaderWriter)this).InnerReaderWriter.ConstructorExpression); } diff --git a/src/EFCore/Storage/Json/JsonCharReaderWriter.cs b/src/EFCore/Storage/Json/JsonCharReaderWriter.cs index 2dd767e51b0..c778dcac17f 100644 --- a/src/EFCore/Storage/Json/JsonCharReaderWriter.cs +++ b/src/EFCore/Storage/Json/JsonCharReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Text.Json; namespace Microsoft.EntityFrameworkCore.Storage.Json; @@ -31,5 +30,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, char value) => writer.WriteStringValue(value.ToString()); /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore/Storage/Json/JsonCollectionOfNullableStructsReaderWriter.cs b/src/EFCore/Storage/Json/JsonCollectionOfNullableStructsReaderWriter.cs index 1161838a1d0..63f25b36e98 100644 --- a/src/EFCore/Storage/Json/JsonCollectionOfNullableStructsReaderWriter.cs +++ b/src/EFCore/Storage/Json/JsonCollectionOfNullableStructsReaderWriter.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.ObjectModel; -using System.Diagnostics.CodeAnalysis; using System.Text.Json; using Microsoft.EntityFrameworkCore.Storage.Internal; @@ -31,9 +30,7 @@ public class JsonCollectionOfNullableStructsReaderWriter /// The reader/writer to use for each element. public JsonCollectionOfNullableStructsReaderWriter(JsonValueReaderWriter elementReaderWriter) - { - _elementReaderWriter = elementReaderWriter; - } + => _elementReaderWriter = elementReaderWriter; /// public override IEnumerable FromJsonTyped(ref Utf8JsonReaderManager manager, object? existingObject = null) @@ -98,7 +95,7 @@ public JsonCollectionOfNullableStructsReaderWriter(JsonValueReaderWriter)Activator.CreateInstance(typeof(TConcreteCollection), [collection])! + : (IList)Activator.CreateInstance(typeof(TConcreteCollection), collection)! : collection; } @@ -125,9 +122,10 @@ JsonValueReaderWriter ICompositeJsonValueReaderWriter.InnerReaderWriter => _elementReaderWriter; private readonly ConstructorInfo _constructorInfo = - typeof(JsonCollectionOfNullableStructsReaderWriter).GetConstructor([typeof(JsonValueReaderWriter)])!; + typeof(JsonCollectionOfNullableStructsReaderWriter).GetConstructor( + [typeof(JsonValueReaderWriter)])!; /// - public override Expression ConstructorExpression => - Expression.New(_constructorInfo, ((ICompositeJsonValueReaderWriter)this).InnerReaderWriter.ConstructorExpression); + public override Expression ConstructorExpression + => Expression.New(_constructorInfo, ((ICompositeJsonValueReaderWriter)this).InnerReaderWriter.ConstructorExpression); } diff --git a/src/EFCore/Storage/Json/JsonCollectionOfReferencesReaderWriter.cs b/src/EFCore/Storage/Json/JsonCollectionOfReferencesReaderWriter.cs index 735e1f04103..f774fa738a1 100644 --- a/src/EFCore/Storage/Json/JsonCollectionOfReferencesReaderWriter.cs +++ b/src/EFCore/Storage/Json/JsonCollectionOfReferencesReaderWriter.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.ObjectModel; -using System.Diagnostics.CodeAnalysis; using System.Text.Json; using Microsoft.EntityFrameworkCore.Storage.Internal; @@ -31,9 +30,7 @@ public class JsonCollectionOfReferencesReaderWriter /// The reader/writer to use for each element. public JsonCollectionOfReferencesReaderWriter(JsonValueReaderWriter elementReaderWriter) - { - _elementReaderWriter = elementReaderWriter; - } + => _elementReaderWriter = elementReaderWriter; /// public override object FromJsonTyped(ref Utf8JsonReaderManager manager, object? existingObject = null) @@ -93,7 +90,7 @@ public override object FromJsonTyped(ref Utf8JsonReaderManager manager, object? return IsReadOnly ? IsArray ? collection.ToArray() - : (IList)Activator.CreateInstance(typeof(TConcreteCollection), [collection])! + : (IList)Activator.CreateInstance(typeof(TConcreteCollection), collection)! : collection; } @@ -122,9 +119,10 @@ public override void ToJsonTyped(Utf8JsonWriter writer, object? value) JsonValueReaderWriter ICompositeJsonValueReaderWriter.InnerReaderWriter => _elementReaderWriter; - private readonly ConstructorInfo _constructorInfo = typeof(JsonCollectionOfReferencesReaderWriter).GetConstructor([typeof(JsonValueReaderWriter)])!; + private readonly ConstructorInfo _constructorInfo = + typeof(JsonCollectionOfReferencesReaderWriter).GetConstructor([typeof(JsonValueReaderWriter)])!; /// - public override Expression ConstructorExpression => - Expression.New(_constructorInfo, ((ICompositeJsonValueReaderWriter)this).InnerReaderWriter.ConstructorExpression); + public override Expression ConstructorExpression + => Expression.New(_constructorInfo, ((ICompositeJsonValueReaderWriter)this).InnerReaderWriter.ConstructorExpression); } diff --git a/src/EFCore/Storage/Json/JsonCollectionOfStructsReaderWriter.cs b/src/EFCore/Storage/Json/JsonCollectionOfStructsReaderWriter.cs index bc68024cbfb..323e296d005 100644 --- a/src/EFCore/Storage/Json/JsonCollectionOfStructsReaderWriter.cs +++ b/src/EFCore/Storage/Json/JsonCollectionOfStructsReaderWriter.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.ObjectModel; -using System.Diagnostics.CodeAnalysis; using System.Text.Json; using Microsoft.EntityFrameworkCore.Storage.Internal; @@ -32,9 +31,7 @@ public class JsonCollectionOfStructsReaderWriter /// /// The reader/writer to use for each element. public JsonCollectionOfStructsReaderWriter(JsonValueReaderWriter elementReaderWriter) - { - _elementReaderWriter = elementReaderWriter; - } + => _elementReaderWriter = elementReaderWriter; /// public override IEnumerable FromJsonTyped(ref Utf8JsonReaderManager manager, object? existingObject = null) @@ -94,7 +91,7 @@ public override IEnumerable FromJsonTyped(ref Utf8JsonReaderManager ma return IsReadOnly ? IsArray ? collection.ToArray() - : (IList)Activator.CreateInstance(typeof(TConcreteCollection), [collection])! + : (IList)Activator.CreateInstance(typeof(TConcreteCollection), collection)! : collection; } @@ -113,9 +110,11 @@ public override void ToJsonTyped(Utf8JsonWriter writer, IEnumerable va JsonValueReaderWriter ICompositeJsonValueReaderWriter.InnerReaderWriter => _elementReaderWriter; - private readonly ConstructorInfo _constructorInfo = typeof(JsonCollectionOfStructsReaderWriter).GetConstructor([typeof(JsonValueReaderWriter)])!; + private readonly ConstructorInfo _constructorInfo = + typeof(JsonCollectionOfStructsReaderWriter).GetConstructor([typeof(JsonValueReaderWriter)]) + !; /// - public override Expression ConstructorExpression => - Expression.New(_constructorInfo, ((ICompositeJsonValueReaderWriter)this).InnerReaderWriter.ConstructorExpression); + public override Expression ConstructorExpression + => Expression.New(_constructorInfo, ((ICompositeJsonValueReaderWriter)this).InnerReaderWriter.ConstructorExpression); } diff --git a/src/EFCore/Storage/Json/JsonConvertedValueReaderWriter.cs b/src/EFCore/Storage/Json/JsonConvertedValueReaderWriter.cs index fc87150b3a6..07ced68e630 100644 --- a/src/EFCore/Storage/Json/JsonConvertedValueReaderWriter.cs +++ b/src/EFCore/Storage/Json/JsonConvertedValueReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Text.Json; using Microsoft.EntityFrameworkCore.Storage.Internal; @@ -47,11 +46,13 @@ JsonValueReaderWriter ICompositeJsonValueReaderWriter.InnerReaderWriter ValueConverter IJsonConvertedValueReaderWriter.Converter => _converter; - private readonly ConstructorInfo _constructorInfo = typeof(JsonConvertedValueReaderWriter).GetConstructor([typeof(JsonValueReaderWriter), typeof(ValueConverter)])!; + private readonly ConstructorInfo _constructorInfo = + typeof(JsonConvertedValueReaderWriter).GetConstructor( + [typeof(JsonValueReaderWriter), typeof(ValueConverter)])!; /// - public override Expression ConstructorExpression => - Expression.New( + public override Expression ConstructorExpression + => Expression.New( _constructorInfo, ((ICompositeJsonValueReaderWriter)this).InnerReaderWriter.ConstructorExpression, ((IJsonConvertedValueReaderWriter)this).Converter.ConstructorExpression); diff --git a/src/EFCore/Storage/Json/JsonDateOnlyReaderWriter.cs b/src/EFCore/Storage/Json/JsonDateOnlyReaderWriter.cs index 2bf454681b5..bbf7ab53c0e 100644 --- a/src/EFCore/Storage/Json/JsonDateOnlyReaderWriter.cs +++ b/src/EFCore/Storage/Json/JsonDateOnlyReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Text.Json; @@ -32,5 +31,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, DateOnly value) => writer.WriteStringValue(value.ToString("o", CultureInfo.InvariantCulture)); /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore/Storage/Json/JsonDateTimeOffsetReaderWriter.cs b/src/EFCore/Storage/Json/JsonDateTimeOffsetReaderWriter.cs index c7cf9c4ecf6..6efd193f2d1 100644 --- a/src/EFCore/Storage/Json/JsonDateTimeOffsetReaderWriter.cs +++ b/src/EFCore/Storage/Json/JsonDateTimeOffsetReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Text.Json; namespace Microsoft.EntityFrameworkCore.Storage.Json; @@ -31,5 +30,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, DateTimeOffset value) => writer.WriteStringValue(value); /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore/Storage/Json/JsonDateTimeReaderWriter.cs b/src/EFCore/Storage/Json/JsonDateTimeReaderWriter.cs index 7f9639cb262..36473172a89 100644 --- a/src/EFCore/Storage/Json/JsonDateTimeReaderWriter.cs +++ b/src/EFCore/Storage/Json/JsonDateTimeReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Text.Json; namespace Microsoft.EntityFrameworkCore.Storage.Json; @@ -31,5 +30,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, DateTime value) => writer.WriteStringValue(value); /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore/Storage/Json/JsonDecimalReaderWriter.cs b/src/EFCore/Storage/Json/JsonDecimalReaderWriter.cs index 56f2bec2071..864003f7464 100644 --- a/src/EFCore/Storage/Json/JsonDecimalReaderWriter.cs +++ b/src/EFCore/Storage/Json/JsonDecimalReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Text.Json; namespace Microsoft.EntityFrameworkCore.Storage.Json; @@ -31,5 +30,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, decimal value) => writer.WriteNumberValue(value); /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore/Storage/Json/JsonDoubleReaderWriter.cs b/src/EFCore/Storage/Json/JsonDoubleReaderWriter.cs index d85124773fc..e323555b28e 100644 --- a/src/EFCore/Storage/Json/JsonDoubleReaderWriter.cs +++ b/src/EFCore/Storage/Json/JsonDoubleReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Text.Json; namespace Microsoft.EntityFrameworkCore.Storage.Json; @@ -31,5 +30,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, double value) => writer.WriteNumberValue(value); /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore/Storage/Json/JsonFloatReaderWriter.cs b/src/EFCore/Storage/Json/JsonFloatReaderWriter.cs index 5a2260c91a5..1a26e8a242e 100644 --- a/src/EFCore/Storage/Json/JsonFloatReaderWriter.cs +++ b/src/EFCore/Storage/Json/JsonFloatReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Text.Json; namespace Microsoft.EntityFrameworkCore.Storage.Json; @@ -31,5 +30,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, float value) => writer.WriteNumberValue(value); /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore/Storage/Json/JsonGuidReaderWriter.cs b/src/EFCore/Storage/Json/JsonGuidReaderWriter.cs index a65ec19387c..5c6b8609c5d 100644 --- a/src/EFCore/Storage/Json/JsonGuidReaderWriter.cs +++ b/src/EFCore/Storage/Json/JsonGuidReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Text.Json; namespace Microsoft.EntityFrameworkCore.Storage.Json; @@ -31,5 +30,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, Guid value) => writer.WriteStringValue(value); /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore/Storage/Json/JsonInt16ReaderWriter.cs b/src/EFCore/Storage/Json/JsonInt16ReaderWriter.cs index b6b52798b86..e85c25d447b 100644 --- a/src/EFCore/Storage/Json/JsonInt16ReaderWriter.cs +++ b/src/EFCore/Storage/Json/JsonInt16ReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Text.Json; namespace Microsoft.EntityFrameworkCore.Storage.Json; @@ -31,5 +30,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, short value) => writer.WriteNumberValue(value); /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore/Storage/Json/JsonInt32ReaderWriter.cs b/src/EFCore/Storage/Json/JsonInt32ReaderWriter.cs index 65fbfe9ba24..d21d8502619 100644 --- a/src/EFCore/Storage/Json/JsonInt32ReaderWriter.cs +++ b/src/EFCore/Storage/Json/JsonInt32ReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Text.Json; namespace Microsoft.EntityFrameworkCore.Storage.Json; @@ -31,5 +30,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, int value) => writer.WriteNumberValue(value); /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore/Storage/Json/JsonInt64ReaderWriter.cs b/src/EFCore/Storage/Json/JsonInt64ReaderWriter.cs index 4a0b8b1f531..4e88395191d 100644 --- a/src/EFCore/Storage/Json/JsonInt64ReaderWriter.cs +++ b/src/EFCore/Storage/Json/JsonInt64ReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Text.Json; namespace Microsoft.EntityFrameworkCore.Storage.Json; @@ -31,5 +30,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, long value) => writer.WriteNumberValue(value); /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore/Storage/Json/JsonNullReaderWriter.cs b/src/EFCore/Storage/Json/JsonNullReaderWriter.cs index 38d4430dbea..1b361ae6ff4 100644 --- a/src/EFCore/Storage/Json/JsonNullReaderWriter.cs +++ b/src/EFCore/Storage/Json/JsonNullReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Text.Json; namespace Microsoft.EntityFrameworkCore.Storage.Json; @@ -31,5 +30,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, object? value) => writer.WriteNullValue(); /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore/Storage/Json/JsonReaderData.cs b/src/EFCore/Storage/Json/JsonReaderData.cs index 791a152faa8..9e9eb4317d5 100644 --- a/src/EFCore/Storage/Json/JsonReaderData.cs +++ b/src/EFCore/Storage/Json/JsonReaderData.cs @@ -62,7 +62,6 @@ public virtual Utf8JsonReader ReadBytes(int bytesConsumed, JsonReaderState state } else { - var buffer = _buffer; var totalConsumed = bytesConsumed + _positionInBuffer; if (_bytesAvailable != 0 && totalConsumed < buffer.Length) diff --git a/src/EFCore/Storage/Json/JsonSByteReaderWriter.cs b/src/EFCore/Storage/Json/JsonSByteReaderWriter.cs index 5b30f05ec4a..53f09feaad7 100644 --- a/src/EFCore/Storage/Json/JsonSByteReaderWriter.cs +++ b/src/EFCore/Storage/Json/JsonSByteReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Text.Json; namespace Microsoft.EntityFrameworkCore.Storage.Json; @@ -31,5 +30,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, sbyte value) => writer.WriteNumberValue(value); /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore/Storage/Json/JsonSignedEnumReaderWriter.cs b/src/EFCore/Storage/Json/JsonSignedEnumReaderWriter.cs index e47849290b3..43286078473 100644 --- a/src/EFCore/Storage/Json/JsonSignedEnumReaderWriter.cs +++ b/src/EFCore/Storage/Json/JsonSignedEnumReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Text.Json; namespace Microsoft.EntityFrameworkCore.Storage.Json; @@ -32,5 +31,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, TEnum value) => writer.WriteNumberValue((long)Convert.ChangeType(value, typeof(long))!); /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore/Storage/Json/JsonStringReaderWriter.cs b/src/EFCore/Storage/Json/JsonStringReaderWriter.cs index db0fd0a161c..471cb8dd351 100644 --- a/src/EFCore/Storage/Json/JsonStringReaderWriter.cs +++ b/src/EFCore/Storage/Json/JsonStringReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Text.Json; namespace Microsoft.EntityFrameworkCore.Storage.Json; @@ -31,5 +30,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, string value) => writer.WriteStringValue(value); /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore/Storage/Json/JsonTimeOnlyReaderWriter.cs b/src/EFCore/Storage/Json/JsonTimeOnlyReaderWriter.cs index 3c8da5eaa0e..7ad13f20225 100644 --- a/src/EFCore/Storage/Json/JsonTimeOnlyReaderWriter.cs +++ b/src/EFCore/Storage/Json/JsonTimeOnlyReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Text.Json; @@ -32,5 +31,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, TimeOnly value) => writer.WriteStringValue(value.ToString("o", CultureInfo.InvariantCulture)); /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore/Storage/Json/JsonTimeSpanReaderWriter.cs b/src/EFCore/Storage/Json/JsonTimeSpanReaderWriter.cs index 250f0dd3ea0..1438388cc52 100644 --- a/src/EFCore/Storage/Json/JsonTimeSpanReaderWriter.cs +++ b/src/EFCore/Storage/Json/JsonTimeSpanReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Text.Json; @@ -32,5 +31,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, TimeSpan value) => writer.WriteStringValue(value.ToString("g", CultureInfo.InvariantCulture)); /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore/Storage/Json/JsonUInt16ReaderWriter.cs b/src/EFCore/Storage/Json/JsonUInt16ReaderWriter.cs index d407d6e8c80..df53cddb192 100644 --- a/src/EFCore/Storage/Json/JsonUInt16ReaderWriter.cs +++ b/src/EFCore/Storage/Json/JsonUInt16ReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Text.Json; namespace Microsoft.EntityFrameworkCore.Storage.Json; @@ -31,5 +30,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, ushort value) => writer.WriteNumberValue(value); /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore/Storage/Json/JsonUInt32ReaderWriter.cs b/src/EFCore/Storage/Json/JsonUInt32ReaderWriter.cs index f1ba5875218..0909f2fafe4 100644 --- a/src/EFCore/Storage/Json/JsonUInt32ReaderWriter.cs +++ b/src/EFCore/Storage/Json/JsonUInt32ReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Text.Json; namespace Microsoft.EntityFrameworkCore.Storage.Json; @@ -31,5 +30,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, uint value) => writer.WriteNumberValue(value); /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore/Storage/Json/JsonUInt64ReaderWriter.cs b/src/EFCore/Storage/Json/JsonUInt64ReaderWriter.cs index 600da6391b0..d1a6846031c 100644 --- a/src/EFCore/Storage/Json/JsonUInt64ReaderWriter.cs +++ b/src/EFCore/Storage/Json/JsonUInt64ReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Text.Json; namespace Microsoft.EntityFrameworkCore.Storage.Json; @@ -31,5 +30,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, ulong value) => writer.WriteNumberValue(value); /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore/Storage/Json/JsonUnsignedEnumReaderWriter.cs b/src/EFCore/Storage/Json/JsonUnsignedEnumReaderWriter.cs index b08268f14b3..92b8e13657d 100644 --- a/src/EFCore/Storage/Json/JsonUnsignedEnumReaderWriter.cs +++ b/src/EFCore/Storage/Json/JsonUnsignedEnumReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Text.Json; namespace Microsoft.EntityFrameworkCore.Storage.Json; @@ -32,5 +31,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, TEnum value) => writer.WriteNumberValue((ulong)Convert.ChangeType(value, typeof(ulong))!); /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore/Storage/Json/JsonValueReaderWriterSource.cs b/src/EFCore/Storage/Json/JsonValueReaderWriterSource.cs index 4e7710b8059..4ba1c59900e 100644 --- a/src/EFCore/Storage/Json/JsonValueReaderWriterSource.cs +++ b/src/EFCore/Storage/Json/JsonValueReaderWriterSource.cs @@ -1,8 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Collections.Concurrent; - namespace Microsoft.EntityFrameworkCore.Storage.Json; /// @@ -28,9 +26,7 @@ public class JsonValueReaderWriterSource : IJsonValueReaderWriterSource /// /// Parameter object containing dependencies for this service. public JsonValueReaderWriterSource(JsonValueReaderWriterSourceDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Storage/Json/JsonWarningEnumReaderWriter.cs b/src/EFCore/Storage/Json/JsonWarningEnumReaderWriter.cs index 2be552ab17b..bef4ee9051d 100644 --- a/src/EFCore/Storage/Json/JsonWarningEnumReaderWriter.cs +++ b/src/EFCore/Storage/Json/JsonWarningEnumReaderWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using System.Text.Json; namespace Microsoft.EntityFrameworkCore.Storage.Json; @@ -23,9 +22,7 @@ public sealed class JsonWarningEnumReaderWriter : JsonValueReaderWriter _isSigned = typeof(TEnum).GetEnumUnderlyingType().IsSignedInteger(); /// public override TEnum FromJsonTyped(ref Utf8JsonReaderManager manager, object? existingObject = null) @@ -77,5 +74,6 @@ public override void ToJsonTyped(Utf8JsonWriter writer, TEnum value) } /// - public override Expression ConstructorExpression => Expression.Property(null, InstanceProperty); + public override Expression ConstructorExpression + => Expression.Property(null, InstanceProperty); } diff --git a/src/EFCore/Storage/Json/Utf8JsonReaderManager.cs b/src/EFCore/Storage/Json/Utf8JsonReaderManager.cs index e704765170a..036c2161a09 100644 --- a/src/EFCore/Storage/Json/Utf8JsonReaderManager.cs +++ b/src/EFCore/Storage/Json/Utf8JsonReaderManager.cs @@ -56,7 +56,8 @@ public JsonTokenType MoveNext() } /// - /// Skips the children of the current JSON token, which may involve reading more data from the stream and creating a new + /// Skips the children of the current JSON token, which may involve reading more data from the stream and creating a new + /// /// instance in . /// public void Skip() diff --git a/src/EFCore/Storage/NonRetryingExecutionStrategy.cs b/src/EFCore/Storage/NonRetryingExecutionStrategy.cs index 13c1bc8aa28..76b2cbad978 100644 --- a/src/EFCore/Storage/NonRetryingExecutionStrategy.cs +++ b/src/EFCore/Storage/NonRetryingExecutionStrategy.cs @@ -25,18 +25,14 @@ public sealed class NonRetryingExecutionStrategy : IExecutionStrategy /// /// Dependencies for this execution strategy. public NonRetryingExecutionStrategy(ExecutionStrategyDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Constructs a new with the given context. /// /// The context on which the operations will be invoked. public NonRetryingExecutionStrategy(DbContext context) - { - Dependencies = context.GetService(); - } + => Dependencies = context.GetService(); private ExecutionStrategyDependencies Dependencies { get; } diff --git a/src/EFCore/Storage/TypeMappingInfo.cs b/src/EFCore/Storage/TypeMappingInfo.cs index 2bd435e1df9..7ab3656b8ec 100644 --- a/src/EFCore/Storage/TypeMappingInfo.cs +++ b/src/EFCore/Storage/TypeMappingInfo.cs @@ -227,12 +227,13 @@ public TypeMappingInfo( Type type, ITypeMappingConfiguration typeMappingConfiguration, CoreTypeMapping? elementTypeMapping = null) - : this(typeMappingConfiguration.GetValueConverter()?.ProviderClrType ?? type, - elementTypeMapping, - unicode: typeMappingConfiguration.IsUnicode(), - size: typeMappingConfiguration.GetMaxLength(), - precision: typeMappingConfiguration.GetPrecision(), - scale: typeMappingConfiguration.GetScale()) + : this( + typeMappingConfiguration.GetValueConverter()?.ProviderClrType ?? type, + elementTypeMapping, + unicode: typeMappingConfiguration.IsUnicode(), + size: typeMappingConfiguration.GetMaxLength(), + precision: typeMappingConfiguration.GetPrecision(), + scale: typeMappingConfiguration.GetScale()) { } @@ -329,7 +330,7 @@ public TypeMappingInfo WithConverter(in ValueConverterInfo converterInfo) public bool IsKeyOrIndex { get; init; } /// - /// Indicates the store-size to use for the mapping, or null if none. + /// Indicates the store-size to use for the mapping, or if none. /// public int? Size { get; init; } diff --git a/src/EFCore/Storage/TypeMappingSource.cs b/src/EFCore/Storage/TypeMappingSource.cs index 3ab4630fd68..dc39b1567cd 100644 --- a/src/EFCore/Storage/TypeMappingSource.cs +++ b/src/EFCore/Storage/TypeMappingSource.cs @@ -120,7 +120,6 @@ protected TypeMappingSource(TypeMappingSourceDependencies dependencies) ?? WithConverter(); } - CoreTypeMapping? WithConverter() { foreach (var converterInfo in self.Dependencies @@ -161,7 +160,6 @@ protected TypeMappingSource(TypeMappingSourceDependencies dependencies) return mapping; } - if (mapping != null && customConverter != null) { @@ -284,11 +282,11 @@ protected TypeMappingSource(TypeMappingSourceDependencies dependencies) customConverter: null); } - /// + /// public override CoreTypeMapping? FindMapping(MemberInfo member) => FindMappingWithConversion(new TypeMappingInfo(member), null, null); - /// + /// public override CoreTypeMapping? FindMapping(MemberInfo member, IModel model, bool useAttributes) => FindMappingWithConversion(new TypeMappingInfo(member), null, null); } diff --git a/src/EFCore/Storage/TypeMappingSourceBase.cs b/src/EFCore/Storage/TypeMappingSourceBase.cs index d70815043f3..750617dd710 100644 --- a/src/EFCore/Storage/TypeMappingSourceBase.cs +++ b/src/EFCore/Storage/TypeMappingSourceBase.cs @@ -34,9 +34,7 @@ public abstract class TypeMappingSourceBase : ITypeMappingSource /// /// Parameter object containing dependencies for this service. protected TypeMappingSourceBase(TypeMappingSourceDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. @@ -120,10 +118,10 @@ protected virtual void ValidateMapping( /// The type mapping, or if none was found. public abstract CoreTypeMapping? FindMapping(Type type, IModel model, CoreTypeMapping? elementMapping = null); - /// + /// public abstract CoreTypeMapping? FindMapping(MemberInfo member); - /// + /// public virtual CoreTypeMapping? FindMapping(MemberInfo member, IModel model, bool useAttributes) => FindMapping(member); diff --git a/src/EFCore/Storage/ValueConversion/CollectionToJsonStringConverter.cs b/src/EFCore/Storage/ValueConversion/CollectionToJsonStringConverter.cs index a9af710ee78..59b1403ddaf 100644 --- a/src/EFCore/Storage/ValueConversion/CollectionToJsonStringConverter.cs +++ b/src/EFCore/Storage/ValueConversion/CollectionToJsonStringConverter.cs @@ -28,15 +28,13 @@ public CollectionToJsonStringConverter(JsonValueReaderWriter collectionJsonReade : base( ToJsonString(collectionJsonReaderWriter), FromJsonString(collectionJsonReaderWriter)) - { - JsonReaderWriter = collectionJsonReaderWriter; - } + => JsonReaderWriter = collectionJsonReaderWriter; private static Expression, string>> ToJsonString(JsonValueReaderWriter collectionJsonReaderWriter) { var prm = Parameter(typeof(IEnumerable), "v"); - return Lambda, string>>( + return Lambda, string>>( Call( collectionJsonReaderWriter.ConstructorExpression, ToJsonStringMethod, diff --git a/src/EFCore/Storage/ValueConversion/NumberToBytesConverter.cs b/src/EFCore/Storage/ValueConversion/NumberToBytesConverter.cs index cf4c0a1fc7c..39986795e88 100644 --- a/src/EFCore/Storage/ValueConversion/NumberToBytesConverter.cs +++ b/src/EFCore/Storage/ValueConversion/NumberToBytesConverter.cs @@ -299,7 +299,7 @@ private static readonly MethodInfo ToDecimalMethod [EntityFrameworkInternal] public static decimal BytesToDecimal(byte[] bytes) { - Span gotBytes = BitConverter.IsLittleEndian ? stackalloc byte[16] : bytes; + var gotBytes = BitConverter.IsLittleEndian ? stackalloc byte[16] : bytes; if (BitConverter.IsLittleEndian) { bytes.CopyTo(gotBytes); diff --git a/src/EFCore/Storage/ValueConversion/StringToBytesConverter.cs b/src/EFCore/Storage/ValueConversion/StringToBytesConverter.cs index 63483ced254..574467b222f 100644 --- a/src/EFCore/Storage/ValueConversion/StringToBytesConverter.cs +++ b/src/EFCore/Storage/ValueConversion/StringToBytesConverter.cs @@ -13,9 +13,14 @@ namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion; /// public class StringToBytesConverter : ValueConverter { - private static readonly MethodInfo EncodingGetBytesMethodInfo = typeof(Encoding).GetMethod(nameof(Encoding.GetBytes), [typeof(string)])!; - private static readonly MethodInfo EncodingGetStringMethodInfo = typeof(Encoding).GetMethod(nameof(Encoding.GetString), [typeof(byte[])])!; - private static readonly MethodInfo EncodingGetEncodingMethodInfo = typeof(Encoding).GetMethod(nameof(Encoding.GetEncoding), [typeof(int)])!; + private static readonly MethodInfo EncodingGetBytesMethodInfo = + typeof(Encoding).GetMethod(nameof(Encoding.GetBytes), [typeof(string)])!; + + private static readonly MethodInfo EncodingGetStringMethodInfo = + typeof(Encoding).GetMethod(nameof(Encoding.GetString), [typeof(byte[])])!; + + private static readonly MethodInfo EncodingGetEncodingMethodInfo = + typeof(Encoding).GetMethod(nameof(Encoding.GetEncoding), [typeof(int)])!; /// /// Creates a new instance of this converter. diff --git a/src/EFCore/Storage/ValueConversion/ValueConverterSelector.cs b/src/EFCore/Storage/ValueConversion/ValueConverterSelector.cs index 0f9935f2db5..7c38b53975b 100644 --- a/src/EFCore/Storage/ValueConversion/ValueConverterSelector.cs +++ b/src/EFCore/Storage/ValueConversion/ValueConverterSelector.cs @@ -64,9 +64,7 @@ public class ValueConverterSelector : IValueConverterSelector /// /// Parameter object containing dependencies for this service. public ValueConverterSelector(ValueConverterSelectorDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. diff --git a/src/EFCore/Storage/ValueConversion/ValueConverter`.cs b/src/EFCore/Storage/ValueConversion/ValueConverter`.cs index 7656b5abc5b..c70fb9d6061 100644 --- a/src/EFCore/Storage/ValueConversion/ValueConverter`.cs +++ b/src/EFCore/Storage/ValueConversion/ValueConverter`.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; using Microsoft.EntityFrameworkCore.Internal; namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion; @@ -19,8 +18,10 @@ public class ValueConverter : ValueConverter private Func? _convertFromProvider; private Func? _convertToProviderTyped; private Func? _convertFromProviderTyped; + private static readonly ConstructorInfo MappingHintsCtor - = typeof(ConverterMappingHints).GetConstructor([typeof(int?), typeof(int?), typeof(int?), typeof(bool?), typeof(Func)])!; + = typeof(ConverterMappingHints).GetConstructor( + [typeof(int?), typeof(int?), typeof(int?), typeof(bool?), typeof(Func)])!; /// /// Initializes a new instance of the class. @@ -177,15 +178,15 @@ public override Type ProviderClrType => typeof(TProvider); private readonly ConstructorInfo _constructorInfo = typeof(ValueConverter).GetConstructor( - [ - typeof(Expression>), - typeof(Expression>), - typeof(ConverterMappingHints) - ])!; + [ + typeof(Expression>), + typeof(Expression>), + typeof(ConverterMappingHints) + ])!; /// - public override Expression ConstructorExpression => - Expression.New( + public override Expression ConstructorExpression + => Expression.New( _constructorInfo, ConvertToProviderExpression, ConvertFromProviderExpression, @@ -198,5 +199,5 @@ public override Type ProviderClrType Expression.Constant(MappingHints.IsUnicode, typeof(bool?)), // valueGeneratorFactory is difficult to build using Expression trees and is obsolete Expression.Default(typeof(Func))) - : Expression.Default(typeof(ConverterMappingHints))); + : Expression.Default(typeof(ConverterMappingHints))); } diff --git a/src/EFCore/Update/IUpdateEntry.cs b/src/EFCore/Update/IUpdateEntry.cs index 1c4ebe04024..ea03a1d6937 100644 --- a/src/EFCore/Update/IUpdateEntry.cs +++ b/src/EFCore/Update/IUpdateEntry.cs @@ -102,10 +102,10 @@ public interface IUpdateEntry object? GetOriginalValue(IPropertyBase propertyBase); /// - /// Returns only if the property has storage for an original value. + /// Returns only if the property has storage for an original value. /// /// The property. - /// if the property may have an original value; if it never can. + /// if the property may have an original value; if it never can. bool CanHaveOriginalValue(IPropertyBase propertyBase); /// diff --git a/src/EFCore/Update/Internal/UpdateAdapterFactory.cs b/src/EFCore/Update/Internal/UpdateAdapterFactory.cs index b166e8579f3..1c00e630cd8 100644 --- a/src/EFCore/Update/Internal/UpdateAdapterFactory.cs +++ b/src/EFCore/Update/Internal/UpdateAdapterFactory.cs @@ -23,9 +23,7 @@ public class UpdateAdapterFactory : IUpdateAdapterFactory /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public UpdateAdapterFactory(ICurrentDbContext currentContext) - { - _currentContext = currentContext; - } + => _currentContext = currentContext; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/ValueGeneration/HiLoValueGenerator.cs b/src/EFCore/ValueGeneration/HiLoValueGenerator.cs index 0682b58a9c8..f6837d380a9 100644 --- a/src/EFCore/ValueGeneration/HiLoValueGenerator.cs +++ b/src/EFCore/ValueGeneration/HiLoValueGenerator.cs @@ -26,9 +26,7 @@ public abstract class HiLoValueGenerator : ValueGenerator /// /// The state used to keep track of which value to return next. protected HiLoValueGenerator(HiLoValueGeneratorState generatorState) - { - _generatorState = generatorState; - } + => _generatorState = generatorState; /// /// Gets a value to be assigned to a property. diff --git a/src/EFCore/ValueGeneration/IValueGeneratorSelector.cs b/src/EFCore/ValueGeneration/IValueGeneratorSelector.cs index d802440063b..bebafddcde2 100644 --- a/src/EFCore/ValueGeneration/IValueGeneratorSelector.cs +++ b/src/EFCore/ValueGeneration/IValueGeneratorSelector.cs @@ -46,7 +46,7 @@ public interface IValueGeneratorSelector /// The entity type that the value generator will be used for. When called on inherited properties on derived entity types, /// this entity type may be different from the declared entity type on /// - /// The value generator, or if none is available. - /// if a value generator was selected; if none was available. + /// The value generator, or if none is available. + /// if a value generator was selected; if none was available. bool TrySelect(IProperty property, ITypeBase typeBase, out ValueGenerator? valueGenerator); } diff --git a/src/EFCore/ValueGeneration/ValueGeneratorCache.cs b/src/EFCore/ValueGeneration/ValueGeneratorCache.cs index 3b41e539aeb..ae8b997710e 100644 --- a/src/EFCore/ValueGeneration/ValueGeneratorCache.cs +++ b/src/EFCore/ValueGeneration/ValueGeneratorCache.cs @@ -32,9 +32,7 @@ public class ValueGeneratorCache : IValueGeneratorCache /// /// Parameter object containing dependencies for this service. public ValueGeneratorCache(ValueGeneratorCacheDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. @@ -51,8 +49,8 @@ private readonly struct CacheKey(IProperty property, ITypeBase typeBase) : IEqua public bool Equals(CacheKey other) => (_property!.Equals(other._property, StringComparison.Ordinal) - && _typeBase!.Equals(other._typeBase, StringComparison.Ordinal) - && _modelId.Equals(other._modelId)); + && _typeBase!.Equals(other._typeBase, StringComparison.Ordinal) + && _modelId.Equals(other._modelId)); public override bool Equals(object? obj) => obj is CacheKey cacheKey && Equals(cacheKey); @@ -77,5 +75,5 @@ public override int GetHashCode() ITypeBase typeBase, Func factory) => _cache.GetOrAdd( - new CacheKey(property, typeBase), static (ck, p) => p.factory(p.property, p.typeBase), (factory, typeBase, property)); + new CacheKey(property, typeBase), static (ck, p) => p.factory(p.property, p.typeBase), (factory, typeBase, property)); } diff --git a/src/EFCore/ValueGeneration/ValueGeneratorSelector.cs b/src/EFCore/ValueGeneration/ValueGeneratorSelector.cs index f6cc78cd8fb..c125b416539 100644 --- a/src/EFCore/ValueGeneration/ValueGeneratorSelector.cs +++ b/src/EFCore/ValueGeneration/ValueGeneratorSelector.cs @@ -37,9 +37,7 @@ public virtual IValueGeneratorCache Cache /// /// Parameter object containing dependencies for this service. public ValueGeneratorSelector(ValueGeneratorSelectorDependencies dependencies) - { - Dependencies = dependencies; - } + => Dependencies = dependencies; /// /// Dependencies for this service. @@ -112,8 +110,8 @@ public virtual ValueGenerator Create(IProperty property, ITypeBase typeBase) /// The entity type that the value generator will be used for. When called on inherited properties on derived entity types, /// this entity type may be different from the declared entity type on /// - /// The newly created value generator, or if none is available. - /// if a generator was created. + /// The newly created value generator, or if none is available. + /// if a generator was created. public virtual bool TryCreate(IProperty property, ITypeBase typeBase, out ValueGenerator? valueGenerator) { var propertyType = property.ClrType.UnwrapNullableType().UnwrapEnumType(); diff --git a/src/EFCore/ValueGeneration/ValueGeneratorSelectorDependencies.cs b/src/EFCore/ValueGeneration/ValueGeneratorSelectorDependencies.cs index f7a0132b518..d13344aab4d 100644 --- a/src/EFCore/ValueGeneration/ValueGeneratorSelectorDependencies.cs +++ b/src/EFCore/ValueGeneration/ValueGeneratorSelectorDependencies.cs @@ -46,9 +46,7 @@ public sealed record ValueGeneratorSelectorDependencies /// [EntityFrameworkInternal] public ValueGeneratorSelectorDependencies(IValueGeneratorCache cache) - { - Cache = cache; - } + => Cache = cache; /// /// The cache being used to store value generator instances. 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 d3c36ca31b3..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 d64ad0c60dc..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/Shared/DictionaryExtensions.cs b/src/Shared/DictionaryExtensions.cs index 89a73011722..0f18964b843 100644 --- a/src/Shared/DictionaryExtensions.cs +++ b/src/Shared/DictionaryExtensions.cs @@ -27,7 +27,7 @@ public static TValue GetOrAddNew( public static TValue? Find( this IReadOnlyDictionary source, TKey key) - => !source.TryGetValue(key, out var value) ? default : value; + => source.GetValueOrDefault(key); public static bool TryGetAndRemove( this IDictionary source, diff --git a/src/EFCore.Analyzers/EFDiagnostics.cs b/src/Shared/EFDiagnostics.cs similarity index 96% rename from src/EFCore.Analyzers/EFDiagnostics.cs rename to src/Shared/EFDiagnostics.cs index c3021424089..42476e39280 100644 --- a/src/EFCore.Analyzers/EFDiagnostics.cs +++ b/src/Shared/EFDiagnostics.cs @@ -6,7 +6,7 @@ namespace Microsoft.EntityFrameworkCore; /// /// Contains the IDs of diagnostics emitted by EF Core analyzers, [Experimental] and other mechanisms. /// -public static class EFDiagnostics +internal static class EFDiagnostics { public const string InternalUsage = "EF1001"; public const string InterpolatedStringUsageInRawQueries = "EF1002"; diff --git a/src/Shared/EnumerableMethods.cs b/src/Shared/EnumerableMethods.cs index 5c03d17d38d..1a65c6c1e6f 100644 --- a/src/Shared/EnumerableMethods.cs +++ b/src/Shared/EnumerableMethods.cs @@ -237,24 +237,16 @@ public static MethodInfo GetAverageWithSelector(Type type) => AverageWithSelectorMethods[type]; public static MethodInfo GetMaxWithoutSelector(Type type) - => MaxWithoutSelectorMethods.TryGetValue(type, out var method) - ? method - : MaxWithoutSelector; + => MaxWithoutSelectorMethods.GetValueOrDefault(type, MaxWithoutSelector); public static MethodInfo GetMaxWithSelector(Type type) - => MaxWithSelectorMethods.TryGetValue(type, out var method) - ? method - : MaxWithSelector; + => MaxWithSelectorMethods.GetValueOrDefault(type, MaxWithSelector); public static MethodInfo GetMinWithoutSelector(Type type) - => MinWithoutSelectorMethods.TryGetValue(type, out var method) - ? method - : MinWithoutSelector; + => MinWithoutSelectorMethods.GetValueOrDefault(type, MinWithoutSelector); public static MethodInfo GetMinWithSelector(Type type) - => MinWithSelectorMethods.TryGetValue(type, out var method) - ? method - : MinWithSelector; + => MinWithSelectorMethods.GetValueOrDefault(type, MinWithSelector); static EnumerableMethods() { diff --git a/src/Shared/SharedTypeExtensions.cs b/src/Shared/SharedTypeExtensions.cs index 868e9c999b1..2263fe3f139 100644 --- a/src/Shared/SharedTypeExtensions.cs +++ b/src/Shared/SharedTypeExtensions.cs @@ -544,13 +544,13 @@ private static void ProcessGenericType( return; } - var offset = type.IsNested ? type.DeclaringType!.GetGenericArguments().Length : 0; + var offset = type.DeclaringType != null ? type.DeclaringType.GetGenericArguments().Length : 0; if (compilable) { - if (type.IsNested) + if (type.DeclaringType != null) { - ProcessType(builder, type.DeclaringType!, fullName, compilable); + ProcessGenericType(builder, type.DeclaringType, genericArguments, offset, fullName, compilable); builder.Append('.'); } else if (fullName) @@ -563,9 +563,9 @@ private static void ProcessGenericType( { if (fullName) { - if (type.IsNested) + if (type.DeclaringType != null) { - ProcessGenericType(builder, type.DeclaringType!, genericArguments, offset, fullName, compilable); + ProcessGenericType(builder, type.DeclaringType, genericArguments, offset, fullName, compilable); builder.Append('+'); } else diff --git a/src/dotnet-ef/Exe.cs b/src/dotnet-ef/Exe.cs index 8729e3ccdeb..9a72be2c6f3 100644 --- a/src/dotnet-ef/Exe.cs +++ b/src/dotnet-ef/Exe.cs @@ -34,10 +34,7 @@ public static int Run( startInfo.WorkingDirectory = workingDirectory; } - var process = new Process - { - StartInfo = startInfo - }; + var process = new Process { StartInfo = startInfo }; if (handleOutput != null) { diff --git a/src/dotnet-ef/Properties/Resources.Designer.cs b/src/dotnet-ef/Properties/Resources.Designer.cs index e11c02b8777..e181047a69b 100644 --- a/src/dotnet-ef/Properties/Resources.Designer.cs +++ b/src/dotnet-ef/Properties/Resources.Designer.cs @@ -323,6 +323,18 @@ public static string MultipleStartupProjects public static string NamespaceDescription => GetString("NamespaceDescription"); + /// + /// Additionally generate all the code required for NativeAOT compilation and precompiled queries (experimental) + /// + public static string NativeAotDescription + => GetString("NativeAotDescription"); + + /// + /// NativeAOT support is experimental and can change in the future. + /// + public static string NativeAotWarning + => GetString("NativeAotWarning"); + /// /// Startup project '{startupProject}' targets framework '.NETCoreApp' version '{targetFrameworkVersion}'. This version of the Entity Framework Core .NET Command-line Tools only supports version 2.0 or higher. For information on using older versions of the tools, see https://go.microsoft.com/fwlink/?linkid=871254 /// diff --git a/src/dotnet-ef/Properties/Resources.resx b/src/dotnet-ef/Properties/Resources.resx index 4182eb6d82a..69810354fcd 100644 --- a/src/dotnet-ef/Properties/Resources.resx +++ b/src/dotnet-ef/Properties/Resources.resx @@ -267,6 +267,12 @@ The namespace to use. Matches the directory by default. + + Additionally generate all the code required for NativeAOT compilation and precompiled queries (experimental). + + + NativeAOT support is experimental and can change in the future. + Startup project '{startupProject}' targets framework '.NETCoreApp' version '{targetFrameworkVersion}'. This version of the Entity Framework Core .NET Command-line Tools only supports version 2.0 or higher. For information on using older versions of the tools, see https://go.microsoft.com/fwlink/?linkid=871254 diff --git a/src/dotnet-ef/RootCommand.cs b/src/dotnet-ef/RootCommand.cs index aa03475a11d..9235279c9ed 100644 --- a/src/dotnet-ef/RootCommand.cs +++ b/src/dotnet-ef/RootCommand.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; using System.Reflection; using System.Runtime.Versioning; using System.Text.Json; @@ -81,7 +80,9 @@ protected override int Execute(string[] _) { Reporter.WriteInformation(Resources.BuildStarted); var skipOptimization = _args!.Count > 2 - && _args[0] == "dbcontext" && _args[1] == "optimize" && !_args.Any(a => a == "--no-scaffold"); + && _args[0] == "dbcontext" + && _args[1] == "optimize" + && !_args.Any(a => a == "--no-scaffold"); startupProject.Build(skipOptimization ? new[] { "/p:EFOptimizeContext=false" } : null); Reporter.WriteInformation(Resources.BuildSucceeded); } diff --git a/src/dotnet-ef/dotnet-ef.csproj b/src/dotnet-ef/dotnet-ef.csproj index c4bd4eeb604..9d55e8c5506 100644 --- a/src/dotnet-ef/dotnet-ef.csproj +++ b/src/dotnet-ef/dotnet-ef.csproj @@ -84,7 +84,8 @@ dotnet ef database update - + + diff --git a/src/ef/Commands/DbContextOptimizeCommand.Configure.cs b/src/ef/Commands/DbContextOptimizeCommand.Configure.cs index 5cc1d77a61b..8716e8cd4f3 100644 --- a/src/ef/Commands/DbContextOptimizeCommand.Configure.cs +++ b/src/ef/Commands/DbContextOptimizeCommand.Configure.cs @@ -13,6 +13,7 @@ internal partial class DbContextOptimizeCommand : ContextCommandBase private CommandOption? _suffix; private CommandOption? _noScaffold; private CommandOption? _precompileQueries; + private CommandOption? _nativeAot; public override void Configure(CommandLineApplication command) { @@ -23,6 +24,7 @@ public override void Configure(CommandLineApplication command) _suffix = command.Option("--suffix ", Resources.SuffixDescription); _noScaffold = command.Option("--no-scaffold", Resources.NoScaffoldDescription); _precompileQueries = command.Option("--precompile-queries", Resources.PrecompileQueriesDescription); + _nativeAot = command.Option("--nativeaot", Resources.NativeAotDescription); base.Configure(command); } diff --git a/src/ef/Commands/DbContextOptimizeCommand.cs b/src/ef/Commands/DbContextOptimizeCommand.cs index 39144f5b780..acd388902ca 100644 --- a/src/ef/Commands/DbContextOptimizeCommand.cs +++ b/src/ef/Commands/DbContextOptimizeCommand.cs @@ -23,6 +23,11 @@ protected override void Validate() { Reporter.WriteWarning(Resources.PrecompileQueriesWarning); } + + if (_nativeAot!.HasValue()) + { + Reporter.WriteWarning(Resources.NativeAotWarning); + } } protected override int Execute(string[] args) @@ -39,7 +44,8 @@ protected override int Execute(string[] args) Context!.Value(), _suffix!.Value() ?? "", !_noScaffold!.HasValue(), - _precompileQueries!.HasValue()); + _precompileQueries!.HasValue(), + _nativeAot!.HasValue()); ReportResults(result); diff --git a/src/ef/IOperationExecutor.cs b/src/ef/IOperationExecutor.cs index 644a938ba7f..f29f33e3b36 100644 --- a/src/ef/IOperationExecutor.cs +++ b/src/ef/IOperationExecutor.cs @@ -15,7 +15,13 @@ internal interface IOperationExecutor : IDisposable void UpdateDatabase(string? migration, string? connectionString, string? contextType); IEnumerable GetContextTypes(); IEnumerable OptimizeContext( - string? outputDir, string? modelNamespace, string? contextType, string? suffix, bool scaffoldModel, bool precompileQueries); + string? outputDir, + string? modelNamespace, + string? contextType, + string? suffix, + bool scaffoldModel, + bool precompileQueries, + bool nativeAot); IDictionary ScaffoldContext( string provider, diff --git a/src/ef/OperationExecutorBase.cs b/src/ef/OperationExecutorBase.cs index 53c910449e3..28ac4861c5b 100644 --- a/src/ef/OperationExecutorBase.cs +++ b/src/ef/OperationExecutorBase.cs @@ -144,7 +144,13 @@ public IEnumerable GetContextTypes() => InvokeOperation>("GetContextTypes"); public IEnumerable OptimizeContext( - string? outputDir, string? modelNamespace, string? contextType, string? suffix, bool scaffoldModel, bool precompileQueries) + string? outputDir, + string? modelNamespace, + string? contextType, + string? suffix, + bool scaffoldModel, + bool precompileQueries, + bool nativeAot) => InvokeOperation>( "OptimizeContext", new Dictionary @@ -154,7 +160,8 @@ public IEnumerable OptimizeContext( ["contextType"] = contextType, ["suffix"] = suffix, ["scaffoldModel"] = scaffoldModel, - ["precompileQueries"] = precompileQueries + ["precompileQueries"] = precompileQueries, + ["nativeAot"] = nativeAot }); public IDictionary ScaffoldContext( diff --git a/src/ef/Properties/Resources.Designer.cs b/src/ef/Properties/Resources.Designer.cs index 32f9b4f25c4..31f58dd2a67 100644 --- a/src/ef/Properties/Resources.Designer.cs +++ b/src/ef/Properties/Resources.Designer.cs @@ -403,6 +403,18 @@ public static string MissingOption(object? option) public static string NamespaceDescription => GetString("NamespaceDescription"); + /// + /// Additionally generate all the code required for NativeAOT compilation and precompiled queries (experimental). + /// + public static string NativeAotDescription + => GetString("NativeAotDescription"); + + /// + /// NativeAOT support is experimental and can change in the future. + /// + public static string NativeAotWarning + => GetString("NativeAotWarning"); + /// /// Don't colorize output. /// diff --git a/src/ef/Properties/Resources.resx b/src/ef/Properties/Resources.resx index f8f33bb0175..5506c7c483c 100644 --- a/src/ef/Properties/Resources.resx +++ b/src/ef/Properties/Resources.resx @@ -297,6 +297,12 @@ The namespace to use. Matches the directory by default. + + Additionally generate all the code required for NativeAOT compilation and precompiled queries (experimental). + + + NativeAOT support is experimental and can change in the future. + Don't colorize output. 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.Build.props b/test/Directory.Build.props index 68b58c1da11..4249b523331 100644 --- a/test/Directory.Build.props +++ b/test/Directory.Build.props @@ -8,4 +8,11 @@ net9.0 + + + + diff --git a/test/Directory.Packages.props b/test/Directory.Packages.props new file mode 100644 index 00000000000..6d70cbaa3fc --- /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..084a382f3ab 100644 --- a/test/EFCore.Analyzers.Tests/EFCore.Analyzers.Tests.csproj +++ b/test/EFCore.Analyzers.Tests/EFCore.Analyzers.Tests.csproj @@ -39,13 +39,20 @@ - - - - + + + + + + + + + + + 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/AppServiceProviderFactoryTest.cs b/test/EFCore.AspNet.InMemory.FunctionalTests/AppServiceProviderFactoryTest.cs index faeff786f93..84b3f4c2c46 100644 --- a/test/EFCore.AspNet.InMemory.FunctionalTests/AppServiceProviderFactoryTest.cs +++ b/test/EFCore.AspNet.InMemory.FunctionalTests/AppServiceProviderFactoryTest.cs @@ -139,7 +139,8 @@ public static TestWebHost BuildWebHost(string[] args) } } -public class TestAppServiceProviderFactory(Assembly startupAssembly, IOperationReporter reporter = null) : AppServiceProviderFactory(startupAssembly, reporter ?? new TestOperationReporter()); +public class TestAppServiceProviderFactory(Assembly startupAssembly, IOperationReporter reporter = null) + : AppServiceProviderFactory(startupAssembly, reporter ?? new TestOperationReporter()); public class TestWebHost(IServiceProvider services) { diff --git a/test/EFCore.AspNet.InMemory.FunctionalTests/AspNetIdentityCustomTypesDefaultInMemoryTest.cs b/test/EFCore.AspNet.InMemory.FunctionalTests/AspNetIdentityCustomTypesDefaultInMemoryTest.cs index d51c1a2a2f7..ab0d2597dfb 100644 --- a/test/EFCore.AspNet.InMemory.FunctionalTests/AspNetIdentityCustomTypesDefaultInMemoryTest.cs +++ b/test/EFCore.AspNet.InMemory.FunctionalTests/AspNetIdentityCustomTypesDefaultInMemoryTest.cs @@ -3,7 +3,8 @@ namespace Microsoft.EntityFrameworkCore; -public class AspNetIdentityCustomTypesDefaultInMemoryTest(AspNetIdentityCustomTypesDefaultInMemoryTest.AspNetIdentityCustomTypesDefaultInMemoryFixture fixture) +public class AspNetIdentityCustomTypesDefaultInMemoryTest( + AspNetIdentityCustomTypesDefaultInMemoryTest.AspNetIdentityCustomTypesDefaultInMemoryFixture fixture) : AspNetIdentityCustomTypesDefaultTestBase< AspNetIdentityCustomTypesDefaultInMemoryTest.AspNetIdentityCustomTypesDefaultInMemoryFixture>(fixture) { diff --git a/test/EFCore.AspNet.InMemory.FunctionalTests/AspNetIdentityCustomTypesIntKeyInMemoryTest.cs b/test/EFCore.AspNet.InMemory.FunctionalTests/AspNetIdentityCustomTypesIntKeyInMemoryTest.cs index 02fb9961576..44eb7687cbc 100644 --- a/test/EFCore.AspNet.InMemory.FunctionalTests/AspNetIdentityCustomTypesIntKeyInMemoryTest.cs +++ b/test/EFCore.AspNet.InMemory.FunctionalTests/AspNetIdentityCustomTypesIntKeyInMemoryTest.cs @@ -3,7 +3,8 @@ namespace Microsoft.EntityFrameworkCore; -public class AspNetIdentityCustomTypesIntKeyInMemoryTest(AspNetIdentityCustomTypesIntKeyInMemoryTest.AspNetIdentityCustomTypesIntKeyInMemoryFixture fixture) +public class AspNetIdentityCustomTypesIntKeyInMemoryTest( + AspNetIdentityCustomTypesIntKeyInMemoryTest.AspNetIdentityCustomTypesIntKeyInMemoryFixture fixture) : AspNetIdentityCustomTypesIntKeyTestBase< AspNetIdentityCustomTypesIntKeyInMemoryTest.AspNetIdentityCustomTypesIntKeyInMemoryFixture>(fixture) { 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/AspNetIdentityCustomTypesDefaultTestBase.cs b/test/EFCore.AspNet.Specification.Tests/AspNetIdentityCustomTypesDefaultTestBase.cs index 5aded433e13..b88e33d4923 100644 --- a/test/EFCore.AspNet.Specification.Tests/AspNetIdentityCustomTypesDefaultTestBase.cs +++ b/test/EFCore.AspNet.Specification.Tests/AspNetIdentityCustomTypesDefaultTestBase.cs @@ -330,9 +330,10 @@ protected override List ExpectedMappings ]; } -public class CustomTypesIdentityContext(DbContextOptions options) : IdentityDbContext(options) +public class CustomTypesIdentityContext(DbContextOptions options) + : IdentityDbContext(options) { protected override void OnModelCreating(ModelBuilder modelBuilder) { @@ -405,9 +406,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) public class CustomUserString : IdentityUser { public CustomUserString() - { - Id = Guid.NewGuid().ToString(); - } + => Id = Guid.NewGuid().ToString(); public string CustomTag { get; set; } @@ -422,9 +421,7 @@ public CustomUserString() public class CustomRoleString : IdentityRole { public CustomRoleString() - { - Id = Guid.NewGuid().ToString(); - } + => Id = Guid.NewGuid().ToString(); public virtual ICollection Users { get; set; } diff --git a/test/EFCore.AspNet.Specification.Tests/AspNetIdentityCustomTypesIntKeyTestBase.cs b/test/EFCore.AspNet.Specification.Tests/AspNetIdentityCustomTypesIntKeyTestBase.cs index 5a5a9decec6..408f8fb48c9 100644 --- a/test/EFCore.AspNet.Specification.Tests/AspNetIdentityCustomTypesIntKeyTestBase.cs +++ b/test/EFCore.AspNet.Specification.Tests/AspNetIdentityCustomTypesIntKeyTestBase.cs @@ -172,8 +172,9 @@ protected override List ExpectedMappings ]; } -public class CustomTypesIdentityContextInt(DbContextOptions options) : IdentityDbContext(options) +public class CustomTypesIdentityContextInt(DbContextOptions options) + : IdentityDbContext(options) { protected override void OnModelCreating(ModelBuilder modelBuilder) { diff --git a/test/EFCore.AspNet.Specification.Tests/ConfigurationDbContextTestBase.cs b/test/EFCore.AspNet.Specification.Tests/ConfigurationDbContextTestBase.cs index 3eca988aebe..84f0ad5164e 100644 --- a/test/EFCore.AspNet.Specification.Tests/ConfigurationDbContextTestBase.cs +++ b/test/EFCore.AspNet.Specification.Tests/ConfigurationDbContextTestBase.cs @@ -200,14 +200,14 @@ private static async Task SaveApiResources(ConfigurationDbContext context) Name = "ApiResource1", DisplayName = "ApiResource 1", Description = "ApiResource 1", - Scopes = [new() { Scope = "S1" }, new() { Scope = "S2" }] + Scopes = [new ApiResourceScope { Scope = "S1" }, new ApiResourceScope { Scope = "S2" }] }, new ApiResource { Name = "ApiResource2", DisplayName = "ApiResource 2", Description = "ApiResource 2", - Scopes = [new() { Scope = "S4" }, new() { Scope = "S5" }] + Scopes = [new ApiResourceScope { Scope = "S4" }, new ApiResourceScope { Scope = "S5" }] }, new ApiResource { 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.Specification.Tests/GrpcTestBase.cs b/test/EFCore.AspNet.Specification.Tests/GrpcTestBase.cs index 77a659dee9b..5f1b444116a 100644 --- a/test/EFCore.AspNet.Specification.Tests/GrpcTestBase.cs +++ b/test/EFCore.AspNet.Specification.Tests/GrpcTestBase.cs @@ -12,9 +12,7 @@ public abstract class GrpcTestBase : IClassFixture where TFixture : GrpcTestBase.GrpcFixtureBase { protected GrpcTestBase(TFixture fixture) - { - Fixture = fixture; - } + => Fixture = fixture; protected TFixture Fixture { get; } diff --git a/test/EFCore.AspNet.SqlServer.FunctionalTests/AspNetIdentityCustomTypesDefaultSqlServerTest.cs b/test/EFCore.AspNet.SqlServer.FunctionalTests/AspNetIdentityCustomTypesDefaultSqlServerTest.cs index c71b019ff68..fbea36dcf4d 100644 --- a/test/EFCore.AspNet.SqlServer.FunctionalTests/AspNetIdentityCustomTypesDefaultSqlServerTest.cs +++ b/test/EFCore.AspNet.SqlServer.FunctionalTests/AspNetIdentityCustomTypesDefaultSqlServerTest.cs @@ -3,7 +3,8 @@ namespace Microsoft.EntityFrameworkCore; -public class AspNetIdentityCustomTypesDefaultSqlServerTest(AspNetIdentityCustomTypesDefaultSqlServerTest.AspNetIdentityCustomTypesDefaultSqlServerFixture fixture) +public class AspNetIdentityCustomTypesDefaultSqlServerTest( + AspNetIdentityCustomTypesDefaultSqlServerTest.AspNetIdentityCustomTypesDefaultSqlServerFixture fixture) : AspNetIdentityCustomTypesDefaultTestBase< AspNetIdentityCustomTypesDefaultSqlServerTest.AspNetIdentityCustomTypesDefaultSqlServerFixture>(fixture) { diff --git a/test/EFCore.AspNet.SqlServer.FunctionalTests/AspNetIdentityCustomTypesIntKeySqlServerTest.cs b/test/EFCore.AspNet.SqlServer.FunctionalTests/AspNetIdentityCustomTypesIntKeySqlServerTest.cs index 6da42d6afbc..944edab6e11 100644 --- a/test/EFCore.AspNet.SqlServer.FunctionalTests/AspNetIdentityCustomTypesIntKeySqlServerTest.cs +++ b/test/EFCore.AspNet.SqlServer.FunctionalTests/AspNetIdentityCustomTypesIntKeySqlServerTest.cs @@ -3,7 +3,8 @@ namespace Microsoft.EntityFrameworkCore; -public class AspNetIdentityCustomTypesIntKeySqlServerTest(AspNetIdentityCustomTypesIntKeySqlServerTest.AspNetIdentityCustomTypesIntKeySqlServerFixture fixture) +public class AspNetIdentityCustomTypesIntKeySqlServerTest( + AspNetIdentityCustomTypesIntKeySqlServerTest.AspNetIdentityCustomTypesIntKeySqlServerFixture fixture) : AspNetIdentityCustomTypesIntKeyTestBase< AspNetIdentityCustomTypesIntKeySqlServerTest.AspNetIdentityCustomTypesIntKeySqlServerFixture>(fixture) { diff --git a/test/EFCore.AspNet.SqlServer.FunctionalTests/AspNetIdentityIntKeySqlServerTest.cs b/test/EFCore.AspNet.SqlServer.FunctionalTests/AspNetIdentityIntKeySqlServerTest.cs index dd00c47d098..b2058476c4b 100644 --- a/test/EFCore.AspNet.SqlServer.FunctionalTests/AspNetIdentityIntKeySqlServerTest.cs +++ b/test/EFCore.AspNet.SqlServer.FunctionalTests/AspNetIdentityIntKeySqlServerTest.cs @@ -4,7 +4,7 @@ namespace Microsoft.EntityFrameworkCore; public class AspNetIdentityIntKeySqlServerTest(AspNetIdentityIntKeySqlServerTest.AspNetIdentityIntKeySqlServerFixture fixture) - : AspNetIdentityIntKeyTestBase(fixture) + : AspNetIdentityIntKeyTestBase(fixture) { public class AspNetIdentityIntKeySqlServerFixture : AspNetIdentityFixtureBase { 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.SqlServer.FunctionalTests/GrpcSqlServerTest.cs b/test/EFCore.AspNet.SqlServer.FunctionalTests/GrpcSqlServerTest.cs index cfaa1c83bfe..bc385b737a6 100644 --- a/test/EFCore.AspNet.SqlServer.FunctionalTests/GrpcSqlServerTest.cs +++ b/test/EFCore.AspNet.SqlServer.FunctionalTests/GrpcSqlServerTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore; #if !EXCLUDE_ON_MAC -public class GrpcSqlServerTest(GrpcSqlServerTest.GrpcSqlServerFixture fixture) : GrpcTestBase(fixture) +public class GrpcSqlServerTest(GrpcSqlServerTest.GrpcSqlServerFixture fixture) + : GrpcTestBase(fixture) { public class GrpcSqlServerFixture : GrpcFixtureBase { diff --git a/test/EFCore.AspNet.Sqlite.FunctionalTests/AspNetIdentityCustomTypesDefaultSqliteTest.cs b/test/EFCore.AspNet.Sqlite.FunctionalTests/AspNetIdentityCustomTypesDefaultSqliteTest.cs index 44010191062..227a10d0e1f 100644 --- a/test/EFCore.AspNet.Sqlite.FunctionalTests/AspNetIdentityCustomTypesDefaultSqliteTest.cs +++ b/test/EFCore.AspNet.Sqlite.FunctionalTests/AspNetIdentityCustomTypesDefaultSqliteTest.cs @@ -3,8 +3,10 @@ namespace Microsoft.EntityFrameworkCore; -public class AspNetIdentityCustomTypesDefaultSqliteTest(AspNetIdentityCustomTypesDefaultSqliteTest.AspNetIdentityCustomTypesDefaultSqliteFixture fixture) - : AspNetIdentityCustomTypesDefaultTestBase(fixture) +public class AspNetIdentityCustomTypesDefaultSqliteTest( + AspNetIdentityCustomTypesDefaultSqliteTest.AspNetIdentityCustomTypesDefaultSqliteFixture fixture) + : AspNetIdentityCustomTypesDefaultTestBase( + fixture) { public class AspNetIdentityCustomTypesDefaultSqliteFixture : AspNetIdentityFixtureBase { diff --git a/test/EFCore.AspNet.Sqlite.FunctionalTests/AspNetIdentityCustomTypesIntKeySqliteTest.cs b/test/EFCore.AspNet.Sqlite.FunctionalTests/AspNetIdentityCustomTypesIntKeySqliteTest.cs index b1acef99e66..761322f6930 100644 --- a/test/EFCore.AspNet.Sqlite.FunctionalTests/AspNetIdentityCustomTypesIntKeySqliteTest.cs +++ b/test/EFCore.AspNet.Sqlite.FunctionalTests/AspNetIdentityCustomTypesIntKeySqliteTest.cs @@ -3,8 +3,10 @@ namespace Microsoft.EntityFrameworkCore; -public class AspNetIdentityCustomTypesIntKeySqliteTest(AspNetIdentityCustomTypesIntKeySqliteTest.AspNetIdentityCustomTypesIntKeySqliteFixture fixture) - : AspNetIdentityCustomTypesIntKeyTestBase(fixture) +public class AspNetIdentityCustomTypesIntKeySqliteTest( + AspNetIdentityCustomTypesIntKeySqliteTest.AspNetIdentityCustomTypesIntKeySqliteFixture fixture) + : AspNetIdentityCustomTypesIntKeyTestBase( + fixture) { public class AspNetIdentityCustomTypesIntKeySqliteFixture : AspNetIdentityFixtureBase { 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/ConcurrencyDetectorEnabledCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/ConcurrencyDetectorEnabledCosmosTest.cs index 03c35306ac1..d60d12e7e6f 100644 --- a/test/EFCore.Cosmos.FunctionalTests/ConcurrencyDetectorEnabledCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/ConcurrencyDetectorEnabledCosmosTest.cs @@ -5,8 +5,9 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class ConcurrencyDetectorEnabledCosmosTest(ConcurrencyDetectorEnabledCosmosTest.ConcurrencyDetectorCosmosFixture fixture) : ConcurrencyDetectorEnabledTestBase< - ConcurrencyDetectorEnabledCosmosTest.ConcurrencyDetectorCosmosFixture>(fixture) +public class ConcurrencyDetectorEnabledCosmosTest(ConcurrencyDetectorEnabledCosmosTest.ConcurrencyDetectorCosmosFixture fixture) + : ConcurrencyDetectorEnabledTestBase< + ConcurrencyDetectorEnabledCosmosTest.ConcurrencyDetectorCosmosFixture>(fixture) { [ConditionalTheory(Skip = "Issue #17246")] public override Task Any(bool async) diff --git a/test/EFCore.Cosmos.FunctionalTests/ConnectionSpecificationTest.cs b/test/EFCore.Cosmos.FunctionalTests/ConnectionSpecificationTest.cs index 538a02fd0c1..267ce8f173a 100644 --- a/test/EFCore.Cosmos.FunctionalTests/ConnectionSpecificationTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/ConnectionSpecificationTest.cs @@ -38,7 +38,8 @@ public async Task Throws_for_missing_connection_info() using var context = new NoConnectionContext(); var creator = context.GetService(); - Assert.Equal(CosmosStrings.ConnectionInfoMissing, + Assert.Equal( + CosmosStrings.ConnectionInfoMissing, (await Assert.ThrowsAsync(() => creator.EnsureDeletedAsync())).Message); } @@ -49,7 +50,6 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) .ConfigureWarnings(w => w.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning)); } - public class Blog { public int Id { get; set; } diff --git a/test/EFCore.Cosmos.FunctionalTests/CosmosApiConsistencyTest.cs b/test/EFCore.Cosmos.FunctionalTests/CosmosApiConsistencyTest.cs index 09653b48a99..10586e1f24e 100644 --- a/test/EFCore.Cosmos.FunctionalTests/CosmosApiConsistencyTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/CosmosApiConsistencyTest.cs @@ -7,7 +7,8 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class CosmosApiConsistencyTest(CosmosApiConsistencyTest.CosmosApiConsistencyFixture fixture) : ApiConsistencyTestBase(fixture) +public class CosmosApiConsistencyTest(CosmosApiConsistencyTest.CosmosApiConsistencyFixture fixture) + : ApiConsistencyTestBase(fixture) { protected override void AddServices(ServiceCollection serviceCollection) => serviceCollection.AddEntityFrameworkCosmos(); diff --git a/test/EFCore.Cosmos.FunctionalTests/CustomConvertersCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/CustomConvertersCosmosTest.cs index fb72ce681cf..4e3a0c0869c 100644 --- a/test/EFCore.Cosmos.FunctionalTests/CustomConvertersCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/CustomConvertersCosmosTest.cs @@ -11,9 +11,7 @@ public class CustomConvertersCosmosTest : CustomConvertersTestBase Fixture.TestSqlLoggerFactory.Clear(); [ConditionalTheory(Skip = "Issue #17246 No Explicit Convert")] public override Task Can_filter_projection_with_inline_enum_variable(bool async) diff --git a/test/EFCore.Cosmos.FunctionalTests/DefaultKeyValuesTest.cs b/test/EFCore.Cosmos.FunctionalTests/DefaultKeyValuesTest.cs index cafa4b3771b..5b07e8fd4d7 100644 --- a/test/EFCore.Cosmos.FunctionalTests/DefaultKeyValuesTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/DefaultKeyValuesTest.cs @@ -58,7 +58,13 @@ public async Task Composite_key_value_with_single_partition_key_must_have_key_se context.Add(new CompositeKeySinglePartitionKey { Id2 = Guid.NewGuid(), Id3 = true }); await AssertSaves(context); - context.Add(new CompositeKeySinglePartitionKey { Id1 = 1, Id2 = Guid.NewGuid(), Id3 = true }); + context.Add( + new CompositeKeySinglePartitionKey + { + Id1 = 1, + Id2 = Guid.NewGuid(), + Id3 = true + }); await AssertSaves(context); context.Add(new CompositeKeySinglePartitionKey { Id1 = 1, PartitionKey = 1 }); @@ -70,16 +76,41 @@ public async Task Composite_key_value_with_single_partition_key_must_have_key_se context.Add(new CompositeKeySinglePartitionKey { Id3 = true, PartitionKey = 1 }); await AssertSaves(context); - context.Add(new CompositeKeySinglePartitionKey { Id1 = 1, Id2 = Guid.NewGuid(), PartitionKey = 1 }); + context.Add( + new CompositeKeySinglePartitionKey + { + Id1 = 1, + Id2 = Guid.NewGuid(), + PartitionKey = 1 + }); await AssertSaves(context); - context.Add(new CompositeKeySinglePartitionKey { Id1 = 1, Id3 = true, PartitionKey = 1 }); + context.Add( + new CompositeKeySinglePartitionKey + { + Id1 = 1, + Id3 = true, + PartitionKey = 1 + }); await AssertSaves(context); - context.Add(new CompositeKeySinglePartitionKey { Id2 = Guid.NewGuid(), Id3 = true, PartitionKey = 1 }); + context.Add( + new CompositeKeySinglePartitionKey + { + Id2 = Guid.NewGuid(), + Id3 = true, + PartitionKey = 1 + }); await AssertSaves(context); - context.Add(new CompositeKeySinglePartitionKey { Id1 = 1, Id2 = Guid.NewGuid(), Id3 = true, PartitionKey = 1 }); + context.Add( + new CompositeKeySinglePartitionKey + { + Id1 = 1, + Id2 = Guid.NewGuid(), + Id3 = true, + PartitionKey = 1 + }); await AssertSaves(context); } @@ -100,16 +131,35 @@ public async Task Single_key_value_with_composite_partition_key_must_have_key_se context.Add(new SingleKeyCompositePartitionKey { PartitionKey3 = true }); await AssertKeyValueNotSet(context, nameof(SingleKeyCompositePartitionKey), nameof(SingleKeyCompositePartitionKey.Id)); - context.Add(new SingleKeyCompositePartitionKey { PartitionKey1 = 1, PartitionKey2 = Guid.NewGuid(), PartitionKey3 = true }); + context.Add( + new SingleKeyCompositePartitionKey + { + PartitionKey1 = 1, + PartitionKey2 = Guid.NewGuid(), + PartitionKey3 = true + }); await AssertKeyValueNotSet(context, nameof(SingleKeyCompositePartitionKey), nameof(SingleKeyCompositePartitionKey.Id)); context.Add(new SingleKeyCompositePartitionKey { Id = 1 }); await AssertSaves(context); - context.Add(new SingleKeyCompositePartitionKey { Id = 1, PartitionKey1 = 1, PartitionKey2 = Guid.NewGuid(), PartitionKey3 = true }); + context.Add( + new SingleKeyCompositePartitionKey + { + Id = 1, + PartitionKey1 = 1, + PartitionKey2 = Guid.NewGuid(), + PartitionKey3 = true + }); await AssertSaves(context); - context.Add(new SingleKeyCompositePartitionKey { Id = 1, PartitionKey2 = Guid.NewGuid(), PartitionKey3 = true }); + context.Add( + new SingleKeyCompositePartitionKey + { + Id = 1, + PartitionKey2 = Guid.NewGuid(), + PartitionKey3 = true + }); await AssertSaves(context); context.Add(new SingleKeyCompositePartitionKey { Id = 1, PartitionKey2 = Guid.NewGuid() }); @@ -133,19 +183,35 @@ public async Task Composite_key_value_with_composite_partition_key_must_have_key context.Add(new CompositeKeyCompositePartitionKey { PartitionKey3 = true }); await AssertKeyValueNotSet(context, nameof(CompositeKeyCompositePartitionKey), nameof(CompositeKeyCompositePartitionKey.Id3)); - context.Add(new CompositeKeyCompositePartitionKey { PartitionKey1 = 1, PartitionKey2 = Guid.NewGuid(), PartitionKey3 = true }); + context.Add( + new CompositeKeyCompositePartitionKey + { + PartitionKey1 = 1, + PartitionKey2 = Guid.NewGuid(), + PartitionKey3 = true + }); await AssertKeyValueNotSet(context, nameof(CompositeKeyCompositePartitionKey), nameof(CompositeKeyCompositePartitionKey.Id3)); context.Add(new CompositeKeyCompositePartitionKey { Id1 = 1 }); await AssertSaves(context); - context.Add(new CompositeKeyCompositePartitionKey - { - Id1 = 1, PartitionKey1 = 1, PartitionKey2 = Guid.NewGuid(), PartitionKey3 = true - }); + context.Add( + new CompositeKeyCompositePartitionKey + { + Id1 = 1, + PartitionKey1 = 1, + PartitionKey2 = Guid.NewGuid(), + PartitionKey3 = true + }); await AssertSaves(context); - context.Add(new CompositeKeyCompositePartitionKey { Id1 = 1, PartitionKey2 = Guid.NewGuid(), PartitionKey3 = true }); + context.Add( + new CompositeKeyCompositePartitionKey + { + Id1 = 1, + PartitionKey2 = Guid.NewGuid(), + PartitionKey3 = true + }); await AssertSaves(context); context.Add(new CompositeKeyCompositePartitionKey { Id1 = 1, PartitionKey2 = Guid.NewGuid() }); @@ -154,13 +220,23 @@ public async Task Composite_key_value_with_composite_partition_key_must_have_key context.Add(new CompositeKeyCompositePartitionKey { Id2 = Guid.NewGuid() }); await AssertSaves(context); - context.Add(new CompositeKeyCompositePartitionKey - { - Id2 = Guid.NewGuid(), PartitionKey1 = 1, PartitionKey2 = Guid.NewGuid(), PartitionKey3 = true - }); + context.Add( + new CompositeKeyCompositePartitionKey + { + Id2 = Guid.NewGuid(), + PartitionKey1 = 1, + PartitionKey2 = Guid.NewGuid(), + PartitionKey3 = true + }); await AssertSaves(context); - context.Add(new CompositeKeyCompositePartitionKey { Id2 = Guid.NewGuid(), PartitionKey2 = Guid.NewGuid(), PartitionKey3 = true }); + context.Add( + new CompositeKeyCompositePartitionKey + { + Id2 = Guid.NewGuid(), + PartitionKey2 = Guid.NewGuid(), + PartitionKey3 = true + }); await AssertSaves(context); context.Add(new CompositeKeyCompositePartitionKey { Id2 = Guid.NewGuid(), PartitionKey2 = Guid.NewGuid() }); @@ -169,13 +245,23 @@ public async Task Composite_key_value_with_composite_partition_key_must_have_key context.Add(new CompositeKeyCompositePartitionKey { Id3 = true }); await AssertSaves(context); - context.Add(new CompositeKeyCompositePartitionKey - { - Id3 = true, PartitionKey1 = 1, PartitionKey2 = Guid.NewGuid(), PartitionKey3 = true - }); + context.Add( + new CompositeKeyCompositePartitionKey + { + Id3 = true, + PartitionKey1 = 1, + PartitionKey2 = Guid.NewGuid(), + PartitionKey3 = true + }); await AssertSaves(context); - context.Add(new CompositeKeyCompositePartitionKey { Id3 = true, PartitionKey2 = Guid.NewGuid(), PartitionKey3 = true }); + context.Add( + new CompositeKeyCompositePartitionKey + { + Id3 = true, + PartitionKey2 = Guid.NewGuid(), + PartitionKey3 = true + }); await AssertSaves(context); context.Add(new CompositeKeyCompositePartitionKey { Id3 = true, PartitionKey2 = Guid.NewGuid() }); @@ -211,7 +297,13 @@ public async Task Composite_same_key_and_partition_key_must_have_key_set() context.Add(new CompositeSameKeyAndPartitionKey { Key3 = true }); await AssertSaves(context); - context.Add(new CompositeSameKeyAndPartitionKey { Key1 = 1, Key2 = Guid.NewGuid(), Key3 = true }); + context.Add( + new CompositeSameKeyAndPartitionKey + { + Key1 = 1, + Key2 = Guid.NewGuid(), + Key3 = true + }); await AssertSaves(context); } @@ -262,7 +354,13 @@ public async Task Composite_key_value_with_single_partition_key_can_use_generate context.Add(new CompositeGeneratedKeySinglePartitionKey { Id2 = Guid.NewGuid(), Id3 = true }); await AssertSaves(context); - context.Add(new CompositeGeneratedKeySinglePartitionKey { Id1 = 1, Id2 = Guid.NewGuid(), Id3 = true }); + context.Add( + new CompositeGeneratedKeySinglePartitionKey + { + Id1 = 1, + Id2 = Guid.NewGuid(), + Id3 = true + }); await AssertSaves(context); context.Add(new CompositeGeneratedKeySinglePartitionKey { Id1 = 1, PartitionKey = 1 }); @@ -274,16 +372,41 @@ public async Task Composite_key_value_with_single_partition_key_can_use_generate context.Add(new CompositeGeneratedKeySinglePartitionKey { Id3 = true, PartitionKey = 1 }); await AssertSaves(context); - context.Add(new CompositeGeneratedKeySinglePartitionKey { Id1 = 1, Id2 = Guid.NewGuid(), PartitionKey = 1 }); + context.Add( + new CompositeGeneratedKeySinglePartitionKey + { + Id1 = 1, + Id2 = Guid.NewGuid(), + PartitionKey = 1 + }); await AssertSaves(context); - context.Add(new CompositeGeneratedKeySinglePartitionKey { Id1 = 1, Id3 = true, PartitionKey = 1 }); + context.Add( + new CompositeGeneratedKeySinglePartitionKey + { + Id1 = 1, + Id3 = true, + PartitionKey = 1 + }); await AssertSaves(context); - context.Add(new CompositeGeneratedKeySinglePartitionKey { Id2 = Guid.NewGuid(), Id3 = true, PartitionKey = 1 }); + context.Add( + new CompositeGeneratedKeySinglePartitionKey + { + Id2 = Guid.NewGuid(), + Id3 = true, + PartitionKey = 1 + }); await AssertSaves(context); - context.Add(new CompositeGeneratedKeySinglePartitionKey { Id1 = 1, Id2 = Guid.NewGuid(), Id3 = true, PartitionKey = 1 }); + context.Add( + new CompositeGeneratedKeySinglePartitionKey + { + Id1 = 1, + Id2 = Guid.NewGuid(), + Id3 = true, + PartitionKey = 1 + }); await AssertSaves(context); } @@ -304,16 +427,35 @@ public async Task Single_key_value_with_composite_partition_key_can_use_generate context.Add(new SingleGeneratedKeyCompositePartitionKey { PartitionKey3 = true }); await AssertSaves(context); - context.Add(new SingleGeneratedKeyCompositePartitionKey { PartitionKey1 = 1, PartitionKey2 = Guid.NewGuid(), PartitionKey3 = true }); + context.Add( + new SingleGeneratedKeyCompositePartitionKey + { + PartitionKey1 = 1, + PartitionKey2 = Guid.NewGuid(), + PartitionKey3 = true + }); await AssertSaves(context); context.Add(new SingleGeneratedKeyCompositePartitionKey { Id = Guid.NewGuid() }); await AssertSaves(context); - context.Add(new SingleGeneratedKeyCompositePartitionKey { Id = Guid.NewGuid(), PartitionKey1 = 1, PartitionKey2 = Guid.NewGuid(), PartitionKey3 = true }); + context.Add( + new SingleGeneratedKeyCompositePartitionKey + { + Id = Guid.NewGuid(), + PartitionKey1 = 1, + PartitionKey2 = Guid.NewGuid(), + PartitionKey3 = true + }); await AssertSaves(context); - context.Add(new SingleGeneratedKeyCompositePartitionKey { Id = Guid.NewGuid(), PartitionKey2 = Guid.NewGuid(), PartitionKey3 = true }); + context.Add( + new SingleGeneratedKeyCompositePartitionKey + { + Id = Guid.NewGuid(), + PartitionKey2 = Guid.NewGuid(), + PartitionKey3 = true + }); await AssertSaves(context); context.Add(new SingleGeneratedKeyCompositePartitionKey { Id = Guid.NewGuid(), PartitionKey2 = Guid.NewGuid() }); @@ -337,19 +479,35 @@ public async Task Composite_key_value_with_composite_partition_key_can_use_gener context.Add(new CompositeGeneratedKeyCompositePartitionKey { PartitionKey3 = true }); await AssertSaves(context); - context.Add(new CompositeGeneratedKeyCompositePartitionKey { PartitionKey1 = 1, PartitionKey2 = Guid.NewGuid(), PartitionKey3 = true }); + context.Add( + new CompositeGeneratedKeyCompositePartitionKey + { + PartitionKey1 = 1, + PartitionKey2 = Guid.NewGuid(), + PartitionKey3 = true + }); await AssertSaves(context); context.Add(new CompositeGeneratedKeyCompositePartitionKey { Id1 = 1 }); await AssertSaves(context); - context.Add(new CompositeGeneratedKeyCompositePartitionKey - { - Id1 = 1, PartitionKey1 = 1, PartitionKey2 = Guid.NewGuid(), PartitionKey3 = true - }); + context.Add( + new CompositeGeneratedKeyCompositePartitionKey + { + Id1 = 1, + PartitionKey1 = 1, + PartitionKey2 = Guid.NewGuid(), + PartitionKey3 = true + }); await AssertSaves(context); - context.Add(new CompositeGeneratedKeyCompositePartitionKey { Id1 = 1, PartitionKey2 = Guid.NewGuid(), PartitionKey3 = true }); + context.Add( + new CompositeGeneratedKeyCompositePartitionKey + { + Id1 = 1, + PartitionKey2 = Guid.NewGuid(), + PartitionKey3 = true + }); await AssertSaves(context); context.Add(new CompositeGeneratedKeyCompositePartitionKey { Id1 = 1, PartitionKey2 = Guid.NewGuid() }); @@ -358,13 +516,23 @@ public async Task Composite_key_value_with_composite_partition_key_can_use_gener context.Add(new CompositeGeneratedKeyCompositePartitionKey { Id2 = Guid.NewGuid() }); await AssertSaves(context); - context.Add(new CompositeGeneratedKeyCompositePartitionKey - { - Id2 = Guid.NewGuid(), PartitionKey1 = 1, PartitionKey2 = Guid.NewGuid(), PartitionKey3 = true - }); + context.Add( + new CompositeGeneratedKeyCompositePartitionKey + { + Id2 = Guid.NewGuid(), + PartitionKey1 = 1, + PartitionKey2 = Guid.NewGuid(), + PartitionKey3 = true + }); await AssertSaves(context); - context.Add(new CompositeGeneratedKeyCompositePartitionKey { Id2 = Guid.NewGuid(), PartitionKey2 = Guid.NewGuid(), PartitionKey3 = true }); + context.Add( + new CompositeGeneratedKeyCompositePartitionKey + { + Id2 = Guid.NewGuid(), + PartitionKey2 = Guid.NewGuid(), + PartitionKey3 = true + }); await AssertSaves(context); context.Add(new CompositeGeneratedKeyCompositePartitionKey { Id2 = Guid.NewGuid(), PartitionKey2 = Guid.NewGuid() }); @@ -373,13 +541,23 @@ public async Task Composite_key_value_with_composite_partition_key_can_use_gener context.Add(new CompositeGeneratedKeyCompositePartitionKey { Id3 = true }); await AssertSaves(context); - context.Add(new CompositeGeneratedKeyCompositePartitionKey - { - Id3 = true, PartitionKey1 = 1, PartitionKey2 = Guid.NewGuid(), PartitionKey3 = true - }); + context.Add( + new CompositeGeneratedKeyCompositePartitionKey + { + Id3 = true, + PartitionKey1 = 1, + PartitionKey2 = Guid.NewGuid(), + PartitionKey3 = true + }); await AssertSaves(context); - context.Add(new CompositeGeneratedKeyCompositePartitionKey { Id3 = true, PartitionKey2 = Guid.NewGuid(), PartitionKey3 = true }); + context.Add( + new CompositeGeneratedKeyCompositePartitionKey + { + Id3 = true, + PartitionKey2 = Guid.NewGuid(), + PartitionKey3 = true + }); await AssertSaves(context); context.Add(new CompositeGeneratedKeyCompositePartitionKey { Id3 = true, PartitionKey2 = Guid.NewGuid() }); @@ -415,7 +593,13 @@ public async Task Composite_same_key_and_partition_key_can_use_generated_value() context.Add(new CompositeSameGeneratedKeyAndPartitionKey { Key3 = true }); await AssertSaves(context); - context.Add(new CompositeSameGeneratedKeyAndPartitionKey { Key1 = 1, Key2 = Guid.NewGuid(), Key3 = true }); + context.Add( + new CompositeSameGeneratedKeyAndPartitionKey + { + Key1 = 1, + Key2 = Guid.NewGuid(), + Key3 = true + }); await AssertSaves(context); } @@ -431,7 +615,9 @@ private static async Task AssertSaves(DefaultKeyValuesTestContext context) } private static async Task AssertKeyValueNotSet( - DefaultKeyValuesTestContext context, string entityTypeName, string propertyName) + DefaultKeyValuesTestContext context, + string entityTypeName, + string propertyName) { Assert.Equal( CoreStrings.WarningAsErrorTemplate( @@ -466,95 +652,201 @@ public class DefaultKeyValuesTestContext(DbContextOptions dbContextOptions) : Db { protected override void OnModelCreating(ModelBuilder modelBuilder) { - modelBuilder.Entity(b => - { - b.ToContainer(b.Metadata.ClrType.Name); - b.HasPartitionKey(e => e.PartitionKey); - b.HasKey(e => new { e.Id, e.PartitionKey }); - }); - - modelBuilder.Entity(b => - { - b.ToContainer(b.Metadata.ClrType.Name); - b.HasPartitionKey(e => e.PartitionKey); - b.HasKey(e => new { e.Id1, e.Id2, e.Id3, e.PartitionKey }); - }); - - modelBuilder.Entity(b => - { - b.ToContainer(b.Metadata.ClrType.Name); - b.HasPartitionKey(e => new { e.PartitionKey1, e.PartitionKey2, e.PartitionKey3 }); - b.HasKey(e => new { e.Id, e.PartitionKey1, e.PartitionKey2, e.PartitionKey3 }); - }); - - modelBuilder.Entity(b => - { - b.ToContainer(b.Metadata.ClrType.Name); - b.HasPartitionKey(e => new { e.PartitionKey1, e.PartitionKey2, e.PartitionKey3 }); - b.HasKey(e => new { e.Id1, e.Id2, e.Id3, e.PartitionKey1, e.PartitionKey2, e.PartitionKey3 }); - }); - - modelBuilder.Entity(b => - { - b.ToContainer(b.Metadata.ClrType.Name); - b.HasPartitionKey(e => e.Id); - b.HasKey(e => e.Id); - }); - - modelBuilder.Entity(b => - { - b.ToContainer(b.Metadata.ClrType.Name); - b.HasPartitionKey(e => new { e.Key1, e.Key2, e.Key3 }); - b.HasKey(e => new { e.Key1, e.Key2, e.Key3 }); - }); - - modelBuilder.Entity(b => - { - b.ToContainer(b.Metadata.ClrType.Name); - b.HasPartitionKey(e => e.PartitionKey); - b.HasKey(e => new { e.Id, e.PartitionKey }); - b.Property(e => e.Id).ValueGeneratedOnAdd(); - }); - - modelBuilder.Entity(b => - { - b.ToContainer(b.Metadata.ClrType.Name); - b.HasPartitionKey(e => e.PartitionKey); - b.HasKey(e => new { e.Id1, e.Id2, e.Id3, e.PartitionKey }); - b.Property(e => e.Id2).ValueGeneratedOnAdd(); - }); - - modelBuilder.Entity(b => - { - b.ToContainer(b.Metadata.ClrType.Name); - b.HasPartitionKey(e => new { e.PartitionKey1, e.PartitionKey2, e.PartitionKey3 }); - b.HasKey(e => new { e.Id, e.PartitionKey1, e.PartitionKey2, e.PartitionKey3 }); - b.Property(e => e.Id).ValueGeneratedOnAdd(); - }); - - modelBuilder.Entity(b => - { - b.ToContainer(b.Metadata.ClrType.Name); - b.HasPartitionKey(e => new { e.PartitionKey1, e.PartitionKey2, e.PartitionKey3 }); - b.HasKey(e => new { e.Id1, e.Id2, e.Id3, e.PartitionKey1, e.PartitionKey2, e.PartitionKey3 }); - b.Property(e => e.Id2).ValueGeneratedOnAdd(); - }); - - modelBuilder.Entity(b => - { - b.ToContainer(b.Metadata.ClrType.Name); - b.HasPartitionKey(e => e.Id); - b.HasKey(e => e.Id); - b.Property(e => e.Id).ValueGeneratedOnAdd(); - }); - - modelBuilder.Entity(b => - { - b.ToContainer(b.Metadata.ClrType.Name); - b.HasPartitionKey(e => new { e.Key1, e.Key2, e.Key3 }); - b.HasKey(e => new { e.Key1, e.Key2, e.Key3 }); - b.Property(e => e.Key2).ValueGeneratedOnAdd(); - }); + modelBuilder.Entity( + b => + { + b.ToContainer(b.Metadata.ClrType.Name); + b.HasPartitionKey(e => e.PartitionKey); + b.HasKey(e => new { e.Id, e.PartitionKey }); + }); + + modelBuilder.Entity( + b => + { + b.ToContainer(b.Metadata.ClrType.Name); + b.HasPartitionKey(e => e.PartitionKey); + b.HasKey( + e => new + { + e.Id1, + e.Id2, + e.Id3, + e.PartitionKey + }); + }); + + modelBuilder.Entity( + b => + { + b.ToContainer(b.Metadata.ClrType.Name); + b.HasPartitionKey( + e => new + { + e.PartitionKey1, + e.PartitionKey2, + e.PartitionKey3 + }); + b.HasKey( + e => new + { + e.Id, + e.PartitionKey1, + e.PartitionKey2, + e.PartitionKey3 + }); + }); + + modelBuilder.Entity( + b => + { + b.ToContainer(b.Metadata.ClrType.Name); + b.HasPartitionKey( + e => new + { + e.PartitionKey1, + e.PartitionKey2, + e.PartitionKey3 + }); + b.HasKey( + e => new + { + e.Id1, + e.Id2, + e.Id3, + e.PartitionKey1, + e.PartitionKey2, + e.PartitionKey3 + }); + }); + + modelBuilder.Entity( + b => + { + b.ToContainer(b.Metadata.ClrType.Name); + b.HasPartitionKey(e => e.Id); + b.HasKey(e => e.Id); + }); + + modelBuilder.Entity( + b => + { + b.ToContainer(b.Metadata.ClrType.Name); + b.HasPartitionKey( + e => new + { + e.Key1, + e.Key2, + e.Key3 + }); + b.HasKey( + e => new + { + e.Key1, + e.Key2, + e.Key3 + }); + }); + + modelBuilder.Entity( + b => + { + b.ToContainer(b.Metadata.ClrType.Name); + b.HasPartitionKey(e => e.PartitionKey); + b.HasKey(e => new { e.Id, e.PartitionKey }); + b.Property(e => e.Id).ValueGeneratedOnAdd(); + }); + + modelBuilder.Entity( + b => + { + b.ToContainer(b.Metadata.ClrType.Name); + b.HasPartitionKey(e => e.PartitionKey); + b.HasKey( + e => new + { + e.Id1, + e.Id2, + e.Id3, + e.PartitionKey + }); + b.Property(e => e.Id2).ValueGeneratedOnAdd(); + }); + + modelBuilder.Entity( + b => + { + b.ToContainer(b.Metadata.ClrType.Name); + b.HasPartitionKey( + e => new + { + e.PartitionKey1, + e.PartitionKey2, + e.PartitionKey3 + }); + b.HasKey( + e => new + { + e.Id, + e.PartitionKey1, + e.PartitionKey2, + e.PartitionKey3 + }); + b.Property(e => e.Id).ValueGeneratedOnAdd(); + }); + + modelBuilder.Entity( + b => + { + b.ToContainer(b.Metadata.ClrType.Name); + b.HasPartitionKey( + e => new + { + e.PartitionKey1, + e.PartitionKey2, + e.PartitionKey3 + }); + b.HasKey( + e => new + { + e.Id1, + e.Id2, + e.Id3, + e.PartitionKey1, + e.PartitionKey2, + e.PartitionKey3 + }); + b.Property(e => e.Id2).ValueGeneratedOnAdd(); + }); + + modelBuilder.Entity( + b => + { + b.ToContainer(b.Metadata.ClrType.Name); + b.HasPartitionKey(e => e.Id); + b.HasKey(e => e.Id); + b.Property(e => e.Id).ValueGeneratedOnAdd(); + }); + + modelBuilder.Entity( + b => + { + b.ToContainer(b.Metadata.ClrType.Name); + b.HasPartitionKey( + e => new + { + e.Key1, + e.Key2, + e.Key3 + }); + b.HasKey( + e => new + { + e.Key1, + e.Key2, + e.Key3 + }); + b.Property(e => e.Key2).ValueGeneratedOnAdd(); + }); } } 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/EmbeddedDocumentsTest.cs b/test/EFCore.Cosmos.FunctionalTests/EmbeddedDocumentsTest.cs index ffd405b6f86..b2b6b0c8f29 100644 --- a/test/EFCore.Cosmos.FunctionalTests/EmbeddedDocumentsTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/EmbeddedDocumentsTest.cs @@ -720,8 +720,8 @@ protected override object GetAdditionalModelCacheKey(DbContext context) public Task InitializeAsync() => Task.CompletedTask; - public Task DisposeAsync() - => TestStore.DisposeAsync(); + public async Task DisposeAsync() + => await TestStore.DisposeAsync(); } public record class EmbeddedTransportationContextOptions(DbContextOptions Options, Action OnModelCreating); diff --git a/test/EFCore.Cosmos.FunctionalTests/EndToEndCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/EndToEndCosmosTest.cs index 19768aa764f..c4691b71fca 100644 --- a/test/EFCore.Cosmos.FunctionalTests/EndToEndCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/EndToEndCosmosTest.cs @@ -700,12 +700,12 @@ public async Task Entities_with_null_PK_can_be_added_with_normal_use_of_DbContex var entry = await context.AddAsync(item); - var id = entry.Property("__id").CurrentValue; + var id = entry.Property("Id").CurrentValue; Assert.NotNull(item.Id); Assert.NotNull(id); - Assert.Equal($"{item.Id}", id); + Assert.Equal(item.Id, id); Assert.Equal(EntityState.Added, entry.State); } @@ -933,8 +933,7 @@ await Can_add_update_delete_with_collection( await Can_add_update_delete_with_collection>>( new Dictionary> { - { "2" , new Dictionary { { "value", 2 } } }, - { "1" , new Dictionary { { "value", 1 } } } + { "2", new Dictionary { { "value", 2 } } }, { "1", new Dictionary { { "value", 1 } } } }, c => { @@ -1525,8 +1524,21 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) => modelBuilder.Entity( cb => { - cb.HasPartitionKey(c => new { c.PartitionKey1, c.PartitionKey2, c.PartitionKey3 }); - cb.HasKey(c => new { c.Id, c.PartitionKey1, c.PartitionKey2, c.PartitionKey3 }); + cb.HasPartitionKey( + c => new + { + c.PartitionKey1, + c.PartitionKey2, + c.PartitionKey3 + }); + cb.HasKey( + c => new + { + c.Id, + c.PartitionKey1, + c.PartitionKey2, + c.PartitionKey3 + }); }); } @@ -1613,7 +1625,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) => modelBuilder.Entity( cb => { - cb.HasPartitionKey(c => new { c.PartitionKey1, c.PartitionKey2 } ); + cb.HasPartitionKey(c => new { c.PartitionKey1, c.PartitionKey2 }); cb.Property(c => c.id).HasConversion(); cb.HasKey(c => new { c.id }); }); @@ -1625,8 +1637,14 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) => modelBuilder.Entity( cb => { - cb.HasPartitionKey(c => new { c.PartitionKey1, c.PartitionKey2 } ); - cb.HasKey(c => new { c.PartitionKey1, c.PartitionKey2, c.id }); + cb.HasPartitionKey(c => new { c.PartitionKey1, c.PartitionKey2 }); + cb.HasKey( + c => new + { + c.PartitionKey1, + c.PartitionKey2, + c.id + }); }); } diff --git a/test/EFCore.Cosmos.FunctionalTests/F1CosmosFixture.cs b/test/EFCore.Cosmos.FunctionalTests/F1CosmosFixture.cs index bb18ffb7ed1..78894274ba2 100644 --- a/test/EFCore.Cosmos.FunctionalTests/F1CosmosFixture.cs +++ b/test/EFCore.Cosmos.FunctionalTests/F1CosmosFixture.cs @@ -16,20 +16,19 @@ protected override ITestStoreFactory TestStoreFactory public override TestHelpers TestHelpers => CosmosTestHelpers.Instance; - public override async Task ReseedAsync() + protected override async Task ShouldSeedAsync(F1Context context) { - await base.ReseedAsync(); - - using var context = CreateContext(); try { - await context.Teams.SingleAsync(t => t.Id == Team.Ferrari); + await base.ShouldSeedAsync(context); } catch { // Recreating the containers without using CosmosClient causes cached metadata in CosmosClient to be out of sync // and causes the first query to fail. This is a workaround for that. } + + return await base.ShouldSeedAsync(context); } public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) diff --git a/test/EFCore.Cosmos.FunctionalTests/FindCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/FindCosmosTest.cs index 20b4510389e..c282f9903e2 100644 --- a/test/EFCore.Cosmos.FunctionalTests/FindCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/FindCosmosTest.cs @@ -9,9 +9,7 @@ public abstract class FindCosmosTest : FindTestBase fixture.TestSqlLoggerFactory.Clear(); [ConditionalFact(Skip = "#25886")] public override void Find_base_type_using_derived_set_tracked() { } @@ -72,7 +70,7 @@ public override void Find_shadow_key_from_store() public override void Returns_null_for_shadow_key_not_in_store() => CosmosTestHelpers.Instance.NoSyncTest(() => base.Returns_null_for_shadow_key_not_in_store()); - public override void Find_int_key_tracked() + public override void Find_int_key_tracked() { base.Find_int_key_tracked(); @@ -463,11 +461,11 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con modelBuilder.Entity() .ToContainer("Ints") - .IncludeRootDiscriminatorInJsonId(); + .HasRootDiscriminatorInJsonId(); modelBuilder.Entity() .ToContainer("Ints") - .IncludeRootDiscriminatorInJsonId(); + .HasRootDiscriminatorInJsonId(); modelBuilder.Entity() .ToContainer("Strings"); @@ -477,7 +475,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con modelBuilder.Entity() .ToContainer("Base") - .IncludeRootDiscriminatorInJsonId(); + .HasRootDiscriminatorInJsonId(); modelBuilder.Entity().ToContainer("ShadowKeys"); } diff --git a/test/EFCore.Cosmos.FunctionalTests/HierarchicalPartitionKeyTest.cs b/test/EFCore.Cosmos.FunctionalTests/HierarchicalPartitionKeyTest.cs index 09e0df1b715..d3e2157c475 100644 --- a/test/EFCore.Cosmos.FunctionalTests/HierarchicalPartitionKeyTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/HierarchicalPartitionKeyTest.cs @@ -275,8 +275,21 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) => modelBuilder.Entity( cb => { - cb.HasPartitionKey(c => new { c.PartitionKey1, c.PartitionKey2, c.PartitionKey3 }); - cb.HasKey(c => new { c.Id, c.PartitionKey1, c.PartitionKey2, c.PartitionKey3 }); + cb.HasPartitionKey( + c => new + { + c.PartitionKey1, + c.PartitionKey2, + c.PartitionKey3 + }); + cb.HasKey( + c => new + { + c.Id, + c.PartitionKey1, + c.PartitionKey2, + c.PartitionKey3 + }); }); } diff --git a/test/EFCore.Cosmos.FunctionalTests/JsonTypesCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/JsonTypesCosmosTest.cs index 13af27e4217..49754ed19a5 100644 --- a/test/EFCore.Cosmos.FunctionalTests/JsonTypesCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/JsonTypesCosmosTest.cs @@ -45,7 +45,8 @@ public override Task Can_read_write_list_of_array_of_GUID_JSON_values(string exp public override Task Can_read_write_list_of_array_of_list_of_array_of_binary_JSON_values(string expected) // Cosmos provider cannot map collections of elements with converters. See Issue #34026. - => Assert.ThrowsAsync(() => base.Can_read_write_list_of_array_of_list_of_array_of_binary_JSON_values(expected)); + => Assert.ThrowsAsync( + () => base.Can_read_write_list_of_array_of_list_of_array_of_binary_JSON_values(expected)); public override Task Can_read_write_list_of_array_of_nullable_GUID_JSON_values(string expected) // Cosmos provider cannot map collections of elements with converters. See Issue #34026. diff --git a/test/EFCore.Cosmos.FunctionalTests/KeysWithConvertersCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/KeysWithConvertersCosmosTest.cs index 41c88fe1f4b..c365f06debe 100644 --- a/test/EFCore.Cosmos.FunctionalTests/KeysWithConvertersCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/KeysWithConvertersCosmosTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class KeysWithConvertersCosmosTest(KeysWithConvertersCosmosTest.KeysWithConvertersCosmosFixture fixture) : KeysWithConvertersTestBase(fixture) +public class KeysWithConvertersCosmosTest(KeysWithConvertersCosmosTest.KeysWithConvertersCosmosFixture fixture) + : KeysWithConvertersTestBase(fixture) { public class KeysWithConvertersCosmosFixture : KeysWithConvertersFixtureBase { @@ -19,7 +20,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con { base.OnModelCreating(modelBuilder, context); - modelBuilder.IncludeRootDiscriminatorInJsonId(); + modelBuilder.HasRootDiscriminatorInJsonId(); } public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) diff --git a/test/EFCore.Cosmos.FunctionalTests/ModelBuilding/CosmosModelBuilderGenericTest.cs b/test/EFCore.Cosmos.FunctionalTests/ModelBuilding/CosmosModelBuilderGenericTest.cs index 204e96295a2..0865ab00f6d 100644 --- a/test/EFCore.Cosmos.FunctionalTests/ModelBuilding/CosmosModelBuilderGenericTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/ModelBuilding/CosmosModelBuilderGenericTest.cs @@ -10,7 +10,8 @@ namespace Microsoft.EntityFrameworkCore.ModelBuilding; public class CosmosModelBuilderGenericTest : ModelBuilderTest { - public class CosmosGenericNonRelationship(CosmosModelBuilderFixture fixture) : NonRelationshipTestBase(fixture), IClassFixture + public class CosmosGenericNonRelationship(CosmosModelBuilderFixture fixture) + : NonRelationshipTestBase(fixture), IClassFixture { // Cosmos provider cannot map collections of elements with converters. See Issue #34026. public override void Element_types_can_have_custom_type_value_converter_type_set() @@ -177,7 +178,13 @@ public virtual void Three_level_hierarchical_partition_key_is_added_to_the_keys( modelBuilder.Entity() .Ignore(b => b.Details) .Ignore(b => b.Orders) - .HasPartitionKey(b => new { b.Title, b.Name, b.AlternateKey }) + .HasPartitionKey( + b => new + { + b.Title, + b.Name, + b.AlternateKey + }) .Property(b => b.AlternateKey).HasConversion(); var model = modelBuilder.FinalizeModel(); @@ -470,12 +477,7 @@ public virtual void Hierarchical_partition_key_is_added_to_the_alternate_key_if_ entity.GetPartitionKeyProperties().Select(p => p.Name)); Assert.Equal( - new[] - { - nameof(Customer.Title), - nameof(Customer.AlternateKey), - CosmosJsonIdConvention.DefaultIdPropertyName - }, + new[] { nameof(Customer.Title), nameof(Customer.AlternateKey), CosmosJsonIdConvention.DefaultIdPropertyName }, entity.FindPrimaryKey()!.Properties.Select(p => p.Name)); } @@ -506,11 +508,23 @@ public virtual void No_alternate_key_is_created_if_id_is_hierarchical_partition_ { var modelBuilder = CreateModelBuilder(); - modelBuilder.Entity().HasKey(e => new { e.Name, e.AlternateKey, e.Title }); + modelBuilder.Entity().HasKey( + e => new + { + e.Name, + e.AlternateKey, + e.Title + }); modelBuilder.Entity() .Ignore(b => b.Details) .Ignore(b => b.Orders) - .HasPartitionKey(b => new { b.Name, b.AlternateKey, b.Title }) + .HasPartitionKey( + b => new + { + b.Name, + b.AlternateKey, + b.Title + }) .Property(b => b.AlternateKey).HasConversion().ToJsonProperty("id"); var model = modelBuilder.FinalizeModel(); @@ -523,11 +537,192 @@ public virtual void No_alternate_key_is_created_if_id_is_hierarchical_partition_ Assert.DoesNotContain(entity.GetKeys(), k => k != entity.FindPrimaryKey()); } + [ConditionalFact] + public virtual void Single_string_primary_key_maps_to_JSON_id() + { + var modelBuilder = CreateModelBuilder(); + + modelBuilder.Entity(); + + var model = modelBuilder.FinalizeModel(); + + var entityType = model.FindEntityType(typeof(SingleStringKey))!; + + Assert.Equal( + [nameof(SingleStringKey.Id)], + entityType.FindPrimaryKey()!.Properties.Select(p => p.Name)); + + Assert.Equal( + [ + nameof(SingleStringKey.Id), "$type", nameof(SingleStringKey.Name), nameof(SingleStringKey.P1), + nameof(SingleStringKey.P2), nameof(SingleStringKey.P3), "__jObject" + ], + entityType.GetProperties().Select(p => p.Name)); + + Assert.Equal(1, entityType.GetKeys().Count()); + Assert.Null(entityType.FindProperty("__id")); + Assert.Equal("id", entityType.FindProperty("Id")!.GetJsonPropertyName()); + } + + [ConditionalFact] // Issue #34511 + public virtual void Single_string_primary_key_with_single_partition_key_maps_to_JSON_id() + { + var modelBuilder = CreateModelBuilder(); + + modelBuilder.Entity().HasPartitionKey(e => e.P1); + + var model = modelBuilder.FinalizeModel(); + + var entityType = model.FindEntityType(typeof(SingleStringKey))!; + + Assert.Equal( + [nameof(SingleStringKey.Id), nameof(SingleStringKey.P1)], + entityType.FindPrimaryKey()!.Properties.Select(p => p.Name)); + + Assert.Equal( + [ + nameof(SingleStringKey.Id), nameof(SingleStringKey.P1), "$type", nameof(SingleStringKey.Name), + nameof(SingleStringKey.P2), nameof(SingleStringKey.P3), "__jObject" + ], + entityType.GetProperties().Select(p => p.Name)); + + Assert.Equal(1, entityType.GetKeys().Count()); + Assert.Null(entityType.FindProperty("__id")); + Assert.Equal("id", entityType.FindProperty("Id")!.GetJsonPropertyName()); + } + + [ConditionalFact] // Issue #34511 + public virtual void Single_string_primary_key_with_hierarchical_partition_key_maps_to_JSON_id() + { + var modelBuilder = CreateModelBuilder(); + + modelBuilder.Entity().HasPartitionKey(e => new { e.P1, e.P2, e.P3 }); + + var model = modelBuilder.FinalizeModel(); + + var entityType = model.FindEntityType(typeof(SingleStringKey))!; + + Assert.Equal( + [nameof(SingleStringKey.Id), nameof(SingleStringKey.P1), nameof(SingleStringKey.P2), nameof(SingleStringKey.P3)], + entityType.FindPrimaryKey()!.Properties.Select(p => p.Name)); + + Assert.Equal( + [ + nameof(SingleStringKey.Id), nameof(SingleStringKey.P1), nameof(SingleStringKey.P2), nameof(SingleStringKey.P3), + "$type", nameof(SingleStringKey.Name), "__jObject" + ], + entityType.GetProperties().Select(p => p.Name)); + + Assert.Equal(1, entityType.GetKeys().Count()); + Assert.Null(entityType.FindProperty("__id")); + Assert.Equal("id", entityType.FindProperty("Id")!.GetJsonPropertyName()); + } + + protected class SingleStringKey + { + public string Id { get; set; } = null!; + public string? Name { get; set; } + public string P1 { get; set; } = null!; + public string P2 { get; set; } = null!; + public string P3 { get; set; } = null!; + } + + [ConditionalFact] // Issue #34554 + public virtual void Single_GUID_primary_key_maps_to_JSON_id() + { + var modelBuilder = CreateModelBuilder(); + + modelBuilder.Entity(); + + var model = modelBuilder.FinalizeModel(); + + var entityType = model.FindEntityType(typeof(SingleGuidKey))!; + + Assert.Equal( + [nameof(SingleGuidKey.Id)], + entityType.FindPrimaryKey()!.Properties.Select(p => p.Name)); + + Assert.Equal( + [ + nameof(SingleGuidKey.Id), "$type", nameof(SingleGuidKey.Name), nameof(SingleGuidKey.P1), + nameof(SingleGuidKey.P2), nameof(SingleGuidKey.P3), "__jObject" + ], + entityType.GetProperties().Select(p => p.Name)); + + Assert.Equal(1, entityType.GetKeys().Count()); + Assert.Null(entityType.FindProperty("__id")); + Assert.Equal("id", entityType.FindProperty("Id")!.GetJsonPropertyName()); + } + + [ConditionalFact] // Issue #34554 + public virtual void Single_GUID_primary_key_with_single_partition_key_maps_to_JSON_id() + { + var modelBuilder = CreateModelBuilder(); + + modelBuilder.Entity().HasPartitionKey(e => e.P1); + + var model = modelBuilder.FinalizeModel(); + + var entityType = model.FindEntityType(typeof(SingleGuidKey))!; + + Assert.Equal( + [nameof(SingleGuidKey.Id), nameof(SingleGuidKey.P1)], + entityType.FindPrimaryKey()!.Properties.Select(p => p.Name)); + + Assert.Equal( + [ + nameof(SingleGuidKey.Id), nameof(SingleGuidKey.P1), "$type", nameof(SingleGuidKey.Name), + nameof(SingleGuidKey.P2), nameof(SingleGuidKey.P3), "__jObject" + ], + entityType.GetProperties().Select(p => p.Name)); + + Assert.Equal(1, entityType.GetKeys().Count()); + Assert.Null(entityType.FindProperty("__id")); + Assert.Equal("id", entityType.FindProperty("Id")!.GetJsonPropertyName()); + } + + [ConditionalFact] // Issue #34554 + public virtual void Single_GUID_primary_key_with_hierarchical_partition_key_maps_to_JSON_id() + { + var modelBuilder = CreateModelBuilder(); + + modelBuilder.Entity().HasPartitionKey(e => new { e.P1, e.P2, e.P3 }); + + var model = modelBuilder.FinalizeModel(); + + var entityType = model.FindEntityType(typeof(SingleGuidKey))!; + + Assert.Equal( + [nameof(SingleGuidKey.Id), nameof(SingleGuidKey.P1), nameof(SingleGuidKey.P2), nameof(SingleGuidKey.P3)], + entityType.FindPrimaryKey()!.Properties.Select(p => p.Name)); + + Assert.Equal( + [ + nameof(SingleGuidKey.Id), nameof(SingleGuidKey.P1), nameof(SingleGuidKey.P2), nameof(SingleGuidKey.P3), + "$type", nameof(SingleGuidKey.Name), "__jObject" + ], + entityType.GetProperties().Select(p => p.Name)); + + Assert.Equal(1, entityType.GetKeys().Count()); + Assert.Null(entityType.FindProperty("__id")); + Assert.Equal("id", entityType.FindProperty("Id")!.GetJsonPropertyName()); + } + + protected class SingleGuidKey + { + public Guid Id { get; set; } + public string? Name { get; set; } + public string P1 { get; set; } = null!; + public string P2 { get; set; } = null!; + public string P3 { get; set; } = null!; + } + protected override TestModelBuilder CreateModelBuilder(Action? configure = null) => new GenericTestModelBuilder(Fixture, configure); } - public class CosmosGenericComplexType(CosmosModelBuilderFixture fixture) : ComplexTypeTestBase(fixture), IClassFixture + public class CosmosGenericComplexType(CosmosModelBuilderFixture fixture) + : ComplexTypeTestBase(fixture), IClassFixture { public override void Properties_can_have_custom_type_value_converter_type_set() => Properties_can_have_custom_type_value_converter_type_set(); @@ -573,7 +768,8 @@ protected override TestModelBuilder CreateModelBuilder(Action new GenericTestModelBuilder(Fixture, configure); } - public class CosmosGenericInheritance(CosmosModelBuilderFixture fixture) : InheritanceTestBase(fixture), IClassFixture + public class CosmosGenericInheritance(CosmosModelBuilderFixture fixture) + : InheritanceTestBase(fixture), IClassFixture { public override void Base_type_can_be_discovered_after_creating_foreign_keys_on_derived() { @@ -602,7 +798,8 @@ protected override TestModelBuilder CreateModelBuilder(Action new GenericTestModelBuilder(Fixture, configure); } - public class CosmosGenericOneToMany(CosmosModelBuilderFixture fixture) : OneToManyTestBase(fixture), IClassFixture + public class CosmosGenericOneToMany(CosmosModelBuilderFixture fixture) + : OneToManyTestBase(fixture), IClassFixture { public override void Creates_overlapping_foreign_keys_with_different_nullability() => Assert.Equal( @@ -631,13 +828,15 @@ protected override TestModelBuilder CreateModelBuilder(Action new GenericTestModelBuilder(Fixture, configure); } - public class CosmosGenericManyToOne(CosmosModelBuilderFixture fixture) : ManyToOneTestBase(fixture), IClassFixture + public class CosmosGenericManyToOne(CosmosModelBuilderFixture fixture) + : ManyToOneTestBase(fixture), IClassFixture { protected override TestModelBuilder CreateModelBuilder(Action? configure = null) => new GenericTestModelBuilder(Fixture, configure); } - public class CosmosGenericOneToOne(CosmosModelBuilderFixture fixture) : OneToOneTestBase(fixture), IClassFixture + public class CosmosGenericOneToOne(CosmosModelBuilderFixture fixture) + : OneToOneTestBase(fixture), IClassFixture { public override void Navigation_to_shared_type_is_not_discovered_by_convention() { @@ -656,11 +855,53 @@ 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); } - public class CosmosGenericManyToMany(CosmosModelBuilderFixture fixture) : ManyToManyTestBase(fixture), IClassFixture + public class CosmosGenericManyToMany(CosmosModelBuilderFixture fixture) + : ManyToManyTestBase(fixture), IClassFixture { [ConditionalFact] public virtual void Can_use_shared_type_as_join_entity_with_partition_keys() @@ -705,7 +946,8 @@ public virtual void Can_use_shared_type_as_join_entity_with_partition_keys() var joinType = model.FindEntityType("JoinType")!; Assert.NotNull(joinType); - Assert.Collection(joinType.GetForeignKeys(), + Assert.Collection( + joinType.GetForeignKeys(), fk => Assert.Equal("Foo", fk["Right"]), fk => Assert.Equal("Bar", fk["Left"])); Assert.Equal(3, joinType.FindPrimaryKey()!.Properties.Count); @@ -759,14 +1001,16 @@ public virtual void Can_use_shared_type_as_join_entity_with_hierarchical_partiti .UsingEntity>( "JoinType", e => e.HasOne().WithMany().HasForeignKey("DependentId", "PartitionId1", "PartitionId2", "PartitionId3"), - e => e.HasOne().WithMany().HasForeignKey("PrincipalId", "PartitionId1", "PartitionId2", "PartitionId3"), + e => e.HasOne().WithMany().HasForeignKey( + "PrincipalId", "PartitionId1", "PartitionId2", "PartitionId3"), e => e.HasPartitionKey("PartitionId1", "PartitionId2", "PartitionId3")); var model = modelBuilder.FinalizeModel(); var joinType = model.FindEntityType("JoinType")!; Assert.NotNull(joinType); - Assert.Collection(joinType.GetForeignKeys(), + Assert.Collection( + joinType.GetForeignKeys(), fk => Assert.Equal("Foo", fk["Right"]), fk => Assert.Equal("Bar", fk["Left"])); @@ -944,7 +1188,8 @@ protected override TestModelBuilder CreateModelBuilder(Action new GenericTestModelBuilder(Fixture, configure); } - public class CosmosGenericOwnedTypes(CosmosModelBuilderFixture fixture) : OwnedTypesTestBase(fixture), IClassFixture + public class CosmosGenericOwnedTypes(CosmosModelBuilderFixture fixture) + : OwnedTypesTestBase(fixture), IClassFixture { public override void Deriving_from_owned_type_throws() // On Cosmos the base type starts as owned @@ -978,7 +1223,7 @@ public override void Can_configure_owned_type() public override void Can_configure_owned_type_collection() => Assert.Equal( - CosmosStrings.IndexesExist(nameof(Order), "foo"), + CosmosStrings.IndexesExist(nameof(Order), "CustomerId"), Assert.Throws( base.Can_configure_owned_type_collection).Message); @@ -990,7 +1235,8 @@ public override void Can_configure_owned_type_collection_using_nested_closure() public override void Can_configure_chained_ownerships() => Assert.Equal( - CosmosStrings.IndexesExist("Book.Label#BookLabel.AnotherBookLabel#AnotherBookLabel.SpecialBookLabel#SpecialBookLabel", "BookId"), + CosmosStrings.IndexesExist( + "Book.Label#BookLabel.AnotherBookLabel#AnotherBookLabel.SpecialBookLabel#SpecialBookLabel", "BookId"), Assert.Throws( base.Can_configure_chained_ownerships).Message); @@ -1005,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) @@ -1035,7 +1273,9 @@ protected override TestModelBuilder CreateModelBuilder(Action CosmosTestHelpers.Instance; + public override TestHelpers TestHelpers + => CosmosTestHelpers.Instance; + public override bool ForeignKeysHaveIndexes => false; } diff --git a/test/EFCore.Cosmos.FunctionalTests/OptimisticConcurrencyCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/OptimisticConcurrencyCosmosTest.cs index b690a982c4a..599d18467d9 100644 --- a/test/EFCore.Cosmos.FunctionalTests/OptimisticConcurrencyCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/OptimisticConcurrencyCosmosTest.cs @@ -59,39 +59,39 @@ protected override IDbContextTransaction BeginTransaction(DatabaseFacade facade) => new FakeDbContextTransaction(); public override Task Calling_Reload_on_an_Added_entity_that_is_not_in_database_is_no_op(bool async) - => CosmosTestHelpers.Instance.NoSyncTest(async, a => base.Calling_Reload_on_an_Added_entity_that_is_not_in_database_is_no_op(a)); + => CosmosTestHelpers.Instance.NoSyncTest(async, base.Calling_Reload_on_an_Added_entity_that_is_not_in_database_is_no_op); public override Task Calling_Reload_on_an_Unchanged_entity_that_is_not_in_database_detaches_it(bool async) => CosmosTestHelpers.Instance.NoSyncTest( - async, a => base.Calling_Reload_on_an_Unchanged_entity_that_is_not_in_database_detaches_it(a)); + async, base.Calling_Reload_on_an_Unchanged_entity_that_is_not_in_database_detaches_it); public override Task Calling_Reload_on_a_Modified_entity_that_is_not_in_database_detaches_it(bool async) => CosmosTestHelpers.Instance.NoSyncTest( - async, a => base.Calling_Reload_on_a_Modified_entity_that_is_not_in_database_detaches_it(a)); + async, base.Calling_Reload_on_a_Modified_entity_that_is_not_in_database_detaches_it); public override Task Calling_Reload_on_a_Deleted_entity_that_is_not_in_database_detaches_it(bool async) => CosmosTestHelpers.Instance.NoSyncTest( - async, a => base.Calling_Reload_on_a_Deleted_entity_that_is_not_in_database_detaches_it(a)); + async, base.Calling_Reload_on_a_Deleted_entity_that_is_not_in_database_detaches_it); public override Task Calling_Reload_on_a_Detached_entity_that_is_not_in_database_detaches_it(bool async) => CosmosTestHelpers.Instance.NoSyncTest( - async, a => base.Calling_Reload_on_a_Detached_entity_that_is_not_in_database_detaches_it(a)); + async, base.Calling_Reload_on_a_Detached_entity_that_is_not_in_database_detaches_it); public override Task Calling_Reload_on_an_Unchanged_entity_makes_the_entity_unchanged(bool async) - => CosmosTestHelpers.Instance.NoSyncTest(async, a => base.Calling_Reload_on_an_Unchanged_entity_makes_the_entity_unchanged(a)); + => CosmosTestHelpers.Instance.NoSyncTest(async, base.Calling_Reload_on_an_Unchanged_entity_makes_the_entity_unchanged); public override Task Calling_Reload_on_a_Modified_entity_makes_the_entity_unchanged(bool async) - => CosmosTestHelpers.Instance.NoSyncTest(async, a => base.Calling_Reload_on_a_Modified_entity_makes_the_entity_unchanged(a)); + => CosmosTestHelpers.Instance.NoSyncTest(async, base.Calling_Reload_on_a_Modified_entity_makes_the_entity_unchanged); public override Task Calling_Reload_on_a_Deleted_entity_makes_the_entity_unchanged(bool async) - => CosmosTestHelpers.Instance.NoSyncTest(async, a => base.Calling_Reload_on_a_Deleted_entity_makes_the_entity_unchanged(a)); + => CosmosTestHelpers.Instance.NoSyncTest(async, base.Calling_Reload_on_a_Deleted_entity_makes_the_entity_unchanged); public override Task Calling_Reload_on_an_Added_entity_that_was_saved_elsewhere_makes_the_entity_unchanged(bool async) => CosmosTestHelpers.Instance.NoSyncTest( - async, a => base.Calling_Reload_on_an_Added_entity_that_was_saved_elsewhere_makes_the_entity_unchanged(a)); + async, base.Calling_Reload_on_an_Added_entity_that_was_saved_elsewhere_makes_the_entity_unchanged); public override Task Calling_Reload_on_a_Detached_entity_makes_the_entity_unchanged(bool async) - => CosmosTestHelpers.Instance.NoSyncTest(async, a => base.Calling_Reload_on_a_Detached_entity_makes_the_entity_unchanged(a)); + => CosmosTestHelpers.Instance.NoSyncTest(async, base.Calling_Reload_on_a_Detached_entity_makes_the_entity_unchanged); private class FakeDbContextTransaction : IDbContextTransaction { diff --git a/test/EFCore.Cosmos.FunctionalTests/OverzealousInitializationCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/OverzealousInitializationCosmosTest.cs index f0b85ef9408..34f5af870aa 100644 --- a/test/EFCore.Cosmos.FunctionalTests/OverzealousInitializationCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/OverzealousInitializationCosmosTest.cs @@ -16,8 +16,9 @@ public override void Fixup_ignores_eagerly_initialized_reference_navs() public class OverzealousInitializationCosmosFixture : OverzealousInitializationFixtureBase { public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) - => base.AddOptions(builder.ConfigureWarnings( - w => w.Ignore(CosmosEventId.NoPartitionKeyDefined))); + => base.AddOptions( + builder.ConfigureWarnings( + w => w.Ignore(CosmosEventId.NoPartitionKeyDefined))); protected override ITestStoreFactory TestStoreFactory => CosmosTestStoreFactory.Instance; diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/FromSqlQueryCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/FromSqlQueryCosmosTest.cs index dc052ecc5a2..a6b932b8814 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/FromSqlQueryCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/FromSqlQueryCosmosTest.cs @@ -51,7 +51,8 @@ SELECT VALUE s public async Task FromSqlRaw_queryable_incorrect_discriminator_throws() { using var context = CreateContext(); - var query = context.Set().FromSqlRaw(""" + var query = context.Set().FromSqlRaw( + """ SELECT * FROM root c WHERE c["$type"] = "OrderDetail" """); @@ -125,7 +126,8 @@ public Task FromSqlRaw_queryable_composed(bool async) async, async a => { using var context = CreateContext(); - var query = context.Set().FromSqlRaw(""" + var query = context.Set().FromSqlRaw( + """ SELECT * FROM root c WHERE c["$type"] = "Customer" """) .Where(c => c.ContactName.Contains("z")); @@ -193,9 +195,10 @@ public Task FromSqlRaw_queryable_composed_compiled(bool async) { var query = EF.CompileAsyncQuery( (NorthwindContext context) => context.Set() - .FromSqlRaw(""" - SELECT * FROM root c WHERE c["$type"] = "Customer" - """) + .FromSqlRaw( + """ +SELECT * FROM root c WHERE c["$type"] = "Customer" +""") .Where(c => c.ContactName.Contains("z"))); using (var context = CreateContext()) @@ -581,9 +584,10 @@ public virtual Task FromSqlRaw_queryable_simple_as_no_tracking_not_composed(bool async, async a => { using var context = CreateContext(); - var query = context.Set().FromSqlRaw(""" - SELECT * FROM root c WHERE c["$type"] = "Customer" - """) + var query = context.Set().FromSqlRaw( + """ +SELECT * FROM root c WHERE c["$type"] = "Customer" +""") .AsNoTracking(); var actual = a @@ -641,9 +645,10 @@ public virtual Task FromSqlRaw_composed_with_nullable_predicate(bool async) async, async a => { using var context = CreateContext(); - var query = context.Set().FromSqlRaw(""" - SELECT * FROM root c WHERE c["$type"] = "Customer" - """) + var query = context.Set().FromSqlRaw( + """ +SELECT * FROM root c WHERE c["$type"] = "Customer" +""") .Where(c => c.ContactName == c.CompanyName); var actual = a @@ -688,9 +693,10 @@ public virtual Task FromSqlRaw_queryable_simple_projection_not_composed(bool asy async, async a => { using var context = CreateContext(); - var query = context.Set().FromSqlRaw(""" - SELECT * FROM root c WHERE c["$type"] = "Customer" - """) + var query = context.Set().FromSqlRaw( + """ +SELECT * FROM root c WHERE c["$type"] = "Customer" +""") .Select( c => new { c.CustomerID, c.City }) .AsNoTracking(); diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/InheritanceQueryCosmosFixture.cs b/test/EFCore.Cosmos.FunctionalTests/Query/InheritanceQueryCosmosFixture.cs index dd3ed72fb1c..54c5489ea89 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/InheritanceQueryCosmosFixture.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/InheritanceQueryCosmosFixture.cs @@ -25,8 +25,9 @@ public Task NoSyncTest(bool async, Func testCode) => CosmosTestHelpers.Instance.NoSyncTest(async, testCode); public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) - => base.AddOptions(builder.ConfigureWarnings( - w => w.Ignore(CoreEventId.MappedEntityTypeIgnoredWarning, CosmosEventId.NoPartitionKeyDefined))); + => base.AddOptions( + builder.ConfigureWarnings( + w => w.Ignore(CoreEventId.MappedEntityTypeIgnoredWarning, CosmosEventId.NoPartitionKeyDefined))); protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) { @@ -36,10 +37,10 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con modelBuilder.Entity().ToContainer("Plants"); modelBuilder.Entity().Property("Discriminator").ToJsonProperty("_type"); modelBuilder.Entity().ToContainer("Countries"); - modelBuilder.Entity().ToContainer("Drinks");; + modelBuilder.Entity().ToContainer("Drinks"); modelBuilder.Entity().ToContainer("Animals"); modelBuilder.Entity().ToContainer("Animals"); - modelBuilder.Entity().ToContainer("Animals");; - modelBuilder.Entity().ToContainer("Animals");; + modelBuilder.Entity().ToContainer("Animals"); + modelBuilder.Entity().ToContainer("Animals"); } } diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/InheritanceQueryCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/InheritanceQueryCosmosTest.cs index 1a984168fcd..0d1aa687b02 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/InheritanceQueryCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/InheritanceQueryCosmosTest.cs @@ -13,7 +13,7 @@ public InheritanceQueryCosmosTest(InheritanceQueryCosmosFixture fixture, ITestOu : base(fixture) { ClearLog(); - //TestLoggerFactory.TestOutputHelper = testOutputHelper; + Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); } [ConditionalFact] @@ -172,7 +172,7 @@ public override Task Can_use_of_type_bird(bool async) """ SELECT VALUE c FROM root c -WHERE c["Discriminator"] IN ("Eagle", "Kiwi") +WHERE (c["Discriminator"] IN ("Eagle", "Kiwi") AND c["Discriminator"] IN ("Eagle", "Kiwi")) ORDER BY c["Species"] """); }); @@ -202,7 +202,7 @@ public override Task Can_use_of_type_bird_with_projection(bool async) """ SELECT VALUE c["EagleId"] FROM root c -WHERE c["Discriminator"] IN ("Eagle", "Kiwi") +WHERE (c["Discriminator"] IN ("Eagle", "Kiwi") AND c["Discriminator"] IN ("Eagle", "Kiwi")) """); }); @@ -216,7 +216,7 @@ public override Task Can_use_of_type_bird_first(bool async) """ SELECT VALUE c FROM root c -WHERE c["Discriminator"] IN ("Eagle", "Kiwi") +WHERE (c["Discriminator"] IN ("Eagle", "Kiwi") AND c["Discriminator"] IN ("Eagle", "Kiwi")) ORDER BY c["Species"] OFFSET 0 LIMIT 1 """); @@ -589,7 +589,7 @@ public override Task GetType_in_hierarchy_in_abstract_base_type(bool async) """ SELECT VALUE c FROM root c -WHERE false +WHERE (c["Discriminator"] IN ("Eagle", "Kiwi") AND false) """); }); @@ -603,7 +603,7 @@ public override Task GetType_in_hierarchy_in_intermediate_type(bool async) """ SELECT VALUE c FROM root c -WHERE false +WHERE (c["Discriminator"] IN ("Eagle", "Kiwi") AND false) """); }); diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/JsonQueryCosmosFixture.cs b/test/EFCore.Cosmos.FunctionalTests/Query/JsonQueryCosmosFixture.cs index f965d396e43..93c954e816a 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/JsonQueryCosmosFixture.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/JsonQueryCosmosFixture.cs @@ -16,8 +16,9 @@ protected override ITestStoreFactory TestStoreFactory => CosmosTestStoreFactory.Instance; public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) - => base.AddOptions(builder.ConfigureWarnings( - w => w.Ignore(CosmosEventId.NoPartitionKeyDefined))); + => base.AddOptions( + builder.ConfigureWarnings( + w => w.Ignore(CosmosEventId.NoPartitionKeyDefined))); public Task NoSyncTest(bool async, Func testCode) => CosmosTestHelpers.Instance.NoSyncTest(async, testCode); @@ -42,12 +43,18 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con modelBuilder.Entity().OwnsOne( x => x.OwnedReferenceRoot, b => { + // Issue #29380 + b.Ignore(x => x.Id); + b.OwnsOne( x => x.OwnedReferenceBranch, bb => { //issue #34026 bb.Ignore(x => x.Enums); bb.Ignore(x => x.NullableEnums); + + // Issue #29380 + bb.Ignore(x => x.Id); }); b.OwnsMany( @@ -56,18 +63,27 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con //issue #34026 bb.Ignore(x => x.Enums); bb.Ignore(x => x.NullableEnums); + + // Issue #29380 + bb.Ignore(x => x.Id); }); }); modelBuilder.Entity().OwnsMany( x => x.OwnedCollectionRoot, b => { + // Issue #29380 + b.Ignore(x => x.Id); + b.OwnsOne( x => x.OwnedReferenceBranch, bb => { //issue #34026 bb.Ignore(x => x.Enums); bb.Ignore(x => x.NullableEnums); + + // Issue #29380 + bb.Ignore(x => x.Id); }); b.OwnsMany( @@ -76,6 +92,9 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con //issue #34026 bb.Ignore(x => x.Enums); bb.Ignore(x => x.NullableEnums); + + // Issue #29380 + bb.Ignore(x => x.Id); }); }); @@ -106,6 +125,9 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con //issue #34026 bb.Ignore(x => x.Enums); bb.Ignore(x => x.NullableEnums); + + // Issue #29380 + bb.Ignore(e => e.Id); }); b.OwnsMany( @@ -114,6 +136,9 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con //issue #34026 bb.Ignore(x => x.Enums); bb.Ignore(x => x.NullableEnums); + + // Issue #29380 + bb.Ignore(e => e.Id); }); }); @@ -126,6 +151,9 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con //issue #34026 bb.Ignore(x => x.Enums); bb.Ignore(x => x.NullableEnums); + + // Issue #29380 + bb.Ignore(e => e.Id); }); b.OwnsMany( @@ -134,6 +162,9 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con //issue #34026 bb.Ignore(x => x.Enums); bb.Ignore(x => x.NullableEnums); + + // Issue #29380 + bb.Ignore(e => e.Id); }); }); diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/JsonQueryCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/JsonQueryCosmosTest.cs index d803f3ec4b5..d9bc9fb7d8c 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/JsonQueryCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/JsonQueryCosmosTest.cs @@ -4,6 +4,7 @@ using Microsoft.Azure.Cosmos; using Microsoft.EntityFrameworkCore.Cosmos.Internal; using Microsoft.EntityFrameworkCore.TestModels.JsonQuery; +using Microsoft.EntityFrameworkCore.TestUtilities.Xunit; namespace Microsoft.EntityFrameworkCore.Query; @@ -26,14 +27,13 @@ public override Task Basic_json_projection_enum_inside_json_entity(bool async) await base.Basic_json_projection_enum_inside_json_entity(a); AssertSql( - """ + """ SELECT c["Id"], c["OwnedReferenceRoot"]["OwnedReferenceBranch"]["Enum"] FROM root c WHERE (c["Discriminator"] = "Basic") """); }); - [ConditionalTheory] public override async Task Basic_json_projection_owned_collection_branch(bool async) { // Always throws for sync. @@ -45,7 +45,6 @@ await Assert.ThrowsAsync( } } - [ConditionalTheory] public override async Task Basic_json_projection_owned_collection_branch_NoTrackingWithIdentityResolution(bool async) { // Always throws for sync. @@ -57,7 +56,6 @@ await Assert.ThrowsAsync( } } - [ConditionalTheory] public override async Task Basic_json_projection_owned_collection_leaf(bool async) { // Always throws for sync. @@ -77,7 +75,7 @@ public override Task Basic_json_projection_owned_collection_root(bool async) // TODO: issue #34067 (?) AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE (c["Discriminator"] = "Basic") @@ -92,14 +90,13 @@ public override Task Basic_json_projection_owned_collection_root_NoTrackingWithI // TODO: issue #34067 (?) AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE (c["Discriminator"] = "Basic") """); }); - [ConditionalTheory] public override Task Basic_json_projection_owned_reference_branch(bool async) => Fixture.NoSyncTest( async, async a => @@ -107,14 +104,13 @@ public override Task Basic_json_projection_owned_reference_branch(bool async) await base.Basic_json_projection_owned_reference_branch(async); AssertSql( -""" + """ SELECT VALUE c FROM root c WHERE (c["Discriminator"] = "Basic") """); }); - [ConditionalTheory] public override Task Basic_json_projection_owned_reference_branch_NoTrackingWithIdentityResolution(bool async) => Fixture.NoSyncTest( async, async a => @@ -122,14 +118,13 @@ public override Task Basic_json_projection_owned_reference_branch_NoTrackingWith await base.Basic_json_projection_owned_reference_branch_NoTrackingWithIdentityResolution(async); AssertSql( -""" + """ SELECT VALUE c FROM root c WHERE (c["Discriminator"] = "Basic") """); }); - [ConditionalTheory] public override Task Basic_json_projection_owned_reference_duplicated(bool async) => Fixture.NoSyncTest( async, async a => @@ -137,7 +132,7 @@ public override Task Basic_json_projection_owned_reference_duplicated(bool async await base.Basic_json_projection_owned_reference_duplicated(async); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE (c["Discriminator"] = "Basic") @@ -145,7 +140,6 @@ ORDER BY c["Id"] """); }); - [ConditionalTheory] public override Task Basic_json_projection_owned_reference_duplicated2(bool async) => Fixture.NoSyncTest( async, async a => @@ -153,7 +147,7 @@ public override Task Basic_json_projection_owned_reference_duplicated2(bool asyn await base.Basic_json_projection_owned_reference_duplicated2(async); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE (c["Discriminator"] = "Basic") @@ -161,7 +155,6 @@ ORDER BY c["Id"] """); }); - [ConditionalTheory] public override Task Basic_json_projection_owned_reference_duplicated2_NoTrackingWithIdentityResolution(bool async) => Fixture.NoSyncTest( async, async a => @@ -169,7 +162,7 @@ public override Task Basic_json_projection_owned_reference_duplicated2_NoTrackin await base.Basic_json_projection_owned_reference_duplicated2_NoTrackingWithIdentityResolution(async); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE (c["Discriminator"] = "Basic") @@ -177,7 +170,6 @@ ORDER BY c["Id"] """); }); - [ConditionalTheory] public override Task Basic_json_projection_owned_reference_duplicated_NoTrackingWithIdentityResolution(bool async) => Fixture.NoSyncTest( async, async a => @@ -185,7 +177,7 @@ public override Task Basic_json_projection_owned_reference_duplicated_NoTracking await base.Basic_json_projection_owned_reference_duplicated_NoTrackingWithIdentityResolution(async); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE (c["Discriminator"] = "Basic") @@ -193,7 +185,6 @@ ORDER BY c["Id"] """); }); - [ConditionalTheory] public override Task Basic_json_projection_owned_reference_leaf(bool async) => Fixture.NoSyncTest( async, async a => @@ -201,7 +192,7 @@ public override Task Basic_json_projection_owned_reference_leaf(bool async) await base.Basic_json_projection_owned_reference_leaf(async); AssertSql( -""" + """ SELECT VALUE c FROM root c WHERE (c["Discriminator"] = "Basic") @@ -216,7 +207,7 @@ public override Task Basic_json_projection_owned_reference_root(bool async) // TODO: issue #34067 (?) AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE (c["Discriminator"] = "Basic") @@ -231,7 +222,7 @@ public override Task Basic_json_projection_owned_reference_root_NoTrackingWithId // TODO: issue #34067 (?) AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE (c["Discriminator"] = "Basic") @@ -245,7 +236,7 @@ public override Task Basic_json_projection_owner_entity(bool async) await base.Basic_json_projection_owner_entity(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE (c["Discriminator"] = "Basic") @@ -259,7 +250,7 @@ public override Task Basic_json_projection_owner_entity_duplicated(bool async) await base.Basic_json_projection_owner_entity_duplicated(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE (c["Discriminator"] = "Basic") @@ -273,7 +264,7 @@ public override Task Basic_json_projection_owner_entity_duplicated_NoTracking(bo await base.Basic_json_projection_owner_entity_duplicated_NoTracking(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE (c["Discriminator"] = "SingleOwned") @@ -287,7 +278,7 @@ public override Task Basic_json_projection_owner_entity_duplicated_NoTrackingWit await base.Basic_json_projection_owner_entity_duplicated_NoTrackingWithIdentityResolution(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE (c["Discriminator"] = "SingleOwned") @@ -301,7 +292,7 @@ public override Task Basic_json_projection_owner_entity_NoTracking(bool async) await base.Basic_json_projection_owner_entity_NoTracking(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE (c["Discriminator"] = "Basic") @@ -315,7 +306,7 @@ public override Task Basic_json_projection_owner_entity_NoTrackingWithIdentityRe await base.Basic_json_projection_owner_entity_NoTrackingWithIdentityResolution(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE (c["Discriminator"] = "Basic") @@ -329,7 +320,7 @@ public override Task Basic_json_projection_owner_entity_twice(bool async) await base.Basic_json_projection_owner_entity_twice(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE (c["Discriminator"] = "Basic") @@ -343,7 +334,7 @@ public override Task Basic_json_projection_owner_entity_twice_NoTracking(bool as await base.Basic_json_projection_owner_entity_twice_NoTracking(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE (c["Discriminator"] = "Basic") @@ -357,7 +348,7 @@ public override Task Basic_json_projection_owner_entity_twice_NoTrackingWithIden await base.Basic_json_projection_owner_entity_twice_NoTrackingWithIdentityResolution(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE (c["Discriminator"] = "Basic") @@ -371,7 +362,7 @@ public override Task Basic_json_projection_scalar(bool async) await base.Basic_json_projection_scalar(a); AssertSql( - """ + """ SELECT VALUE c["OwnedReferenceRoot"]["Name"] FROM root c WHERE (c["Discriminator"] = "Basic") @@ -396,7 +387,7 @@ public override Task Custom_naming_projection_owned_collection(bool async) // TODO: issue #34067 (?) AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE (c["Discriminator"] = "CustomNaming") @@ -404,7 +395,6 @@ ORDER BY c["Id"] """); }); - [ConditionalTheory] public override Task Custom_naming_projection_owned_reference(bool async) => Fixture.NoSyncTest( async, async a => @@ -412,7 +402,7 @@ public override Task Custom_naming_projection_owned_reference(bool async) await base.Custom_naming_projection_owned_reference(async); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE (c["Discriminator"] = "CustomNaming") @@ -426,7 +416,7 @@ public override Task Custom_naming_projection_owned_scalar(bool async) await base.Custom_naming_projection_owned_scalar(a); AssertSql( - """ + """ SELECT VALUE c["OwnedReferenceRoot"]["OwnedReferenceBranch"]["Fraction"] FROM root c WHERE (c["Discriminator"] = "CustomNaming") @@ -440,7 +430,7 @@ public override Task Custom_naming_projection_owner_entity(bool async) await base.Custom_naming_projection_owner_entity(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE (c["Discriminator"] = "CustomNaming") @@ -453,7 +443,8 @@ public override async Task Entity_including_collection_with_json(bool async) () => base.Entity_including_collection_with_json(async))).Message; Assert.Equal( - CosmosStrings.NonEmbeddedIncludeNotSupported("Navigation: EntityBasic.JsonEntityBasics (List) Collection ToDependent JsonEntityBasic"), + CosmosStrings.NonEmbeddedIncludeNotSupported( + "Navigation: EntityBasic.JsonEntityBasics (List) Collection ToDependent JsonEntityBasic"), message); } @@ -485,6 +476,7 @@ public override Task Group_by_on_json_scalar_using_collection_indexer(bool async public override Task Group_by_Skip_Take_on_json_scalar(bool async) => base.Group_by_Skip_Take_on_json_scalar(async); + [SkipOnCiCondition] public override Task Json_all_types_entity_projection(bool async) => Fixture.NoSyncTest( async, async a => @@ -492,13 +484,14 @@ public override Task Json_all_types_entity_projection(bool async) await base.Json_all_types_entity_projection(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE (c["Discriminator"] = "AllTypes") """); }); + [SkipOnCiCondition] public override Task Json_all_types_projection_from_owned_entity_reference(bool async) => Fixture.NoSyncTest( async, async a => @@ -507,7 +500,7 @@ public override Task Json_all_types_projection_from_owned_entity_reference(bool // TODO: issue #34067 (?) AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE (c["Discriminator"] = "AllTypes") @@ -521,12 +514,14 @@ public override Task Json_all_types_projection_individual_properties(bool async) await base.Json_all_types_projection_individual_properties(a); AssertSql( - """ + """ SELECT c["Reference"]["TestDefaultString"], c["Reference"]["TestMaxLengthString"], c["Reference"]["TestBoolean"], c["Reference"]["TestByte"], c["Reference"]["TestCharacter"], c["Reference"]["TestDateTime"], c["Reference"]["TestDateTimeOffset"], c["Reference"]["TestDecimal"], c["Reference"]["TestDouble"], c["Reference"]["TestGuid"], c["Reference"]["TestInt16"], c["Reference"]["TestInt32"], c["Reference"]["TestInt64"], c["Reference"]["TestSignedByte"], c["Reference"]["TestSingle"], c["Reference"]["TestTimeSpan"], c["Reference"]["TestDateOnly"], c["Reference"]["TestTimeOnly"], c["Reference"]["TestUnsignedInt16"], c["Reference"]["TestUnsignedInt32"], c["Reference"]["TestUnsignedInt64"], c["Reference"]["TestEnum"], c["Reference"]["TestEnumWithIntConverter"], c["Reference"]["TestNullableEnum"], c["Reference"]["TestNullableEnumWithIntConverter"], c["Reference"]["TestNullableEnumWithConverterThatHandlesNulls"] FROM root c WHERE (c["Discriminator"] = "AllTypes") """); }); + + [SkipOnCiCondition] public override Task Json_boolean_predicate(bool async) => Fixture.NoSyncTest( async, async a => @@ -534,7 +529,7 @@ public override Task Json_boolean_predicate(bool async) await base.Json_boolean_predicate(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "AllTypes") AND c["Reference"]["TestBoolean"]) @@ -548,7 +543,7 @@ public override Task Json_boolean_predicate_negated(bool async) await base.Json_boolean_predicate_negated(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "AllTypes") AND NOT(c["Reference"]["TestBoolean"])) @@ -562,7 +557,7 @@ public override Task Json_boolean_projection(bool async) await base.Json_boolean_projection(a); AssertSql( - """ + """ SELECT VALUE c["Reference"]["TestBoolean"] FROM root c WHERE (c["Discriminator"] = "AllTypes") @@ -576,7 +571,7 @@ public override Task Json_boolean_projection_negated(bool async) await base.Json_boolean_projection_negated(a); AssertSql( - """ + """ SELECT VALUE NOT(c["Reference"]["TestBoolean"]) FROM root c WHERE (c["Discriminator"] = "AllTypes") @@ -585,7 +580,7 @@ FROM root c public override Task Json_branch_collection_distinct_and_other_collection(bool async) => AssertTranslationFailed( - () => base.Json_branch_collection_distinct_and_other_collection(async)); + () => base.Json_branch_collection_distinct_and_other_collection(async)); [ConditionalTheory(Skip = "issue #34335")] public override Task Json_collection_after_collection_index_in_projection_using_constant_when_owner_is_not_present(bool async) @@ -643,7 +638,7 @@ public override Task Json_collection_Any_with_predicate(bool async) await base.Json_collection_Any_with_predicate(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "Basic") AND EXISTS ( @@ -655,11 +650,11 @@ FROM o IN c["OwnedReferenceRoot"]["OwnedCollectionBranch"] public override Task Json_collection_Distinct_Count_with_predicate(bool async) => AssertTranslationFailed( - () => base.Json_collection_Distinct_Count_with_predicate(async)); + () => base.Json_collection_Distinct_Count_with_predicate(async)); public override Task Json_collection_distinct_in_projection(bool async) => AssertTranslationFailed( - () => base.Json_collection_distinct_in_projection(async)); + () => base.Json_collection_distinct_in_projection(async)); [ConditionalTheory(Skip = "issue #34335")] public override Task Json_collection_ElementAtOrDefault_in_projection(bool async) @@ -688,7 +683,7 @@ public override Task Json_collection_ElementAt_and_pushdown(bool async) await base.Json_collection_ElementAt_and_pushdown(a); AssertSql( - """ + """ SELECT VALUE { "Id" : c["Id"], @@ -706,7 +701,7 @@ public override Task Json_collection_ElementAt_in_predicate(bool async) await base.Json_collection_ElementAt_in_predicate(a); AssertSql( - """ + """ SELECT VALUE c["Id"] FROM root c WHERE ((c["Discriminator"] = "Basic") AND (c["OwnedCollectionRoot"][1]["Name"] != "Foo")) @@ -737,7 +732,6 @@ public override Task Json_collection_filter_in_projection(bool async) => AssertTranslationFailed( () => base.Json_collection_filter_in_projection(async)); - [ConditionalTheory] public override async Task Json_collection_index_in_predicate_nested_mix(bool async) { var message = (await Assert.ThrowsAsync( @@ -778,7 +772,7 @@ public override Task Json_collection_index_in_predicate_using_constant(bool asyn await base.Json_collection_index_in_predicate_using_constant(a); AssertSql( - """ + """ SELECT VALUE c["Id"] FROM root c WHERE ((c["Discriminator"] = "Basic") AND (c["OwnedCollectionRoot"][0]["Name"] != "Foo")) @@ -792,7 +786,7 @@ public override Task Json_collection_index_in_predicate_using_variable(bool asyn await base.Json_collection_index_in_predicate_using_variable(a); AssertSql( - """ + """ @__prm_0='1' SELECT VALUE c["Id"] @@ -811,7 +805,6 @@ public override Task Json_collection_index_in_projection_basic(bool async) AssertSql(""); }); - [ConditionalTheory] public override async Task Json_collection_index_in_projection_nested(bool async) { var message = (await Assert.ThrowsAsync( @@ -821,7 +814,6 @@ public override async Task Json_collection_index_in_projection_nested(bool async Assert.Equal(NotImplementedBindPropertyMessage, message); } - [ConditionalTheory] public override async Task Json_collection_index_in_projection_nested_project_collection(bool async) { var message = (await Assert.ThrowsAsync( @@ -831,7 +823,6 @@ public override async Task Json_collection_index_in_projection_nested_project_co Assert.Equal(NotImplementedBindPropertyMessage, message); } - [ConditionalTheory] public override async Task Json_collection_index_in_projection_nested_project_collection_anonymous_projection(bool async) { var message = (await Assert.ThrowsAsync( @@ -841,7 +832,6 @@ public override async Task Json_collection_index_in_projection_nested_project_co Assert.Equal(NotImplementedBindPropertyMessage, message); } - [ConditionalTheory] public override async Task Json_collection_index_in_projection_nested_project_reference(bool async) { var message = (await Assert.ThrowsAsync( @@ -851,7 +841,6 @@ public override async Task Json_collection_index_in_projection_nested_project_re Assert.Equal(NotImplementedBindPropertyMessage, message); } - [ConditionalTheory] public override async Task Json_collection_index_in_projection_nested_project_scalar(bool async) { var message = (await Assert.ThrowsAsync( @@ -959,7 +948,6 @@ public override Task Json_collection_index_in_projection_when_owner_is_not_prese AssertSql(""); }); - [ConditionalTheory] public override async Task Json_collection_index_in_projection_when_owner_is_not_present_multiple(bool async) { var message = (await Assert.ThrowsAsync( @@ -969,7 +957,6 @@ public override async Task Json_collection_index_in_projection_when_owner_is_not Assert.Equal(NotImplementedBindPropertyMessage, message); } - [ConditionalTheory] public override async Task Json_collection_index_in_projection_when_owner_is_present_misc1(bool async) { var message = (await Assert.ThrowsAsync( @@ -989,7 +976,6 @@ public override Task Json_collection_index_in_projection_when_owner_is_present_m AssertSql(""); }); - [ConditionalTheory] public override async Task Json_collection_index_in_projection_when_owner_is_present_multiple(bool async) { var message = (await Assert.ThrowsAsync( @@ -1020,11 +1006,9 @@ public override Task Json_collection_index_outside_bounds2(bool async) }); // returns "wrong" results by design - see #34351 for more context - [ConditionalTheory] public override Task Json_collection_index_outside_bounds_with_property_access(bool async) => Task.CompletedTask; - [ConditionalTheory] public override async Task Json_collection_index_with_expression_Select_ElementAt(bool async) { var message = (await Assert.ThrowsAsync( @@ -1034,7 +1018,6 @@ public override async Task Json_collection_index_with_expression_Select_ElementA Assert.Equal(NotImplementedBindPropertyMessage, message); } - [ConditionalTheory] public override async Task Json_collection_index_with_parameter_Select_ElementAt(bool async) { var message = (await Assert.ThrowsAsync( @@ -1055,7 +1038,7 @@ public override Task Json_collection_in_projection_with_composition_count(bool a await base.Json_collection_in_projection_with_composition_count(a); AssertSql( - """ + """ SELECT VALUE ARRAY_LENGTH(c["OwnedCollectionRoot"]) FROM root c WHERE (c["Discriminator"] = "Basic") @@ -1078,7 +1061,7 @@ public override Task Json_collection_leaf_filter_in_projection(bool async) await base.Json_collection_leaf_filter_in_projection(a); AssertSql( - """ + """ SELECT VALUE ARRAY( SELECT VALUE o FROM o IN c["OwnedReferenceRoot"]["OwnedReferenceBranch"]["OwnedCollectionLeaf"] @@ -1089,7 +1072,6 @@ ORDER BY c["Id"] """); }); - public override Task Json_collection_of_primitives_contains_in_predicate(bool async) => Fixture.NoSyncTest( async, async a => @@ -1097,7 +1079,7 @@ public override Task Json_collection_of_primitives_contains_in_predicate(bool as await base.Json_collection_of_primitives_contains_in_predicate(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "Basic") AND ARRAY_CONTAINS(c["OwnedReferenceRoot"]["Names"], "e1_r1")) @@ -1111,7 +1093,7 @@ public override Task Json_collection_of_primitives_index_used_in_orderby(bool as await base.Json_collection_of_primitives_index_used_in_orderby(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE (c["Discriminator"] = "Basic") @@ -1126,7 +1108,7 @@ public override Task Json_collection_of_primitives_index_used_in_predicate(bool await base.Json_collection_of_primitives_index_used_in_predicate(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "Basic") AND (c["OwnedReferenceRoot"]["Names"][0] = "e1_r1")) @@ -1141,7 +1123,7 @@ public override Task Json_collection_of_primitives_index_used_in_projection(bool await base.Json_collection_of_primitives_index_used_in_projection(a); AssertSql( - """ + """ SELECT VALUE c["OwnedReferenceRoot"]["OwnedReferenceBranch"]["Enums"][0] FROM root c WHERE (c["Discriminator"] = "JsonEntityBasic") @@ -1156,7 +1138,7 @@ public override Task Json_collection_of_primitives_SelectMany(bool async) await base.Json_collection_of_primitives_SelectMany(a); AssertSql( - """ + """ SELECT VALUE n FROM root c JOIN n IN c["OwnedReferenceRoot"]["Names"] @@ -1166,10 +1148,8 @@ JOIN n IN c["OwnedReferenceRoot"]["Names"] public override Task Json_collection_OrderByDescending_Skip_ElementAt(bool async) => AssertTranslationFailedWithDetails( - () => base.Json_collection_OrderByDescending_Skip_ElementAt(async), - CosmosStrings.LimitOffsetNotSupportedInSubqueries + - Environment.NewLine + - CosmosStrings.LimitOffsetNotSupportedInSubqueries); + () => base.Json_collection_OrderByDescending_Skip_ElementAt(async), + CosmosStrings.LimitOffsetNotSupportedInSubqueries + Environment.NewLine + CosmosStrings.LimitOffsetNotSupportedInSubqueries); [ConditionalTheory(Skip = "issue #34349")] public override Task Json_collection_SelectMany(bool async) @@ -1182,22 +1162,23 @@ public override Task Json_collection_SelectMany(bool async) }); [ConditionalTheory(Skip = "issue #34335")] - public override Task Json_collection_Select_entity_collection_ElementAt(bool async) => base.Json_collection_Select_entity_collection_ElementAt(async); + public override Task Json_collection_Select_entity_collection_ElementAt(bool async) + => base.Json_collection_Select_entity_collection_ElementAt(async); public override Task Json_collection_Select_entity_ElementAt(bool async) => AssertTranslationFailedWithDetails( - () => base.Json_collection_Select_entity_ElementAt(async), - CosmosStrings.LimitOffsetNotSupportedInSubqueries); + () => base.Json_collection_Select_entity_ElementAt(async), + CosmosStrings.LimitOffsetNotSupportedInSubqueries); public override Task Json_collection_Select_entity_in_anonymous_object_ElementAt(bool async) => AssertTranslationFailedWithDetails( - () => base.Json_collection_Select_entity_in_anonymous_object_ElementAt(async), - CosmosStrings.LimitOffsetNotSupportedInSubqueries); + () => base.Json_collection_Select_entity_in_anonymous_object_ElementAt(async), + CosmosStrings.LimitOffsetNotSupportedInSubqueries); public override Task Json_collection_Select_entity_with_initializer_ElementAt(bool async) => AssertTranslationFailedWithDetails( - () => base.Json_collection_Select_entity_with_initializer_ElementAt(async), - CosmosStrings.LimitOffsetNotSupportedInSubqueries); + () => base.Json_collection_Select_entity_with_initializer_ElementAt(async), + CosmosStrings.LimitOffsetNotSupportedInSubqueries); public override Task Json_collection_Skip(bool async) => Fixture.NoSyncTest( @@ -1206,7 +1187,7 @@ public override Task Json_collection_Skip(bool async) await base.Json_collection_Skip(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "Basic") AND (ARRAY( @@ -1217,18 +1198,18 @@ FROM o IN (SELECT VALUE ARRAY_SLICE(c["OwnedReferenceRoot"]["OwnedCollectionBran public override Task Json_collection_skip_take_in_projection(bool async) => AssertTranslationFailedWithDetails( - () => base.Json_collection_skip_take_in_projection(async), - CosmosStrings.LimitOffsetNotSupportedInSubqueries); + () => base.Json_collection_skip_take_in_projection(async), + CosmosStrings.LimitOffsetNotSupportedInSubqueries); public override Task Json_collection_skip_take_in_projection_project_into_anonymous_type(bool async) => AssertTranslationFailedWithDetails( - () => base.Json_collection_skip_take_in_projection_project_into_anonymous_type(async), - CosmosStrings.LimitOffsetNotSupportedInSubqueries); + () => base.Json_collection_skip_take_in_projection_project_into_anonymous_type(async), + CosmosStrings.LimitOffsetNotSupportedInSubqueries); public override Task Json_collection_skip_take_in_projection_with_json_reference_access_as_final_operation(bool async) => AssertTranslationFailedWithDetails( - () => base.Json_collection_skip_take_in_projection_with_json_reference_access_as_final_operation(async), - CosmosStrings.LimitOffsetNotSupportedInSubqueries); + () => base.Json_collection_skip_take_in_projection_with_json_reference_access_as_final_operation(async), + CosmosStrings.LimitOffsetNotSupportedInSubqueries); public override Task Json_collection_Where_ElementAt(bool async) => Fixture.NoSyncTest( @@ -1238,7 +1219,7 @@ public override Task Json_collection_Where_ElementAt(bool async) await base.Json_collection_Where_ElementAt(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "Basic") AND (ARRAY( @@ -1255,7 +1236,7 @@ public override Task Json_collection_within_collection_Count(bool async) await base.Json_collection_within_collection_Count(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "Basic") AND EXISTS ( @@ -1281,7 +1262,7 @@ public override Task Json_entity_with_inheritance_basic_projection(bool async) await base.Json_entity_with_inheritance_basic_projection(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE c["$type"] IN ("JsonEntityInheritanceBase", "JsonEntityInheritanceDerived") @@ -1295,7 +1276,7 @@ public override Task Json_entity_with_inheritance_project_derived(bool async) await base.Json_entity_with_inheritance_project_derived(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE (c["$type"] IN ("JsonEntityInheritanceBase", "JsonEntityInheritanceDerived") AND (c["$type"] = "JsonEntityInheritanceDerived")) @@ -1324,23 +1305,24 @@ public override Task Json_entity_with_inheritance_project_navigations_on_derived public override Task Json_leaf_collection_distinct_and_other_collection(bool async) => AssertTranslationFailed( - () => base.Json_leaf_collection_distinct_and_other_collection(async)); + () => base.Json_leaf_collection_distinct_and_other_collection(async)); public override Task Json_multiple_collection_projections(bool async) => AssertTranslationFailed( - () => base.Json_multiple_collection_projections(async)); + () => base.Json_multiple_collection_projections(async)); public override Task Json_nested_collection_anonymous_projection_in_projection(bool async) => AssertTranslationFailed( - () => base.Json_nested_collection_anonymous_projection_in_projection(async)); + () => base.Json_nested_collection_anonymous_projection_in_projection(async)); - public override Task Json_nested_collection_anonymous_projection_of_primitives_in_projection_NoTrackingWithIdentityResolution(bool async) + public override Task Json_nested_collection_anonymous_projection_of_primitives_in_projection_NoTrackingWithIdentityResolution( + bool async) => AssertTranslationFailed( - () => base.Json_nested_collection_anonymous_projection_of_primitives_in_projection_NoTrackingWithIdentityResolution(async)); + () => base.Json_nested_collection_anonymous_projection_of_primitives_in_projection_NoTrackingWithIdentityResolution(async)); public override Task Json_nested_collection_filter_in_projection(bool async) => AssertTranslationFailed( - () => base.Json_nested_collection_filter_in_projection(async)); + () => base.Json_nested_collection_filter_in_projection(async)); [ConditionalTheory(Skip = "issue #34349")] public override Task Json_nested_collection_SelectMany(bool async) @@ -1359,7 +1341,7 @@ public override Task Json_predicate_on_bool_converted_to_int_zero_one(bool async await base.Json_predicate_on_bool_converted_to_int_zero_one(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "Converters") AND (c["Reference"]["BoolConvertedToIntZeroOne"] = 1)) @@ -1373,7 +1355,7 @@ public override Task Json_predicate_on_bool_converted_to_int_zero_one_with_expli await base.Json_predicate_on_bool_converted_to_int_zero_one_with_explicit_comparison(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "Converters") AND (c["Reference"]["BoolConvertedToIntZeroOne"] = 0)) @@ -1387,7 +1369,7 @@ public override Task Json_predicate_on_bool_converted_to_string_True_False(bool await base.Json_predicate_on_bool_converted_to_string_True_False(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "Converters") AND (c["Reference"]["BoolConvertedToStringTrueFalse"] = "True")) @@ -1401,7 +1383,7 @@ public override Task Json_predicate_on_bool_converted_to_string_True_False_with_ await base.Json_predicate_on_bool_converted_to_string_True_False_with_explicit_comparison(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "Converters") AND (c["Reference"]["BoolConvertedToStringTrueFalse"] = "True")) @@ -1415,7 +1397,7 @@ public override Task Json_predicate_on_bool_converted_to_string_Y_N(bool async) await base.Json_predicate_on_bool_converted_to_string_Y_N(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "Converters") AND (c["Reference"]["BoolConvertedToStringYN"] = "Y")) @@ -1429,13 +1411,14 @@ public override Task Json_predicate_on_bool_converted_to_string_Y_N_with_explici await base.Json_predicate_on_bool_converted_to_string_Y_N_with_explicit_comparison(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "Converters") AND (c["Reference"]["BoolConvertedToStringYN"] = "N")) """); }); + [SkipOnCiCondition] public override Task Json_predicate_on_byte(bool async) => Fixture.NoSyncTest( async, async a => @@ -1443,13 +1426,14 @@ public override Task Json_predicate_on_byte(bool async) await base.Json_predicate_on_byte(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "AllTypes") AND (c["Reference"]["TestByte"] != 3)) """); }); + [SkipOnCiCondition] public override Task Json_predicate_on_byte_array(bool async) => Fixture.NoSyncTest( async, async a => @@ -1457,13 +1441,14 @@ public override Task Json_predicate_on_byte_array(bool async) await base.Json_predicate_on_byte_array(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "AllTypes") AND (c["Reference"]["TestByteArray"] != "AQID")) """); }); + [SkipOnCiCondition] public override Task Json_predicate_on_character(bool async) => Fixture.NoSyncTest( async, async a => @@ -1471,13 +1456,14 @@ public override Task Json_predicate_on_character(bool async) await base.Json_predicate_on_character(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "AllTypes") AND (c["Reference"]["TestCharacter"] != "z")) """); }); + [SkipOnCiCondition] public override Task Json_predicate_on_dateonly(bool async) => Fixture.NoSyncTest( async, async a => @@ -1485,13 +1471,14 @@ public override Task Json_predicate_on_dateonly(bool async) await base.Json_predicate_on_dateonly(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "AllTypes") AND (c["Reference"]["TestDateOnly"] != "0003-02-01")) """); }); + [SkipOnCiCondition] public override Task Json_predicate_on_datetime(bool async) => Fixture.NoSyncTest( async, async a => @@ -1499,13 +1486,14 @@ public override Task Json_predicate_on_datetime(bool async) await base.Json_predicate_on_datetime(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "AllTypes") AND (c["Reference"]["TestDateTime"] != "2000-01-03T00:00:00")) """); }); + [SkipOnCiCondition] public override Task Json_predicate_on_datetimeoffset(bool async) => Fixture.NoSyncTest( async, async a => @@ -1513,13 +1501,14 @@ public override Task Json_predicate_on_datetimeoffset(bool async) await base.Json_predicate_on_datetimeoffset(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "AllTypes") AND (c["Reference"]["TestDateTimeOffset"] != "2000-01-04T00:00:00+03:02")) """); }); + [SkipOnCiCondition] public override Task Json_predicate_on_decimal(bool async) => Fixture.NoSyncTest( async, async a => @@ -1527,13 +1516,14 @@ public override Task Json_predicate_on_decimal(bool async) await base.Json_predicate_on_decimal(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "AllTypes") AND (c["Reference"]["TestDecimal"] != 1.35)) """); }); + [SkipOnCiCondition] public override Task Json_predicate_on_default_string(bool async) => Fixture.NoSyncTest( async, async a => @@ -1541,13 +1531,14 @@ public override Task Json_predicate_on_default_string(bool async) await base.Json_predicate_on_default_string(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "AllTypes") AND (c["Reference"]["TestDefaultString"] != "MyDefaultStringInReference1")) """); }); + [SkipOnCiCondition] public override Task Json_predicate_on_double(bool async) => Fixture.NoSyncTest( async, async a => @@ -1555,13 +1546,14 @@ public override Task Json_predicate_on_double(bool async) await base.Json_predicate_on_double(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "AllTypes") AND (c["Reference"]["TestDouble"] != 33.25)) """); }); + [SkipOnCiCondition] public override Task Json_predicate_on_enum(bool async) => Fixture.NoSyncTest( async, async a => @@ -1569,13 +1561,14 @@ public override Task Json_predicate_on_enum(bool async) await base.Json_predicate_on_enum(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "AllTypes") AND (c["Reference"]["TestEnum"] != 2)) """); }); + [SkipOnCiCondition] public override Task Json_predicate_on_enumwithintconverter(bool async) => Fixture.NoSyncTest( async, async a => @@ -1583,13 +1576,14 @@ public override Task Json_predicate_on_enumwithintconverter(bool async) await base.Json_predicate_on_enumwithintconverter(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "AllTypes") AND (c["Reference"]["TestEnumWithIntConverter"] != -3)) """); }); + [SkipOnCiCondition] public override Task Json_predicate_on_guid(bool async) => Fixture.NoSyncTest( async, async a => @@ -1597,13 +1591,14 @@ public override Task Json_predicate_on_guid(bool async) await base.Json_predicate_on_guid(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "AllTypes") AND (c["Reference"]["TestGuid"] != "00000000-0000-0000-0000-000000000000")) """); }); + [SkipOnCiCondition] public override Task Json_predicate_on_int16(bool async) => Fixture.NoSyncTest( async, async a => @@ -1611,13 +1606,14 @@ public override Task Json_predicate_on_int16(bool async) await base.Json_predicate_on_int16(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "AllTypes") AND (c["Reference"]["TestInt16"] != 3)) """); }); + [SkipOnCiCondition] public override Task Json_predicate_on_int32(bool async) => Fixture.NoSyncTest( async, async a => @@ -1625,13 +1621,14 @@ public override Task Json_predicate_on_int32(bool async) await base.Json_predicate_on_int32(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "AllTypes") AND (c["Reference"]["TestInt32"] != 33)) """); }); + [SkipOnCiCondition] public override Task Json_predicate_on_int64(bool async) => Fixture.NoSyncTest( async, async a => @@ -1639,7 +1636,7 @@ public override Task Json_predicate_on_int64(bool async) await base.Json_predicate_on_int64(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "AllTypes") AND (c["Reference"]["TestInt64"] != 333)) @@ -1653,13 +1650,14 @@ public override Task Json_predicate_on_int_zero_one_converted_to_bool(bool async await base.Json_predicate_on_int_zero_one_converted_to_bool(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "Converters") AND (c["Reference"]["IntZeroOneConvertedToBool"] = true)) """); }); + [SkipOnCiCondition] public override Task Json_predicate_on_max_length_string(bool async) => Fixture.NoSyncTest( async, async a => @@ -1667,13 +1665,14 @@ public override Task Json_predicate_on_max_length_string(bool async) await base.Json_predicate_on_max_length_string(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "AllTypes") AND (c["Reference"]["TestMaxLengthString"] != "Foo")) """); }); + [SkipOnCiCondition] public override Task Json_predicate_on_nullableenum1(bool async) => Fixture.NoSyncTest( async, async a => @@ -1681,13 +1680,14 @@ public override Task Json_predicate_on_nullableenum1(bool async) await base.Json_predicate_on_nullableenum1(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "AllTypes") AND (c["Reference"]["TestNullableEnum"] != -1)) """); }); + [SkipOnCiCondition] public override Task Json_predicate_on_nullableenum2(bool async) => Fixture.NoSyncTest( async, async a => @@ -1695,13 +1695,14 @@ public override Task Json_predicate_on_nullableenum2(bool async) await base.Json_predicate_on_nullableenum2(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "AllTypes") AND (c["Reference"]["TestNullableEnum"] != null)) """); }); + [SkipOnCiCondition] public override Task Json_predicate_on_nullableenumwithconverter1(bool async) => Fixture.NoSyncTest( async, async a => @@ -1709,13 +1710,14 @@ public override Task Json_predicate_on_nullableenumwithconverter1(bool async) await base.Json_predicate_on_nullableenumwithconverter1(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "AllTypes") AND (c["Reference"]["TestNullableEnumWithIntConverter"] != 2)) """); }); + [SkipOnCiCondition] public override Task Json_predicate_on_nullableenumwithconverter2(bool async) => Fixture.NoSyncTest( async, async a => @@ -1723,13 +1725,14 @@ public override Task Json_predicate_on_nullableenumwithconverter2(bool async) await base.Json_predicate_on_nullableenumwithconverter2(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "AllTypes") AND (c["Reference"]["TestNullableEnumWithIntConverter"] != null)) """); }); + [SkipOnCiCondition] public override Task Json_predicate_on_nullableenumwithconverterthathandlesnulls1(bool async) => Fixture.NoSyncTest( async, async a => @@ -1737,7 +1740,7 @@ public override Task Json_predicate_on_nullableenumwithconverterthathandlesnulls await base.Json_predicate_on_nullableenumwithconverterthathandlesnulls1(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "AllTypes") AND (c["Reference"]["TestNullableEnumWithConverterThatHandlesNulls"] != "One")) @@ -1753,6 +1756,7 @@ public override Task Json_predicate_on_nullableenumwithconverterthathandlesnulls AssertSql(""); }); + [SkipOnCiCondition] public override Task Json_predicate_on_nullableint321(bool async) => Fixture.NoSyncTest( async, async a => @@ -1760,13 +1764,14 @@ public override Task Json_predicate_on_nullableint321(bool async) await base.Json_predicate_on_nullableint321(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "AllTypes") AND (c["Reference"]["TestNullableInt32"] != 100)) """); }); + [SkipOnCiCondition] public override Task Json_predicate_on_nullableint322(bool async) => Fixture.NoSyncTest( async, async a => @@ -1774,13 +1779,14 @@ public override Task Json_predicate_on_nullableint322(bool async) await base.Json_predicate_on_nullableint322(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "AllTypes") AND (c["Reference"]["TestNullableInt32"] != null)) """); }); + [SkipOnCiCondition] public override Task Json_predicate_on_signedbyte(bool async) => Fixture.NoSyncTest( async, async a => @@ -1788,13 +1794,14 @@ public override Task Json_predicate_on_signedbyte(bool async) await base.Json_predicate_on_signedbyte(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "AllTypes") AND (c["Reference"]["TestSignedByte"] != 100)) """); }); + [SkipOnCiCondition] public override Task Json_predicate_on_single(bool async) => Fixture.NoSyncTest( async, async a => @@ -1802,13 +1809,14 @@ public override Task Json_predicate_on_single(bool async) await base.Json_predicate_on_single(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "AllTypes") AND (c["Reference"]["TestSingle"] != 10.4)) """); }); + [SkipOnCiCondition] public override Task Json_predicate_on_string_condition(bool async) => Fixture.NoSyncTest( async, async a => @@ -1816,7 +1824,7 @@ public override Task Json_predicate_on_string_condition(bool async) await base.Json_predicate_on_string_condition(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "AllTypes") AND ((NOT(c["Reference"]["TestBoolean"]) ? c["Reference"]["TestMaxLengthString"] : c["Reference"]["TestDefaultString"]) = "MyDefaultStringInReference1")) @@ -1830,7 +1838,7 @@ public override Task Json_predicate_on_string_True_False_converted_to_bool(bool await base.Json_predicate_on_string_True_False_converted_to_bool(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "Converters") AND (c["Reference"]["StringTrueFalseConvertedToBool"] = false)) @@ -1844,13 +1852,14 @@ public override Task Json_predicate_on_string_Y_N_converted_to_bool(bool async) await base.Json_predicate_on_string_Y_N_converted_to_bool(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "Converters") AND (c["Reference"]["StringYNConvertedToBool"] = false)) """); }); + [SkipOnCiCondition] public override Task Json_predicate_on_timeonly(bool async) => Fixture.NoSyncTest( async, async a => @@ -1858,13 +1867,14 @@ public override Task Json_predicate_on_timeonly(bool async) await base.Json_predicate_on_timeonly(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "AllTypes") AND (c["Reference"]["TestTimeOnly"] != "03:02:00")) """); }); + [SkipOnCiCondition] public override Task Json_predicate_on_timespan(bool async) => Fixture.NoSyncTest( async, async a => @@ -1872,13 +1882,14 @@ public override Task Json_predicate_on_timespan(bool async) await base.Json_predicate_on_timespan(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "AllTypes") AND (c["Reference"]["TestTimeSpan"] != "03:02:00")) """); }); + [SkipOnCiCondition] public override Task Json_predicate_on_unisgnedint16(bool async) => Fixture.NoSyncTest( async, async a => @@ -1886,13 +1897,14 @@ public override Task Json_predicate_on_unisgnedint16(bool async) await base.Json_predicate_on_unisgnedint16(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "AllTypes") AND (c["Reference"]["TestUnsignedInt16"] != 100)) """); }); + [SkipOnCiCondition] public override Task Json_predicate_on_unsignedint32(bool async) => Fixture.NoSyncTest( async, async a => @@ -1900,13 +1912,14 @@ public override Task Json_predicate_on_unsignedint32(bool async) await base.Json_predicate_on_unsignedint32(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "AllTypes") AND (c["Reference"]["TestUnsignedInt32"] != 1000)) """); }); + [SkipOnCiCondition] public override Task Json_predicate_on_unsignedint64(bool async) => Fixture.NoSyncTest( async, async a => @@ -1914,7 +1927,7 @@ public override Task Json_predicate_on_unsignedint64(bool async) await base.Json_predicate_on_unsignedint64(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE ((c["Discriminator"] = "AllTypes") AND (c["Reference"]["TestUnsignedInt64"] != 10000)) @@ -1923,20 +1936,19 @@ FROM root c public override Task Json_projection_collection_element_and_reference_AsNoTrackingWithIdentityResolution(bool async) => AssertTranslationFailedWithDetails( - () => base.Json_projection_collection_element_and_reference_AsNoTrackingWithIdentityResolution(async), - CosmosStrings.LimitOffsetNotSupportedInSubqueries); + () => base.Json_projection_collection_element_and_reference_AsNoTrackingWithIdentityResolution(async), + CosmosStrings.LimitOffsetNotSupportedInSubqueries); public override Task Json_projection_deduplication_with_collection_indexer_in_original(bool async) => AssertTranslationFailedWithDetails( - () => base.Json_projection_deduplication_with_collection_indexer_in_original(async), - CosmosStrings.LimitOffsetNotSupportedInSubqueries); + () => base.Json_projection_deduplication_with_collection_indexer_in_original(async), + CosmosStrings.LimitOffsetNotSupportedInSubqueries); public override Task Json_projection_deduplication_with_collection_indexer_in_target(bool async) => AssertTranslationFailedWithDetails( - () => base.Json_projection_deduplication_with_collection_indexer_in_target(async), - CosmosStrings.LimitOffsetNotSupportedInSubqueries); + () => base.Json_projection_deduplication_with_collection_indexer_in_target(async), + CosmosStrings.LimitOffsetNotSupportedInSubqueries); - [ConditionalTheory] public override async Task Json_projection_deduplication_with_collection_in_original_and_collection_indexer_in_target(bool async) { var message = (await Assert.ThrowsAsync( @@ -1953,7 +1965,7 @@ public override Task Json_projection_enum_with_custom_conversion(bool async) await base.Json_projection_enum_with_custom_conversion(a); AssertSql( - """ + """ SELECT c["Id"], c["OwnedReferenceRoot"]["Enum"] FROM root c WHERE (c["Discriminator"] = "CustomNaming") @@ -1962,14 +1974,17 @@ FROM root c public override Task Json_projection_nested_collection_and_element_correct_order_AsNoTrackingWithIdentityResolution(bool async) => AssertTranslationFailedWithDetails( - () => base.Json_projection_nested_collection_and_element_correct_order_AsNoTrackingWithIdentityResolution(async), - CosmosStrings.LimitOffsetNotSupportedInSubqueries); + () => base.Json_projection_nested_collection_and_element_correct_order_AsNoTrackingWithIdentityResolution(async), + CosmosStrings.LimitOffsetNotSupportedInSubqueries); - [ConditionalTheory] - public override async Task Json_projection_nested_collection_element_using_parameter_and_the_owner_in_correct_order_AsNoTrackingWithIdentityResolution(bool async) + public override async Task + Json_projection_nested_collection_element_using_parameter_and_the_owner_in_correct_order_AsNoTrackingWithIdentityResolution( + bool async) { var message = (await Assert.ThrowsAsync( - () => base.Json_projection_nested_collection_element_using_parameter_and_the_owner_in_correct_order_AsNoTrackingWithIdentityResolution(async))).Message; + () => base + .Json_projection_nested_collection_element_using_parameter_and_the_owner_in_correct_order_AsNoTrackingWithIdentityResolution( + async))).Message; // issue #34348 Assert.Equal(NotImplementedBindPropertyMessage, message); @@ -1982,28 +1997,34 @@ public override Task Json_projection_nothing_interesting_AsNoTrackingWithIdentit await base.Json_projection_nothing_interesting_AsNoTrackingWithIdentityResolution(a); AssertSql( - """ + """ SELECT c["Id"], c["Name"] FROM root c WHERE (c["Discriminator"] = "Basic") """); }); - [ConditionalTheory] - public override async Task Json_projection_only_second_element_through_collection_element_constant_projected_nested_AsNoTrackingWithIdentityResolution(bool async) + public override async Task + Json_projection_only_second_element_through_collection_element_constant_projected_nested_AsNoTrackingWithIdentityResolution( + bool async) { var message = (await Assert.ThrowsAsync( - () => base.Json_projection_only_second_element_through_collection_element_constant_projected_nested_AsNoTrackingWithIdentityResolution(async))).Message; + () => base + .Json_projection_only_second_element_through_collection_element_constant_projected_nested_AsNoTrackingWithIdentityResolution( + async))).Message; // issue #34348 Assert.Equal(NotImplementedBindPropertyMessage, message); } - [ConditionalTheory] - public override async Task Json_projection_only_second_element_through_collection_element_parameter_projected_nested_AsNoTrackingWithIdentityResolution(bool async) + public override async Task + Json_projection_only_second_element_through_collection_element_parameter_projected_nested_AsNoTrackingWithIdentityResolution( + bool async) { var message = (await Assert.ThrowsAsync( - () => base.Json_projection_only_second_element_through_collection_element_parameter_projected_nested_AsNoTrackingWithIdentityResolution(async))).Message; + () => base + .Json_projection_only_second_element_through_collection_element_parameter_projected_nested_AsNoTrackingWithIdentityResolution( + async))).Message; // issue #34348 Assert.Equal(NotImplementedBindPropertyMessage, message); @@ -2016,7 +2037,7 @@ public override Task Json_projection_owner_entity_AsNoTrackingWithIdentityResolu await base.Json_projection_owner_entity_AsNoTrackingWithIdentityResolution(a); AssertSql( - """ + """ SELECT c["Id"], c FROM root c WHERE (c["Discriminator"] = "Basic") @@ -2025,43 +2046,57 @@ FROM root c public override Task Json_projection_reference_collection_and_collection_element_nested_AsNoTrackingWithIdentityResolution(bool async) => AssertTranslationFailedWithDetails( - () => base.Json_projection_reference_collection_and_collection_element_nested_AsNoTrackingWithIdentityResolution(async), - CosmosStrings.LimitOffsetNotSupportedInSubqueries); + () => base.Json_projection_reference_collection_and_collection_element_nested_AsNoTrackingWithIdentityResolution(async), + CosmosStrings.LimitOffsetNotSupportedInSubqueries); - public override Task Json_projection_second_element_projected_before_owner_as_well_as_root_AsNoTrackingWithIdentityResolution(bool async) + public override Task Json_projection_second_element_projected_before_owner_as_well_as_root_AsNoTrackingWithIdentityResolution( + bool async) => AssertTranslationFailedWithDetails( - () => base.Json_projection_second_element_projected_before_owner_as_well_as_root_AsNoTrackingWithIdentityResolution(async), - CosmosStrings.LimitOffsetNotSupportedInSubqueries); + () => base.Json_projection_second_element_projected_before_owner_as_well_as_root_AsNoTrackingWithIdentityResolution(async), + CosmosStrings.LimitOffsetNotSupportedInSubqueries); [ConditionalTheory(Skip = "issue #34350")] - public override Task Json_projection_second_element_projected_before_owner_nested_as_well_as_root_AsNoTrackingWithIdentityResolution(bool async) + public override Task Json_projection_second_element_projected_before_owner_nested_as_well_as_root_AsNoTrackingWithIdentityResolution( + bool async) => Fixture.NoSyncTest( async, async a => { - await base.Json_projection_second_element_projected_before_owner_nested_as_well_as_root_AsNoTrackingWithIdentityResolution(a); + await base.Json_projection_second_element_projected_before_owner_nested_as_well_as_root_AsNoTrackingWithIdentityResolution( + a); AssertSql(""); }); - [ConditionalTheory] - public override async Task Json_projection_second_element_through_collection_element_constant_different_values_projected_before_owner_nested_AsNoTrackingWithIdentityResolution(bool async) + public override async Task + Json_projection_second_element_through_collection_element_constant_different_values_projected_before_owner_nested_AsNoTrackingWithIdentityResolution( + bool async) { var message = (await Assert.ThrowsAsync( - () => base.Json_projection_second_element_through_collection_element_constant_different_values_projected_before_owner_nested_AsNoTrackingWithIdentityResolution(async))).Message; + () => base + .Json_projection_second_element_through_collection_element_constant_different_values_projected_before_owner_nested_AsNoTrackingWithIdentityResolution( + async))).Message; // issue #34348 Assert.Equal(NotImplementedBindPropertyMessage, message); } - public override Task Json_projection_second_element_through_collection_element_constant_projected_after_owner_nested_AsNoTrackingWithIdentityResolution(bool async) + public override Task + Json_projection_second_element_through_collection_element_constant_projected_after_owner_nested_AsNoTrackingWithIdentityResolution( + bool async) => AssertTranslationFailedWithDetails( - () => base.Json_projection_second_element_through_collection_element_constant_projected_after_owner_nested_AsNoTrackingWithIdentityResolution(async), - CosmosStrings.LimitOffsetNotSupportedInSubqueries); + () => base + .Json_projection_second_element_through_collection_element_constant_projected_after_owner_nested_AsNoTrackingWithIdentityResolution( + async), + CosmosStrings.LimitOffsetNotSupportedInSubqueries); - public override Task Json_projection_second_element_through_collection_element_parameter_correctly_projected_after_owner_nested_AsNoTrackingWithIdentityResolution(bool async) + public override Task + Json_projection_second_element_through_collection_element_parameter_correctly_projected_after_owner_nested_AsNoTrackingWithIdentityResolution( + bool async) => AssertTranslationFailedWithDetails( - () => base.Json_projection_second_element_through_collection_element_parameter_correctly_projected_after_owner_nested_AsNoTrackingWithIdentityResolution(async), - CosmosStrings.LimitOffsetNotSupportedInSubqueries); + () => base + .Json_projection_second_element_through_collection_element_parameter_correctly_projected_after_owner_nested_AsNoTrackingWithIdentityResolution( + async), + CosmosStrings.LimitOffsetNotSupportedInSubqueries); [ConditionalTheory(Skip = "issue #34350")] public override Task Json_projection_with_deduplication(bool async) @@ -2073,7 +2108,6 @@ public override Task Json_projection_with_deduplication(bool async) AssertSql(""); }); - [ConditionalTheory] public override Task Json_projection_with_deduplication_reverse_order(bool async) => Fixture.NoSyncTest( async, async a => @@ -2081,7 +2115,7 @@ public override Task Json_projection_with_deduplication_reverse_order(bool async await base.Json_projection_with_deduplication_reverse_order(async); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE (c["Discriminator"] = "Basic") @@ -2095,7 +2129,7 @@ public override Task Json_property_in_predicate(bool async) await base.Json_property_in_predicate(a); AssertSql( - """ + """ SELECT VALUE c["Id"] FROM root c WHERE ((c["Discriminator"] = "Basic") AND (c["OwnedReferenceRoot"]["OwnedReferenceBranch"]["Fraction"] < 20.5)) @@ -2109,7 +2143,7 @@ public override Task Json_scalar_length(bool async) await base.Json_scalar_length(a); AssertSql( - """ + """ SELECT VALUE c["Name"] FROM root c WHERE ((c["Discriminator"] = "Basic") AND (LENGTH(c["OwnedReferenceRoot"]["Name"]) > 2)) @@ -2123,7 +2157,7 @@ public override Task Json_scalar_optional_null_semantics(bool async) await base.Json_scalar_optional_null_semantics(a); AssertSql( - """ + """ SELECT VALUE c["Name"] FROM root c WHERE ((c["Discriminator"] = "Basic") AND (c["OwnedReferenceRoot"]["Name"] != c["OwnedReferenceRoot"]["OwnedReferenceBranch"]["OwnedReferenceLeaf"]["SomethingSomething"])) @@ -2137,7 +2171,7 @@ public override Task Json_scalar_required_null_semantics(bool async) await base.Json_scalar_required_null_semantics(a); AssertSql( - """ + """ SELECT VALUE c["Name"] FROM root c WHERE ((c["Discriminator"] = "Basic") AND (c["OwnedReferenceRoot"]["Number"] != LENGTH(c["OwnedReferenceRoot"]["Name"]))) @@ -2146,18 +2180,18 @@ FROM root c public override Task Json_subquery_property_pushdown_length(bool async) => AssertTranslationFailedWithDetails( - () => base.Json_subquery_property_pushdown_length(async), - CosmosStrings.LimitOffsetNotSupportedInSubqueries); + () => base.Json_subquery_property_pushdown_length(async), + CosmosStrings.LimitOffsetNotSupportedInSubqueries); public override Task Json_subquery_reference_pushdown_property(bool async) => AssertTranslationFailedWithDetails( - () => base.Json_subquery_reference_pushdown_property(async), - CosmosStrings.LimitOffsetNotSupportedInSubqueries); + () => base.Json_subquery_reference_pushdown_property(async), + CosmosStrings.LimitOffsetNotSupportedInSubqueries); public override Task Json_subquery_reference_pushdown_reference(bool async) => AssertTranslationFailedWithDetails( - () => base.Json_subquery_reference_pushdown_reference(async), - CosmosStrings.LimitOffsetNotSupportedInSubqueries); + () => base.Json_subquery_reference_pushdown_reference(async), + CosmosStrings.LimitOffsetNotSupportedInSubqueries); public override Task Json_subquery_reference_pushdown_reference_anonymous_projection(bool async) => base.Json_subquery_reference_pushdown_reference_anonymous_projection(async); @@ -2167,13 +2201,13 @@ public override Task Json_subquery_reference_pushdown_reference_pushdown_anonymo public override Task Json_subquery_reference_pushdown_reference_pushdown_collection(bool async) => AssertTranslationFailedWithDetails( - () => base.Json_subquery_reference_pushdown_reference_pushdown_collection(async), - CosmosStrings.LimitOffsetNotSupportedInSubqueries); + () => base.Json_subquery_reference_pushdown_reference_pushdown_collection(async), + CosmosStrings.LimitOffsetNotSupportedInSubqueries); public override Task Json_subquery_reference_pushdown_reference_pushdown_reference(bool async) => AssertTranslationFailedWithDetails( - () => base.Json_subquery_reference_pushdown_reference_pushdown_reference(async), - CosmosStrings.LimitOffsetNotSupportedInSubqueries); + () => base.Json_subquery_reference_pushdown_reference_pushdown_reference(async), + CosmosStrings.LimitOffsetNotSupportedInSubqueries); public override async Task Json_with_include_on_entity_collection(bool async) { @@ -2181,19 +2215,20 @@ public override async Task Json_with_include_on_entity_collection(bool async) () => base.Json_with_include_on_entity_collection(async))).Message; Assert.Equal( - CosmosStrings.NonEmbeddedIncludeNotSupported("Navigation: JsonEntityBasic.EntityCollection (List) Collection ToDependent JsonEntityBasicForCollection Inverse: Parent"), + CosmosStrings.NonEmbeddedIncludeNotSupported( + "Navigation: JsonEntityBasic.EntityCollection (List) Collection ToDependent JsonEntityBasicForCollection Inverse: Parent"), message); } public override Task Json_with_include_on_entity_collection_and_reference(bool async) => AssertTranslationFailedWithDetails( - () => base.Json_with_include_on_entity_collection_and_reference(async), - CosmosStrings.MultipleRootEntityTypesReferencedInQuery(nameof(JsonEntityBasicForReference), nameof(JsonEntityBasic))); + () => base.Json_with_include_on_entity_collection_and_reference(async), + CosmosStrings.MultipleRootEntityTypesReferencedInQuery(nameof(JsonEntityBasicForReference), nameof(JsonEntityBasic))); public override Task Json_with_include_on_entity_reference(bool async) => AssertTranslationFailedWithDetails( - () => base.Json_with_include_on_entity_reference(async), - CosmosStrings.MultipleRootEntityTypesReferencedInQuery(nameof(JsonEntityBasicForReference), nameof(JsonEntityBasic))); + () => base.Json_with_include_on_entity_reference(async), + CosmosStrings.MultipleRootEntityTypesReferencedInQuery(nameof(JsonEntityBasicForReference), nameof(JsonEntityBasic))); public override Task Json_with_include_on_json_entity(bool async) => Fixture.NoSyncTest( @@ -2202,7 +2237,7 @@ public override Task Json_with_include_on_json_entity(bool async) await base.Json_with_include_on_json_entity(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE (c["Discriminator"] = "Basic") @@ -2211,54 +2246,54 @@ FROM root c public override Task Json_with_projection_of_json_collection_and_entity_collection(bool async) => AssertTranslationFailed( - () => base.Json_with_projection_of_json_collection_and_entity_collection(async)); + () => base.Json_with_projection_of_json_collection_and_entity_collection(async)); public override Task Json_with_projection_of_json_collection_element_and_entity_collection(bool async) => AssertTranslationFailedWithDetails( - () => base.Json_with_projection_of_json_collection_element_and_entity_collection(async), - CosmosStrings.MultipleRootEntityTypesReferencedInQuery(nameof(JsonEntityBasicForReference), nameof(JsonEntityBasic))); + () => base.Json_with_projection_of_json_collection_element_and_entity_collection(async), + CosmosStrings.MultipleRootEntityTypesReferencedInQuery(nameof(JsonEntityBasicForReference), nameof(JsonEntityBasic))); public override Task Json_with_projection_of_json_collection_leaf_and_entity_collection(bool async) => AssertTranslationFailed( - () => base.Json_with_projection_of_json_collection_leaf_and_entity_collection(async)); + () => base.Json_with_projection_of_json_collection_leaf_and_entity_collection(async)); public override Task Json_with_projection_of_json_reference_and_entity_collection(bool async) => AssertTranslationFailed( - () => base.Json_with_projection_of_json_reference_and_entity_collection(async)); + () => base.Json_with_projection_of_json_reference_and_entity_collection(async)); public override Task Json_with_projection_of_json_reference_leaf_and_entity_collection(bool async) => AssertTranslationFailed( - () => base.Json_with_projection_of_json_reference_leaf_and_entity_collection(async)); + () => base.Json_with_projection_of_json_reference_leaf_and_entity_collection(async)); public override Task Json_with_projection_of_mix_of_json_collections_json_references_and_entity_collection(bool async) => AssertTranslationFailedWithDetails( - () => base.Json_with_projection_of_mix_of_json_collections_json_references_and_entity_collection(async), - CosmosStrings.MultipleRootEntityTypesReferencedInQuery(nameof(JsonEntityBasicForReference), nameof(JsonEntityBasic))); + () => base.Json_with_projection_of_mix_of_json_collections_json_references_and_entity_collection(async), + CosmosStrings.MultipleRootEntityTypesReferencedInQuery(nameof(JsonEntityBasicForReference), nameof(JsonEntityBasic))); - public override Task Json_with_projection_of_multiple_json_references_and_entity_collection(bool async) + public override Task Json_with_projection_of_multiple_json_references_and_entity_collection(bool async) => AssertTranslationFailedWithDetails( - () => base.Json_with_projection_of_multiple_json_references_and_entity_collection(async), - CosmosStrings.LimitOffsetNotSupportedInSubqueries); + () => base.Json_with_projection_of_multiple_json_references_and_entity_collection(async), + CosmosStrings.LimitOffsetNotSupportedInSubqueries); public override Task Left_join_json_entities(bool async) => AssertTranslationFailedWithDetails( - () => base.Left_join_json_entities(async), - CosmosStrings.MultipleRootEntityTypesReferencedInQuery(nameof(JsonEntityBasic), nameof(JsonEntitySingleOwned))); + () => base.Left_join_json_entities(async), + CosmosStrings.MultipleRootEntityTypesReferencedInQuery(nameof(JsonEntityBasic), nameof(JsonEntitySingleOwned))); public override Task Left_join_json_entities_complex_projection(bool async) => AssertTranslationFailedWithDetails( - () => base.Left_join_json_entities_complex_projection(async), - CosmosStrings.MultipleRootEntityTypesReferencedInQuery(nameof(JsonEntityBasic), nameof(JsonEntitySingleOwned))); + () => base.Left_join_json_entities_complex_projection(async), + CosmosStrings.MultipleRootEntityTypesReferencedInQuery(nameof(JsonEntityBasic), nameof(JsonEntitySingleOwned))); public override Task Left_join_json_entities_complex_projection_json_being_inner(bool async) => AssertTranslationFailedWithDetails( - () => base.Left_join_json_entities_complex_projection_json_being_inner(async), - CosmosStrings.MultipleRootEntityTypesReferencedInQuery(nameof(JsonEntitySingleOwned), nameof(JsonEntityBasic))); + () => base.Left_join_json_entities_complex_projection_json_being_inner(async), + CosmosStrings.MultipleRootEntityTypesReferencedInQuery(nameof(JsonEntitySingleOwned), nameof(JsonEntityBasic))); public override Task Left_join_json_entities_json_being_inner(bool async) => AssertTranslationFailedWithDetails( - () => base.Left_join_json_entities_json_being_inner(async), - CosmosStrings.MultipleRootEntityTypesReferencedInQuery(nameof(JsonEntitySingleOwned), nameof(JsonEntityBasic))); + () => base.Left_join_json_entities_json_being_inner(async), + CosmosStrings.MultipleRootEntityTypesReferencedInQuery(nameof(JsonEntitySingleOwned), nameof(JsonEntityBasic))); public override Task Project_entity_with_single_owned(bool async) => Fixture.NoSyncTest( @@ -2267,7 +2302,7 @@ public override Task Project_entity_with_single_owned(bool async) await base.Project_entity_with_single_owned(a); AssertSql( - """ + """ SELECT VALUE c FROM root c WHERE (c["Discriminator"] = "SingleOwned") @@ -2276,27 +2311,27 @@ FROM root c public override Task Project_json_entity_FirstOrDefault_subquery(bool async) => AssertTranslationFailed( - () => base.Project_json_entity_FirstOrDefault_subquery(async)); + () => base.Project_json_entity_FirstOrDefault_subquery(async)); public override Task Project_json_entity_FirstOrDefault_subquery_deduplication(bool async) => AssertTranslationFailed( - () => base.Project_json_entity_FirstOrDefault_subquery_deduplication(async)); + () => base.Project_json_entity_FirstOrDefault_subquery_deduplication(async)); public override Task Project_json_entity_FirstOrDefault_subquery_deduplication_and_outer_reference(bool async) => AssertTranslationFailed( - () => base.Project_json_entity_FirstOrDefault_subquery_deduplication_and_outer_reference(async)); + () => base.Project_json_entity_FirstOrDefault_subquery_deduplication_and_outer_reference(async)); public override Task Project_json_entity_FirstOrDefault_subquery_deduplication_outer_reference_and_pruning(bool async) => AssertTranslationFailed( - () => base.Project_json_entity_FirstOrDefault_subquery_deduplication_outer_reference_and_pruning(async)); + () => base.Project_json_entity_FirstOrDefault_subquery_deduplication_outer_reference_and_pruning(async)); public override Task Project_json_entity_FirstOrDefault_subquery_with_binding_on_top(bool async) => AssertTranslationFailed( - () => base.Project_json_entity_FirstOrDefault_subquery_with_binding_on_top(async)); + () => base.Project_json_entity_FirstOrDefault_subquery_with_binding_on_top(async)); public override Task Project_json_entity_FirstOrDefault_subquery_with_entity_comparison_on_top(bool async) => AssertTranslationFailed( - () => base.Project_json_entity_FirstOrDefault_subquery_with_entity_comparison_on_top(async)); + () => base.Project_json_entity_FirstOrDefault_subquery_with_entity_comparison_on_top(async)); public override async Task Project_json_reference_in_tracking_query_fails(bool async) { diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindAggregateOperatorsQueryCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindAggregateOperatorsQueryCosmosTest.cs index 7f285c08223..2d30fc87c90 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindAggregateOperatorsQueryCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindAggregateOperatorsQueryCosmosTest.cs @@ -1447,15 +1447,15 @@ public override Task Contains_with_local_array_closure(bool async) await base.Contains_with_local_array_closure(a); AssertSql( - """ + """ @__ids_0='["ABCDE","ALFKI"]' SELECT VALUE c FROM root c WHERE ARRAY_CONTAINS(@__ids_0, c["id"]) """, - // - """ + // + """ @__ids_0='["ABCDE"]' SELECT VALUE c @@ -1610,8 +1610,8 @@ SELECT VALUE c FROM root c WHERE ARRAY_CONTAINS(@__p_0, c["id"]) """, - // - """ + // + """ @__p_0='["ABCDE","ANATR"]' SELECT VALUE c @@ -1709,8 +1709,8 @@ SELECT 1 FROM p IN (SELECT VALUE @__p_0) WHERE ((p != null) AND (p = c["id"]))) """, - // - """ + // + """ @__p_0='["ABCDE","ANATR"]' SELECT VALUE c @@ -1830,8 +1830,8 @@ SELECT VALUE c FROM root c WHERE ARRAY_CONTAINS(@__ids_0, c["id"]) """, - // - """ + // + """ @__ids_0='["ABCDE"]' SELECT VALUE c @@ -1900,8 +1900,8 @@ SELECT VALUE c FROM root c WHERE ARRAY_CONTAINS(@__AsReadOnly_0, c["id"]) """, - // - """ + // + """ @__AsReadOnly_0='["ABCDE","ANATR"]' SELECT VALUE c @@ -2401,8 +2401,8 @@ SELECT VALUE c FROM root c WHERE ((c["City"] = "México D.F.") AND ARRAY_CONTAINS(@__ids_0, c["id"])) """, - // - """ + // + """ @__ids_0='["ABCDE","ALFKI","ANATR"]' SELECT VALUE c @@ -2471,8 +2471,8 @@ SELECT VALUE c FROM root c WHERE ((c["City"] = "México D.F.") AND NOT(ARRAY_CONTAINS(@__ids_0, c["id"]))) """, - // - """ + // + """ @__ids_0='["ABCDE","ALFKI","ANATR"]' SELECT VALUE c diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindDbFunctionsQueryCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindDbFunctionsQueryCosmosTest.cs index 39832d51071..9559f950d0b 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindDbFunctionsQueryCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindDbFunctionsQueryCosmosTest.cs @@ -11,9 +11,7 @@ public NorthwindDbFunctionsQueryCosmosTest( NorthwindQueryCosmosFixture fixture, ITestOutputHelper testOutputHelper) : base(fixture) - { - ClearLog(); - } + => ClearLog(); [ConditionalFact] public virtual void Check_all_tests_overridden() diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindFunctionsQueryCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindFunctionsQueryCosmosTest.cs index dc76fc9e20e..1c45d073e68 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindFunctionsQueryCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindFunctionsQueryCosmosTest.cs @@ -1647,7 +1647,7 @@ public override Task Static_equals_int_compared_to_long(bool async) """ SELECT VALUE c FROM root c -WHERE false +WHERE ((c["$type"] = "Order") AND false) """); }); diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindKeylessEntitiesQueryCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindKeylessEntitiesQueryCosmosTest.cs index 4b29b445211..e971fd661ec 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindKeylessEntitiesQueryCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindKeylessEntitiesQueryCosmosTest.cs @@ -41,8 +41,8 @@ public override Task KeylessEntity_where_simple(bool async) async, async a => { await base.KeylessEntity_where_simple(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c WHERE (c["City"] = "London") @@ -175,8 +175,8 @@ public override Task Auto_initialized_view_set(bool async) async, async a => { await base.Auto_initialized_view_set(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c """); diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindMiscellaneousQueryCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindMiscellaneousQueryCosmosTest.cs index d0dd8315fbe..3c2aa4c0970 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindMiscellaneousQueryCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindMiscellaneousQueryCosmosTest.cs @@ -672,8 +672,8 @@ public override Task Queryable_nested_simple(bool async) async, async a => { await base.Queryable_nested_simple(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c """); @@ -733,8 +733,8 @@ public override Task Take_simple_parameterized(bool async) async, async a => { await base.Take_simple_parameterized(a); -AssertSql( - """ + AssertSql( + """ @__p_0='10' SELECT VALUE c @@ -749,8 +749,8 @@ public override Task Take_simple_projection(bool async) async, async a => { await base.Take_simple_projection(a); -AssertSql( - """ + AssertSql( + """ @__p_0='10' SELECT VALUE c["City"] @@ -765,8 +765,8 @@ public override Task Take_subquery_projection(bool async) async, async a => { await base.Take_subquery_projection(a); -AssertSql( - """ + AssertSql( + """ @__p_0='2' SELECT VALUE c["City"] @@ -821,8 +821,8 @@ public override async Task Any_predicate(bool async) var exception = await Assert.ThrowsAsync(() => base.Any_predicate(async)); Assert.Equal(HttpStatusCode.BadRequest, exception.StatusCode); -AssertSql( - """ + AssertSql( + """ SELECT VALUE EXISTS ( SELECT 1 FROM root c @@ -1340,8 +1340,8 @@ public override Task OrderBy(bool async) async, async a => { await base.OrderBy(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c ORDER BY c["id"] @@ -1374,8 +1374,8 @@ public override async Task OrderBy_integer(bool async) // Cosmos client evaluation. Issue #17246. await Assert.ThrowsAsync( async () => await base.OrderBy_integer(async)); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c ORDER BY 3 @@ -1408,8 +1408,8 @@ public override Task OrderBy_anon(bool async) async, async a => { await base.OrderBy_anon(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c["id"] FROM root c ORDER BY c["id"] @@ -1421,8 +1421,8 @@ public override Task OrderBy_anon2(bool async) async, async a => { await base.OrderBy_anon2(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c ORDER BY c["id"] @@ -1471,8 +1471,8 @@ public override async Task OrderBy_shadow(bool async) // Cosmos client evaluation. Issue #17246. await Assert.ThrowsAsync( async () => await base.OrderBy_shadow(async)); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c ORDER BY c["Title"], c["EmployeeID"] @@ -1743,8 +1743,8 @@ public override async Task Select_null_coalesce_operator(bool async) // Cosmos client evaluation. Issue #17246. await Assert.ThrowsAsync( async () => await base.Select_null_coalesce_operator(async)); -AssertSql( - """ + AssertSql( + """ SELECT VALUE { "CustomerID" : c["id"], @@ -1765,8 +1765,8 @@ public override async Task OrderBy_conditional_operator(bool async) // Cosmos client evaluation. Issue #17246. await Assert.ThrowsAsync( async () => await base.OrderBy_conditional_operator(async)); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c ORDER BY ((c["Region"] = null) ? "ZZ" : c["Region"]), c["id"] @@ -1811,8 +1811,8 @@ public override Task Projection_null_coalesce_operator(bool async) async, async a => { await base.Projection_null_coalesce_operator(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE { "CustomerID" : c["id"], @@ -1828,8 +1828,8 @@ public override Task Filter_coalesce_operator(bool async) async, async a => { await base.Filter_coalesce_operator(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c WHERE (((c["ContactName"] != null) ? c["ContactName"] : c["CompanyName"]) = "Liz Nixon") @@ -1906,8 +1906,8 @@ public override async Task Selected_column_can_coalesce(bool async) // Unsupported ORDER BY clause. await Assert.ThrowsAsync( () => base.Selected_column_can_coalesce(async)); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c ORDER BY ((c["Region"] != null) ? c["Region"] : "ZZ") @@ -2073,8 +2073,8 @@ public override async Task Select_bitwise_or(bool async) { // Bitwise operators on booleans. Issue #13168. await Assert.ThrowsAsync(() => base.Select_bitwise_or(async)); -AssertSql( - """ + AssertSql( + """ SELECT VALUE { "CustomerID" : c["id"], @@ -2093,8 +2093,8 @@ public override async Task Select_bitwise_or_multiple(bool async) { // Bitwise operators on booleans. Issue #13168. await Assert.ThrowsAsync(() => base.Select_bitwise_or_multiple(async)); -AssertSql( - """ + AssertSql( + """ SELECT VALUE { "CustomerID" : c["id"], @@ -2113,8 +2113,8 @@ public override async Task Select_bitwise_and(bool async) { // Bitwise operators on booleans. Issue #13168. await Assert.ThrowsAsync(() => base.Select_bitwise_and(async)); -AssertSql( - """ + AssertSql( + """ SELECT VALUE { "CustomerID" : c["id"], @@ -2133,8 +2133,8 @@ public override async Task Select_bitwise_and_or(bool async) { // Bitwise operators on booleans. Issue #13168. await Assert.ThrowsAsync(() => base.Select_bitwise_and_or(async)); -AssertSql( - """ + AssertSql( + """ SELECT VALUE { "CustomerID" : c["id"], @@ -2153,8 +2153,8 @@ public override async Task Where_bitwise_or_with_logical_or(bool async) { // Bitwise operators on booleans. Issue #13168. await Assert.ThrowsAsync(() => base.Where_bitwise_or_with_logical_or(async)); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c WHERE (((c["id"] = "ALFKI") | (c["id"] = "ANATR")) OR (c["id"] = "ANTON")) @@ -2167,8 +2167,8 @@ public override Task Where_bitwise_and_with_logical_and(bool async) async, async a => { await base.Where_bitwise_and_with_logical_and(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c WHERE (((c["id"] = "ALFKI") & (c["id"] = "ANATR")) AND (c["id"] = "ANTON")) @@ -2182,8 +2182,8 @@ public override async Task Where_bitwise_or_with_logical_and(bool async) { // Bitwise operators on booleans. Issue #13168. await Assert.ThrowsAsync(() => base.Where_bitwise_or_with_logical_and(async)); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c WHERE (((c["id"] = "ALFKI") | (c["id"] = "ANATR")) AND (c["Country"] = "Germany")) @@ -2196,8 +2196,8 @@ public override Task Where_bitwise_and_with_logical_or(bool async) async, async a => { await base.Where_bitwise_and_with_logical_or(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c WHERE (((c["id"] = "ALFKI") & (c["id"] = "ANATR")) OR (c["id"] = "ANTON")) @@ -2269,8 +2269,8 @@ public override async Task Select_bitwise_or_with_logical_or(bool async) { // Bitwise operators on booleans. Issue #13168. await Assert.ThrowsAsync(() => base.Select_bitwise_or_with_logical_or(async)); -AssertSql( - """ + AssertSql( + """ SELECT VALUE { "CustomerID" : c["id"], @@ -2289,8 +2289,8 @@ public override async Task Select_bitwise_and_with_logical_and(bool async) { // Bitwise operators on booleans. Issue #13168. await Assert.ThrowsAsync(() => base.Select_bitwise_and_with_logical_and(async)); -AssertSql( - """ + AssertSql( + """ SELECT VALUE { "CustomerID" : c["id"], @@ -2354,7 +2354,7 @@ FROM root c """ SELECT VALUE c FROM root c -WHERE false +WHERE ((c["$type"] = "Order") AND false) """); }); @@ -2641,7 +2641,7 @@ public override async Task DefaultIfEmpty_in_subquery_nested_filter_order_compar await AssertTranslationFailed(() => base.DefaultIfEmpty_in_subquery_nested_filter_order_comparison(async)); AssertSql( -); + ); } public override async Task OrderBy_skip_take(bool async) @@ -2700,7 +2700,7 @@ await AssertTranslationFailedWithDetails( CosmosStrings.LimitOffsetNotSupportedInSubqueries); AssertSql( -); + ); } public override Task OrderBy_skip_take_distinct(bool async) @@ -2811,8 +2811,8 @@ public override Task Anonymous_member_distinct_where(bool async) async, async a => { await base.Anonymous_member_distinct_where(a); -AssertSql( - """ + AssertSql( + """ SELECT DISTINCT VALUE c["id"] FROM root c WHERE (c["id"] = "ALFKI") @@ -2842,8 +2842,8 @@ public override Task Anonymous_complex_distinct_where(bool async) async, async a => { await base.Anonymous_complex_distinct_where(a); -AssertSql( - """ + AssertSql( + """ SELECT DISTINCT VALUE (c["id"] || c["City"]) FROM root c WHERE ((c["id"] || c["City"]) = "ALFKIBerlin") @@ -2865,7 +2865,7 @@ public override async Task Anonymous_complex_distinct_result(bool async) // Cosmos client evaluation. Issue #17246. await AssertTranslationFailed(() => base.Anonymous_complex_distinct_result(async)); AssertSql( -); + ); } public override async Task Anonymous_complex_orderby(bool async) @@ -2889,8 +2889,8 @@ public override async Task Anonymous_subquery_orderby(bool async) { // Cosmos client evaluation. Issue #17246. await AssertTranslationFailed(() => base.Anonymous_subquery_orderby(async)); -AssertSql( -); + AssertSql( + ); } public override Task DTO_member_distinct_where(bool async) @@ -2898,8 +2898,8 @@ public override Task DTO_member_distinct_where(bool async) async, async a => { await base.DTO_member_distinct_where(a); -AssertSql( - """ + AssertSql( + """ SELECT DISTINCT VALUE c["id"] FROM root c WHERE (c["id"] = "ALFKI") @@ -2929,8 +2929,8 @@ public override Task DTO_complex_distinct_where(bool async) async, async a => { await base.DTO_complex_distinct_where(a); -AssertSql( - """ + AssertSql( + """ SELECT DISTINCT VALUE (c["id"] || c["City"]) FROM root c WHERE ((c["id"] || c["City"]) = "ALFKIBerlin") @@ -2963,8 +2963,8 @@ public override async Task DTO_complex_orderby(bool async) // Cosmos client evaluation. Issue #17246. await Assert.ThrowsAsync( async () => await base.DTO_complex_orderby(async)); -AssertSql( - """ + AssertSql( + """ SELECT VALUE (c["id"] || c["City"]) FROM root c ORDER BY (c["id"] || c["City"]) @@ -3190,8 +3190,8 @@ public override async Task Select_distinct_sum(bool async) { // Cosmos client evaluation. Issue #17246. await AssertTranslationFailed(() => base.Select_distinct_sum(async)); -AssertSql( -); + AssertSql( + ); } public override Task Comparing_to_fixed_string_parameter(bool async) @@ -3199,8 +3199,8 @@ public override Task Comparing_to_fixed_string_parameter(bool async) async, async a => { await base.Comparing_to_fixed_string_parameter(a); -AssertSql( - """ + AssertSql( + """ @__prefix_0='A' SELECT VALUE c["id"] @@ -3277,8 +3277,8 @@ public override Task Comparing_collection_navigation_to_null(bool async) async, async a => { await base.Comparing_collection_navigation_to_null(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c["id"] FROM root c WHERE (c["id"] = null) @@ -3291,7 +3291,7 @@ public override async Task Comparing_collection_navigation_to_null_complex(bool await AssertTranslationFailed(() => base.Comparing_collection_navigation_to_null_complex(async)); AssertSql( -); + ); } public override Task Compare_collection_navigation_with_itself(bool async) @@ -3299,8 +3299,8 @@ public override Task Compare_collection_navigation_with_itself(bool async) async, async a => { await base.Compare_collection_navigation_with_itself(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c["id"] FROM root c WHERE (STARTSWITH(c["id"], "A") AND (c["id"] = c["id"])) @@ -3329,7 +3329,7 @@ public override async Task Compare_two_collection_navigations_with_different_pro await AssertTranslationFailed(() => base.Compare_two_collection_navigations_with_different_property_chains(async)); AssertSql( -); + ); } public override Task OrderBy_ThenBy_same_column_different_direction(bool async) @@ -3337,8 +3337,8 @@ public override Task OrderBy_ThenBy_same_column_different_direction(bool async) async, async a => { await base.OrderBy_ThenBy_same_column_different_direction(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c["id"] FROM root c WHERE STARTSWITH(c["id"], "A") @@ -3351,8 +3351,8 @@ public override Task OrderBy_OrderBy_same_column_different_direction(bool async) async, async a => { await base.OrderBy_OrderBy_same_column_different_direction(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c["id"] FROM root c WHERE STARTSWITH(c["id"], "A") @@ -3383,8 +3383,8 @@ public override Task OrderBy_Dto_projection_skip_take(bool async) async, async a => { await base.OrderBy_Dto_projection_skip_take(a); -AssertSql( - """ + AssertSql( + """ @__p_0='5' @__p_1='10' @@ -3399,8 +3399,8 @@ public override async Task Join_take_count_works(bool async) { // Cosmos client evaluation. Issue #17246. await AssertTranslationFailed(() => base.Join_take_count_works(async)); -AssertSql( -); + AssertSql( + ); } public override async Task OrderBy_empty_list_contains(bool async) @@ -3410,8 +3410,8 @@ public override async Task OrderBy_empty_list_contains(bool async) { await Assert.ThrowsAsync( async () => await base.OrderBy_empty_list_contains(async)); -AssertSql( - """ + AssertSql( + """ @__list_0='[]' SELECT VALUE c @@ -3615,8 +3615,8 @@ public override async Task OrderByDescending_ThenByDescending(bool async) // Cosmos client evaluation. Issue #17246. await Assert.ThrowsAsync( async () => await base.OrderByDescending_ThenByDescending(async)); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c["City"] FROM root c ORDER BY c["id"] DESC, c["Country"] DESC @@ -3630,7 +3630,7 @@ public override async Task OrderBy_Join(bool async) await AssertTranslationFailed(() => base.OrderBy_Join(async)); AssertSql( -); + ); } public override async Task OrderBy_ThenBy(bool async) @@ -3763,8 +3763,8 @@ public override Task Where_Property_when_shadow_unconstrained_generic_method(boo async, async a => { await base.Where_Property_when_shadow_unconstrained_generic_method(a); -AssertSql( - """ + AssertSql( + """ @__value_0='Sales Representative' SELECT VALUE c @@ -4006,8 +4006,8 @@ public override Task Entity_equality_contains_with_list_of_null(bool async) async, async a => { await base.Entity_equality_contains_with_list_of_null(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c WHERE c["id"] IN (null, "ALFKI") @@ -4208,8 +4208,8 @@ public override Task AsEnumerable_over_string(bool async) async, async a => { await base.AsEnumerable_over_string(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c["City"] FROM root c ORDER BY c["id"] @@ -4289,8 +4289,8 @@ public override async Task Throws_on_concurrent_query_first(bool async) if (async) { await base.Throws_on_concurrent_query_first(async); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c """); @@ -4302,8 +4302,8 @@ public override Task Entity_equality_through_include(bool async) async, async a => { await base.Entity_equality_through_include(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c["id"] FROM root c WHERE (c["id"] = null) @@ -4352,8 +4352,8 @@ public override Task OrderBy_Select(bool async) async, async a => { await base.OrderBy_Select(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c["ContactName"] FROM root c ORDER BY c["id"] @@ -4397,8 +4397,8 @@ public override Task ToList_over_string(bool async) async, async a => { await base.ToList_over_string(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c["City"] FROM root c ORDER BY c["id"] @@ -4431,8 +4431,8 @@ public override Task ToListAsync_with_canceled_token() true, async _ => { await base.ToListAsync_with_canceled_token(); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c """); @@ -4460,8 +4460,8 @@ public override Task Entity_equality_orderby(bool async) async, async a => { await base.Entity_equality_orderby(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c ORDER BY c["id"] @@ -4473,8 +4473,8 @@ public override Task Load_should_track_results(bool async) async, async a => { await base.Load_should_track_results(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c """); @@ -4494,16 +4494,16 @@ public override Task Where_Property_shadow_closure(bool async) async, async a => { await base.Where_Property_shadow_closure(a); -AssertSql( - """ + AssertSql( + """ @__value_0='Sales Representative' SELECT VALUE c FROM root c WHERE (c["Title"] = @__value_0) """, - // - """ + // + """ @__value_0='Steven' SELECT VALUE c @@ -4547,8 +4547,8 @@ public override Task MemberInitExpression_NewExpression_is_funcletized_even_when async, async a => { await base.MemberInitExpression_NewExpression_is_funcletized_even_when_bindings_are_not_evaluatable(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c["id"] FROM root c WHERE STARTSWITH(c["id"], "A") @@ -4608,8 +4608,8 @@ public override async Task Throws_on_concurrent_query_list(bool async) if (async) { await base.Throws_on_concurrent_query_list(async); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c """); @@ -4667,8 +4667,8 @@ public override Task OrderByDescending(bool async) async, async a => { await base.OrderByDescending(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c["City"] FROM root c ORDER BY c["id"] DESC @@ -4964,8 +4964,8 @@ public override Task Contains_over_concatenated_columns_with_different_sizes(boo async, async a => { await base.Contains_over_concatenated_columns_with_different_sizes(a); -AssertSql( - """ + AssertSql( + """ @__data_0='["ALFKIAlfreds Futterkiste","ANATRAna Trujillo Emparedados y helados"]' SELECT VALUE c @@ -5003,8 +5003,8 @@ public override Task Contains_over_concatenated_column_and_parameter(bool async) async, async a => { await base.Contains_over_concatenated_column_and_parameter(a); -AssertSql( - """ + AssertSql( + """ @__data_1='["ALFKISomeVariable","ANATRSomeVariable","ALFKIX"]' @__someVariable_0='SomeVariable' @@ -5035,8 +5035,8 @@ public override Task Compiler_generated_local_closure_produces_valid_parameter_n async, async a => { await base.Compiler_generated_local_closure_produces_valid_parameter_name(a); -AssertSql( - """ + AssertSql( + """ @__customerId_0='ALFKI' @__details_City_1='Berlin' @@ -5055,6 +5055,42 @@ public override Task Static_member_access_gets_parameterized_within_larger_evalu AssertSql("ReadItem(None, ALFKI)"); }); + public override Task Select_Order(bool async) + => Fixture.NoSyncTest( + async, async a => + { + await base.Select_Order(a); + + AssertSql( + """ +SELECT VALUE c["id"] +FROM root c +ORDER BY c["id"] +"""); + }); + + public override Task Select_OrderDescending(bool async) + => Fixture.NoSyncTest( + async, async a => + { + await base.Select_OrderDescending(a); + + AssertSql( + """ +SELECT VALUE c["id"] +FROM root c +ORDER BY c["id"] DESC +"""); + }); + + public override async Task Where_Order_First(bool async) + { + await AssertTranslationFailed( + () => base.Where_Order_First(async)); + + AssertSql(); + } + #region ToPageAsync [ConditionalFact] @@ -5184,13 +5220,13 @@ public virtual async Task ToPageAsync_with_exact_maxItemCount() Assert.Equal("ALFKI", onlyPage.Values[0].CustomerID); Assert.Equal("WOLZA", onlyPage.Values[^1].CustomerID); Assert.Null(onlyPage.ContinuationToken); -AssertSql( - """ + AssertSql( + """ SELECT VALUE COUNT(1) FROM root c """, - // - """ + // + """ SELECT VALUE c FROM root c ORDER BY c["id"] @@ -5208,8 +5244,8 @@ public virtual async Task ToPageAsync_does_not_use_ReadItem() Assert.Equal("ALFKI", onlyPage.Values[0].CustomerID); Assert.Null(onlyPage.ContinuationToken); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c WHERE (c["id"] = "ALFKI") diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindQueryCosmosFixture.cs b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindQueryCosmosFixture.cs index 9ea50d1c564..a96b54ccbf8 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindQueryCosmosFixture.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindQueryCosmosFixture.cs @@ -30,8 +30,9 @@ public void NoSyncTest(Action testCode) => CosmosTestHelpers.Instance.NoSyncTest(testCode); public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) - => base.AddOptions(builder.ConfigureWarnings( - w => w.Ignore(CosmosEventId.NoPartitionKeyDefined))); + => base.AddOptions( + builder.ConfigureWarnings( + w => w.Ignore(CosmosEventId.NoPartitionKeyDefined))); protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) { @@ -41,32 +42,32 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con modelBuilder.Entity().ToContainer("Employees"); modelBuilder.Entity() - .IncludeRootDiscriminatorInJsonId() + .HasRootDiscriminatorInJsonId() .ToContainer("ProductsAndOrders"); modelBuilder.Entity() - .IncludeRootDiscriminatorInJsonId() + .HasRootDiscriminatorInJsonId() .ToContainer("ProductsAndOrders"); modelBuilder.Entity() - .IncludeRootDiscriminatorInJsonId() + .HasRootDiscriminatorInJsonId() .ToContainer("ProductsAndOrders"); modelBuilder.Entity() .ToContainer("ProductsAndOrders") - .IncludeRootDiscriminatorInJsonId() + .HasRootDiscriminatorInJsonId() .HasDiscriminator("$type").HasValue("Order"); modelBuilder .Entity() .ToContainer("ProductsAndOrders") - .IncludeRootDiscriminatorInJsonId() + .HasRootDiscriminatorInJsonId() .HasDiscriminator("$type").HasValue("Product"); modelBuilder .Entity() .ToContainer("ProductsAndOrders") - .IncludeRootDiscriminatorInJsonId() + .HasRootDiscriminatorInJsonId() .HasDiscriminator("$type").HasValue("ProductView"); modelBuilder diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindSelectQueryCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindSelectQueryCosmosTest.cs index 0a268f9aec9..3890ecec032 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindSelectQueryCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindSelectQueryCosmosTest.cs @@ -141,8 +141,8 @@ public override Task Projection_of_entity_type_into_object_array(bool async) async, async a => { await base.Projection_of_entity_type_into_object_array(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c WHERE STARTSWITH(c["id"], "A") @@ -163,8 +163,8 @@ public override Task Projection_of_entity_type_into_object_list(bool async) async, async a => { await base.Projection_of_entity_type_into_object_list(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c ORDER BY c["id"] @@ -230,8 +230,8 @@ public override Task Select_anonymous_one(bool async) async, async a => { await base.Select_anonymous_one(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c["City"] FROM root c """); @@ -285,8 +285,8 @@ public override Task Select_anonymous_constant_in_expression(bool async) async, async a => { await base.Select_anonymous_constant_in_expression(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE { "CustomerID" : c["id"], @@ -332,8 +332,8 @@ public override Task Select_constant_int(bool async) async, async a => { await base.Select_constant_int(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE 0 FROM root c """); @@ -357,8 +357,8 @@ public override Task Select_local(bool async) async, async a => { await base.Select_local(a); -AssertSql( - """ + AssertSql( + """ @__x_0='10' SELECT VALUE @__x_0 @@ -387,8 +387,8 @@ public override Task Select_project_filter(bool async) async, async a => { await base.Select_project_filter(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c["CompanyName"] FROM root c WHERE (c["City"] = "London") @@ -478,8 +478,8 @@ public override Task New_date_time_in_anonymous_type_works(bool async) async, async a => { await base.New_date_time_in_anonymous_type_works(a); -AssertSql( - """ + AssertSql( + """ SELECT 1 FROM root c WHERE STARTSWITH(c["id"], "A") @@ -952,8 +952,8 @@ public override Task Anonymous_projection_with_repeated_property_being_ordered(b async, async a => { await base.Anonymous_projection_with_repeated_property_being_ordered(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c["id"] FROM root c ORDER BY c["id"] @@ -995,8 +995,8 @@ public override Task Client_method_in_projection_requiring_materialization_1(boo async, async a => { await base.Client_method_in_projection_requiring_materialization_1(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c WHERE STARTSWITH(c["id"], "A") @@ -1008,8 +1008,8 @@ public override Task Client_method_in_projection_requiring_materialization_2(boo async, async a => { await base.Client_method_in_projection_requiring_materialization_2(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c WHERE STARTSWITH(c["id"], "A") @@ -1400,8 +1400,8 @@ public override Task Projection_take_projection_doesnt_project_intermittent_colu async, async a => { await base.Projection_take_projection_doesnt_project_intermittent_column(a); -AssertSql( - """ + AssertSql( + """ @__p_0='10' SELECT VALUE ((c["id"] || " ") || c["City"]) @@ -1694,13 +1694,13 @@ public override Task Select_bool_closure(bool async) async, async a => { await base.Select_bool_closure(a); -AssertSql( - """ + AssertSql( + """ SELECT 1 FROM root c """, - // - """ + // + """ SELECT 1 FROM root c """); @@ -1824,8 +1824,8 @@ public override Task Select_anonymous_empty(bool async) async, async a => { await base.Select_anonymous_empty(a); -AssertSql( - """ + AssertSql( + """ SELECT 1 FROM root c """); @@ -1849,8 +1849,8 @@ public override Task Select_into(bool async) async, async a => { await base.Select_into(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c["id"] FROM root c WHERE (c["id"] = "ALFKI") @@ -1947,8 +1947,8 @@ public override Task Select_over_10_nested_ternary_condition(bool async) async, async a => { await base.Select_over_10_nested_ternary_condition(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE ((c["id"] = "1") ? "01" : ((c["id"] = "2") ? "02" : ((c["id"] = "3") ? "03" : ((c["id"] = "4") ? "04" : ((c["id"] = "5") ? "05" : ((c["id"] = "6") ? "06" : ((c["id"] = "7") ? "07" : ((c["id"] = "8") ? "08" : ((c["id"] = "9") ? "09" : ((c["id"] = "10") ? "10" : ((c["id"] = "11") ? "11" : null))))))))))) FROM root c """); diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindWhereQueryCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindWhereQueryCosmosTest.cs index bbf6d938b00..81298094b74 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindWhereQueryCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindWhereQueryCosmosTest.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Azure.Cosmos; using Microsoft.EntityFrameworkCore.Cosmos.Internal; using Microsoft.EntityFrameworkCore.TestModels.Northwind; using Xunit.Sdk; @@ -1455,8 +1454,8 @@ public override Task Where_is_not_null(bool async) async, async a => { await base.Where_is_not_null(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c WHERE (c["City"] != null) @@ -1482,8 +1481,8 @@ public override Task Where_constant_is_not_null(bool async) async, async a => { await base.Where_constant_is_not_null(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c """); @@ -1827,8 +1826,8 @@ public override Task Where_comparison_to_nullable_bool(bool async) async, async a => { await base.Where_comparison_to_nullable_bool(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c WHERE (ENDSWITH(c["id"], "KI") = true) @@ -1840,8 +1839,8 @@ public override Task Where_true(bool async) async, async a => { await base.Where_true(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c """); @@ -1953,7 +1952,7 @@ public override async Task Where_concat_string_int_comparison4(bool async) await AssertTranslationFailed(() => base.Where_concat_string_int_comparison4(async)); AssertSql( -); + ); } public override Task Where_string_concat_method_comparison(bool async) @@ -2075,7 +2074,7 @@ public override Task Where_ternary_boolean_condition_with_false_as_result_false( """ SELECT VALUE c FROM root c -WHERE false +WHERE ((c["$type"] = "Product") AND false) """); }); @@ -2234,7 +2233,7 @@ public override async Task Where_multiple_contains_in_subquery_with_or(bool asyn await AssertTranslationFailed(() => base.Where_multiple_contains_in_subquery_with_or(async)); AssertSql( -); + ); } public override async Task Where_multiple_contains_in_subquery_with_and(bool async) @@ -2528,7 +2527,7 @@ public override Task Filter_with_EF_Property_using_closure_for_property_name(boo await base.Filter_with_EF_Property_using_closure_for_property_name(a); AssertSql("ReadItem(None, ALFKI)"); - }); + }); public override Task Filter_with_EF_Property_using_function_for_property_name(bool async) => Fixture.NoSyncTest( @@ -2711,7 +2710,7 @@ public override async Task Where_Like_or_comparison(bool async) await AssertTranslationFailed(() => base.Where_Like_or_comparison(async)); AssertSql( -); + ); } public override Task GetType_on_non_hierarchy1(bool async) @@ -2760,8 +2759,8 @@ public override Task GetType_on_non_hierarchy4(bool async) async, async a => { await base.GetType_on_non_hierarchy4(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c """); @@ -2772,8 +2771,8 @@ public override Task Case_block_simplification_works_correctly(bool async) async, async a => { await base.Case_block_simplification_works_correctly(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c WHERE (((c["Region"] = null) ? "OR" : c["Region"]) = "OR") @@ -2857,8 +2856,8 @@ public override Task Generic_Ilist_contains_translates_to_server(bool async) async, async a => { await base.Generic_Ilist_contains_translates_to_server(a); -AssertSql( - """ + AssertSql( + """ @__cities_0='["Seattle"]' SELECT VALUE c @@ -2886,8 +2885,8 @@ public override Task Multiple_OrElse_on_same_column_with_null_constant_compariso async, async a => { await base.Multiple_OrElse_on_same_column_with_null_constant_comparison_converted_to_in(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c WHERE ((((c["Region"] = "WA") OR (c["Region"] = "OR")) OR (c["Region"] = null)) OR (c["Region"] = "BC")) @@ -2899,8 +2898,8 @@ public override Task Constant_array_Contains_OrElse_comparison_with_constant_get async, async a => { await base.Constant_array_Contains_OrElse_comparison_with_constant_gets_combined_to_one_in(a); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c WHERE (c["id"] IN ("ALFKI", "ANATR") OR (c["id"] = "ANTON")) @@ -3123,16 +3122,16 @@ public override Task Where_poco_closure(bool async) async, async a => { await base.Where_poco_closure(a); -AssertSql( - """ + AssertSql( + """ @__entity_equality_customer_0_CustomerID='ALFKI' SELECT VALUE c["id"] FROM root c WHERE (c["id"] = @__entity_equality_customer_0_CustomerID) """, - // - """ + // + """ @__entity_equality_customer_0_CustomerID='ANATR' SELECT VALUE c["id"] @@ -3184,8 +3183,8 @@ public override async Task EF_Constant_does_not_parameterized_as_part_of_bigger_ public override async Task EF_Constant_with_non_evaluatable_argument_throws(bool async) { await base.EF_Constant_with_non_evaluatable_argument_throws(async); -AssertSql( -); + AssertSql( + ); } public override Task EF_Parameter(bool async) diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/OwnedQueryCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/OwnedQueryCosmosTest.cs index 5a236b80163..bd0ccc93934 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/OwnedQueryCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/OwnedQueryCosmosTest.cs @@ -68,7 +68,8 @@ public override async Task Navigation_rewrite_on_owned_collection_with_compositi // Always throws for sync. if (async) { - var exception = await Assert.ThrowsAsync(() => base.Navigation_rewrite_on_owned_collection_with_composition(async)); + var exception = + await Assert.ThrowsAsync(() => base.Navigation_rewrite_on_owned_collection_with_composition(async)); Assert.Equal(HttpStatusCode.BadRequest, exception.StatusCode); @@ -269,12 +270,14 @@ await AssertTranslationFailedWithDetails( AssertSql(); } - public override async Task Navigation_rewrite_on_owned_reference_followed_by_regular_entity_and_another_reference_in_predicate_and_projection( - bool async) + public override async Task + Navigation_rewrite_on_owned_reference_followed_by_regular_entity_and_another_reference_in_predicate_and_projection( + bool async) { // Address.Planet is a non-owned navigation, cross-document join await AssertTranslationFailedWithDetails( - () => base.Navigation_rewrite_on_owned_reference_followed_by_regular_entity_and_another_reference_in_predicate_and_projection(async), + () => base.Navigation_rewrite_on_owned_reference_followed_by_regular_entity_and_another_reference_in_predicate_and_projection( + async), CosmosStrings.MultipleRootEntityTypesReferencedInQuery("Planet", "OwnedPerson")); AssertSql(); @@ -1337,8 +1340,9 @@ public TestSqlLoggerFactory TestSqlLoggerFactory => (TestSqlLoggerFactory)ServiceProvider.GetRequiredService(); public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) - => base.AddOptions(builder.ConfigureWarnings( - w => w.Ignore(CosmosEventId.NoPartitionKeyDefined))); + => base.AddOptions( + builder.ConfigureWarnings( + w => w.Ignore(CosmosEventId.NoPartitionKeyDefined))); protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) { diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/PrimitiveCollectionsQueryCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/PrimitiveCollectionsQueryCosmosTest.cs index a931d3dccc6..78dd12d771c 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/PrimitiveCollectionsQueryCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/PrimitiveCollectionsQueryCosmosTest.cs @@ -377,10 +377,10 @@ public override Task Inline_collection_Max_with_three_values(bool async) => CosmosTestHelpers.Instance.NoSyncTest( async, async a => { - await base.Inline_collection_Max_with_three_values(a); + await base.Inline_collection_Max_with_three_values(a); - AssertSql( - """ + AssertSql( + """ @__i_0='35' SELECT VALUE c @@ -517,6 +517,41 @@ FROM a IN (SELECT VALUE [@__i_0]) """); }); + public override Task Inline_collection_Contains_with_EF_Parameter(bool async) + => CosmosTestHelpers.Instance.NoSyncTest( + async, async a => + { + await base.Inline_collection_Contains_with_EF_Parameter(async); + + AssertSql( + """ +@__p_0='[2,999,1000]' + +SELECT VALUE c +FROM root c +WHERE ARRAY_CONTAINS(@__p_0, c["Id"]) +"""); + }); + + public override Task Inline_collection_Count_with_column_predicate_with_EF_Parameter(bool async) + => CosmosTestHelpers.Instance.NoSyncTest( + async, async a => + { + await base.Inline_collection_Count_with_column_predicate_with_EF_Parameter(async); + + AssertSql( + """ +@__p_0='[2,999,1000]' + +SELECT VALUE c +FROM root c +WHERE (( + SELECT VALUE COUNT(1) + FROM p IN (SELECT VALUE @__p_0) + WHERE (p > c["Id"])) = 2) +"""); + }); + public override Task Parameter_collection_Count(bool async) => CosmosTestHelpers.Instance.NoSyncTest( async, async a => @@ -1502,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 => @@ -2057,8 +2113,9 @@ protected override ITestStoreFactory TestStoreFactory => CosmosTestStoreFactory.Instance; public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) - => base.AddOptions(builder.ConfigureWarnings( - w => w.Ignore(CosmosEventId.NoPartitionKeyDefined))); + => base.AddOptions( + builder.ConfigureWarnings( + w => w.Ignore(CosmosEventId.NoPartitionKeyDefined))); protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) { diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/QueryLoggingCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/QueryLoggingCosmosTest.cs index 57c42bbe0fd..26c7fc1a9fe 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/QueryLoggingCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/QueryLoggingCosmosTest.cs @@ -7,8 +7,9 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class QueryLoggingCosmosTest(QueryLoggingCosmosTest.NorthwindQueryCosmosFixtureInsensitive fixture) : QueryLoggingCosmosTestBase(fixture), - IClassFixture> +public class QueryLoggingCosmosTest(QueryLoggingCosmosTest.NorthwindQueryCosmosFixtureInsensitive fixture) + : QueryLoggingCosmosTestBase(fixture), + IClassFixture> { public class NorthwindQueryCosmosFixtureInsensitive : NorthwindQueryCosmosFixture where TModelCustomizer : ITestModelCustomizer, new() diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/QueryLoggingCosmosTestSensitive.cs b/test/EFCore.Cosmos.FunctionalTests/Query/QueryLoggingCosmosTestSensitive.cs index df562c4c1c6..e4ab578e139 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/QueryLoggingCosmosTestSensitive.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/QueryLoggingCosmosTestSensitive.cs @@ -5,5 +5,6 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class QueryLoggingCosmosTestSensitive(NorthwindQueryCosmosFixture fixture) : QueryLoggingCosmosTestBase(fixture), - IClassFixture>; +public class QueryLoggingCosmosTestSensitive(NorthwindQueryCosmosFixture fixture) + : QueryLoggingCosmosTestBase(fixture), + IClassFixture>; diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryDiscriminatorInIdTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryDiscriminatorInIdTest.cs index 6ad245a065f..56282084c14 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryDiscriminatorInIdTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryDiscriminatorInIdTest.cs @@ -78,7 +78,20 @@ public override async Task Predicate_with_partial_values_in_hierarchical_partiti """ SELECT VALUE c FROM root c -WHERE (c["$type"] IN ("HierarchicalPartitionKeyEntity", "DerivedHierarchicalPartitionKeyEntity") AND ((c["PartitionKey1"] = "PK1") AND (c["PartitionKey2"] = 1))) +WHERE c["$type"] IN ("HierarchicalPartitionKeyEntity", "DerivedHierarchicalPartitionKeyEntity") +"""); + } + + public override async Task Predicate_with_partial_values_and_gap_in_hierarchical_partition_key() + { + await base.Predicate_with_partial_values_and_gap_in_hierarchical_partition_key(); + + // Not ReadItem because no primary key value + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE (c["$type"] IN ("HierarchicalPartitionKeyEntity", "DerivedHierarchicalPartitionKeyEntity") AND c["PartitionKey3"]) """); } @@ -91,7 +104,7 @@ public override async Task Predicate_with_partial_values_in_only_hierarchical_pa """ SELECT VALUE c FROM root c -WHERE (c["$type"] IN ("OnlyHierarchicalPartitionKeyEntity", "DerivedOnlyHierarchicalPartitionKeyEntity") AND ((c["PartitionKey1"] = "PK1a") AND (c["PartitionKey2"] = 1))) +WHERE c["$type"] IN ("OnlyHierarchicalPartitionKeyEntity", "DerivedOnlyHierarchicalPartitionKeyEntity") """); } @@ -175,11 +188,16 @@ FROM root c """); } - public override async Task WithPartitionKey_with_missing_value_in_hierarchical_partition_key() + public override async Task WithPartitionKey_with_partial_value_in_hierarchical_partition_key() { - await base.WithPartitionKey_with_missing_value_in_hierarchical_partition_key(); + await base.WithPartitionKey_with_partial_value_in_hierarchical_partition_key(); - AssertSql(); + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE c["$type"] IN ("HierarchicalPartitionKeyEntity", "DerivedHierarchicalPartitionKeyEntity") +"""); } public override async Task Both_WithPartitionKey_and_predicate_comparisons_with_different_values() @@ -243,7 +261,7 @@ public override async Task ReadItem_with_hierarchical_partition_key() """ SELECT VALUE c FROM root c -WHERE (c["$type"] IN ("HierarchicalPartitionKeyEntity", "DerivedHierarchicalPartitionKeyEntity") AND (c["Id"] = 1)) +WHERE (c["$type"] IN ("HierarchicalPartitionKeyEntity", "DerivedHierarchicalPartitionKeyEntity") AND (c["Id"] = "31887258-bdf9-49b8-89b2-01b6aa741a4a")) """); } @@ -268,7 +286,7 @@ public override async Task ReadItem_with_single_partition_key_constant() """ SELECT VALUE c FROM root c -WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND (c["Id"] = 1)) +WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND (c["Id"] = "b29bced8-e1e5-420e-82d7-1c7a51703d34")) """); } @@ -294,7 +312,7 @@ public override async Task ReadItem_with_single_partition_key_parameter() """ SELECT VALUE c FROM root c -WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND (c["Id"] = 1)) +WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND (c["Id"] = "b29bced8-e1e5-420e-82d7-1c7a51703d34")) """); } @@ -320,7 +338,7 @@ public override async Task ReadItem_with_SingleAsync() """ SELECT VALUE c FROM root c -WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND (c["Id"] = 1)) +WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND (c["Id"] = "b29bced8-e1e5-420e-82d7-1c7a51703d34")) OFFSET 0 LIMIT 2 """); } @@ -347,7 +365,7 @@ public override async Task ReadItem_with_inverse_comparison() """ SELECT VALUE c FROM root c -WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND (1 = c["Id"])) +WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND ("b29bced8-e1e5-420e-82d7-1c7a51703d34" = c["Id"])) """); } @@ -373,7 +391,7 @@ public override async Task ReadItem_with_EF_Property() """ SELECT VALUE c FROM root c -WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND (c["Id"] = 1)) +WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND (c["Id"] = "b29bced8-e1e5-420e-82d7-1c7a51703d34")) """); } @@ -386,15 +404,15 @@ public override async Task ReadItem_with_WithPartitionKey() """ SELECT VALUE c FROM root c -WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND (c["Id"] = 1)) +WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND (c["Id"] = "b29bced8-e1e5-420e-82d7-1c7a51703d34")) """); } public override async Task ReadItem_with_WithPartitionKey_with_only_partition_key() { await base.ReadItem_with_WithPartitionKey_with_only_partition_key(); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c WHERE (c["$type"] IN ("OnlySinglePartitionKeyEntity", "DerivedOnlySinglePartitionKeyEntity") AND (c["PartitionKey"] = "PK1a")) @@ -410,11 +428,10 @@ public override async Task Multiple_incompatible_predicate_comparisons_cause_no_ """ SELECT VALUE c FROM root c -WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND ((c["Id"] = 1) AND (c["Id"] = 2))) +WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND ((c["Id"] = "b29bced8-e1e5-420e-82d7-1c7a51703d34") AND (c["Id"] = "3307a33b-7f28-49ef-9857-48f4e3ebcaed"))) """); } - public override async Task Multiple_incompatible_predicate_comparisons_cause_no_ReadItem_with_only_partition_key() { await base.Multiple_incompatible_predicate_comparisons_cause_no_ReadItem_with_only_partition_key(); @@ -451,18 +468,18 @@ public override async Task ReadItem_is_not_used_without_partition_key() """ SELECT VALUE c FROM root c -WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND (c["Id"] = 1)) +WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND (c["Id"] = "b29bced8-e1e5-420e-82d7-1c7a51703d34")) """); } public override async Task ReadItem_with_non_existent_id() { await base.ReadItem_with_non_existent_id(); -AssertSql( - """ + AssertSql( + """ SELECT VALUE c FROM root c -WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND (c["Id"] = 999)) +WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND (c["Id"] = "50b66960-35be-40c5-bc3d-4c9f2799d4d1")) """); } @@ -474,7 +491,7 @@ public override async Task ReadItem_with_AsNoTracking() """ SELECT VALUE c FROM root c -WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND (c["Id"] = 1)) +WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND (c["Id"] = "b29bced8-e1e5-420e-82d7-1c7a51703d34")) """); } @@ -487,7 +504,7 @@ public override async Task ReadItem_with_AsNoTrackingWithIdentityResolution() """ SELECT VALUE c FROM root c -WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND (c["Id"] = 1)) +WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND (c["Id"] = "b29bced8-e1e5-420e-82d7-1c7a51703d34")) """); } @@ -520,7 +537,6 @@ public override async Task ReadItem_for_child_type_with_shared_container() AssertSql("""ReadItem(["PK2"], SharedContainerEntity2Child|5)"""); } - public override async Task Predicate_with_hierarchical_partition_key_leaf() { await base.Predicate_with_hierarchical_partition_key_leaf(); @@ -570,7 +586,7 @@ public override async Task Predicate_with_partial_values_in_hierarchical_partiti """ SELECT VALUE c FROM root c -WHERE ((c["$type"] = "DerivedHierarchicalPartitionKeyEntity") AND ((c["PartitionKey1"] = "PK1") AND (c["PartitionKey2"] = 1))) +WHERE (c["$type"] = "DerivedHierarchicalPartitionKeyEntity") """); } @@ -583,7 +599,7 @@ public override async Task Predicate_with_partial_values_in_only_hierarchical_pa """ SELECT VALUE c FROM root c -WHERE ((c["$type"] = "DerivedOnlyHierarchicalPartitionKeyEntity") AND ((c["PartitionKey1"] = "PK1c") AND (c["PartitionKey2"] = 1))) +WHERE (c["$type"] = "DerivedOnlyHierarchicalPartitionKeyEntity") """); } @@ -667,11 +683,16 @@ FROM root c """); } - public override async Task WithPartitionKey_with_missing_value_in_hierarchical_partition_key_leaf() + public override async Task WithPartitionKey_with_partial_value_in_hierarchical_partition_key_leaf() { - await base.WithPartitionKey_with_missing_value_in_hierarchical_partition_key(); + await base.WithPartitionKey_with_partial_value_in_hierarchical_partition_key(); - AssertSql(); + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE c["$type"] IN ("HierarchicalPartitionKeyEntity", "DerivedHierarchicalPartitionKeyEntity") +"""); } public override async Task Both_WithPartitionKey_and_predicate_comparisons_with_different_values_leaf() @@ -724,7 +745,10 @@ public override async Task ReadItem_with_hierarchical_partition_key_leaf() { await base.ReadItem_with_hierarchical_partition_key_leaf(); - AssertSql("""ReadItem(["PK1",1.0,true], DerivedHierarchicalPartitionKeyEntity|11)"""); + AssertSql( + """ +ReadItem(["PK1",1.0,true], DerivedHierarchicalPartitionKeyEntity|316c846c-787f-44b9-aadf-272f1658c5ff) +"""); } public override async Task ReadItem_with_only_hierarchical_partition_key_leaf() @@ -738,7 +762,7 @@ public override async Task ReadItem_with_single_partition_key_constant_leaf() { await base.ReadItem_with_single_partition_key_constant_leaf(); - AssertSql("""ReadItem(["PK1"], DerivedSinglePartitionKeyEntity|11)"""); + AssertSql("""ReadItem(["PK1"], DerivedSinglePartitionKeyEntity|188d3253-81be-4a87-b58f-a2bd07e6b98c)"""); } public override async Task ReadItem_with_only_single_partition_key_constant_leaf() @@ -752,7 +776,7 @@ public override async Task ReadItem_with_single_partition_key_parameter_leaf() { await base.ReadItem_with_single_partition_key_parameter_leaf(); - AssertSql("""ReadItem(["PK1"], DerivedSinglePartitionKeyEntity|11)"""); + AssertSql("""ReadItem(["PK1"], DerivedSinglePartitionKeyEntity|188d3253-81be-4a87-b58f-a2bd07e6b98c)"""); } public override async Task ReadItem_with_only_single_partition_key_parameter_leaf() @@ -766,7 +790,7 @@ public override async Task ReadItem_with_SingleAsync_leaf() { await base.ReadItem_with_SingleAsync_leaf(); - AssertSql("""ReadItem(["PK1"], DerivedSinglePartitionKeyEntity|11)"""); + AssertSql("""ReadItem(["PK1"], DerivedSinglePartitionKeyEntity|188d3253-81be-4a87-b58f-a2bd07e6b98c)"""); } public override async Task ReadItem_with_SingleAsync_with_only_partition_key_leaf() @@ -780,7 +804,7 @@ public override async Task ReadItem_with_inverse_comparison_leaf() { await base.ReadItem_with_inverse_comparison_leaf(); - AssertSql("""ReadItem(["PK1"], DerivedSinglePartitionKeyEntity|11)"""); + AssertSql("""ReadItem(["PK1"], DerivedSinglePartitionKeyEntity|188d3253-81be-4a87-b58f-a2bd07e6b98c)"""); } public override async Task ReadItem_with_inverse_comparison_with_only_partition_key_leaf() @@ -794,14 +818,14 @@ public override async Task ReadItem_with_EF_Property_leaf() { await base.ReadItem_with_EF_Property_leaf(); - AssertSql("""ReadItem(["PK1"], DerivedSinglePartitionKeyEntity|11)"""); + AssertSql("""ReadItem(["PK1"], DerivedSinglePartitionKeyEntity|188d3253-81be-4a87-b58f-a2bd07e6b98c)"""); } public override async Task ReadItem_with_WithPartitionKey_leaf() { await base.ReadItem_with_WithPartitionKey_leaf(); - AssertSql("""ReadItem(["PK1"], DerivedSinglePartitionKeyEntity|11)"""); + AssertSql("""ReadItem(["PK1"], DerivedSinglePartitionKeyEntity|188d3253-81be-4a87-b58f-a2bd07e6b98c)"""); } public override async Task ReadItem_with_WithPartitionKey_with_only_partition_key_leaf() @@ -820,7 +844,7 @@ public override async Task Multiple_incompatible_predicate_comparisons_cause_no_ """ SELECT VALUE c FROM root c -WHERE ((c["$type"] = "DerivedSinglePartitionKeyEntity") AND ((c["Id"] = 11) AND (c["Id"] = 22))) +WHERE ((c["$type"] = "DerivedSinglePartitionKeyEntity") AND ((c["Id"] = "188d3253-81be-4a87-b58f-a2bd07e6b98c") AND (c["Id"] = "11f8d1fd-7472-46f5-9e20-16af42b3b8d1"))) """); } @@ -854,7 +878,7 @@ public override async Task ReadItem_is_not_used_without_partition_key_leaf() """ SELECT VALUE c FROM root c -WHERE ((c["$type"] = "DerivedSinglePartitionKeyEntity") AND (c["Id"] = 11)) +WHERE ((c["$type"] = "DerivedSinglePartitionKeyEntity") AND (c["Id"] = "188d3253-81be-4a87-b58f-a2bd07e6b98c")) """); } @@ -862,21 +886,21 @@ public override async Task ReadItem_with_non_existent_id_leaf() { await base.ReadItem_with_non_existent_id_leaf(); - AssertSql("""ReadItem(["PK1"], DerivedSinglePartitionKeyEntity|999)"""); + AssertSql("""ReadItem(["PK1"], DerivedSinglePartitionKeyEntity|b964beda-b4e1-4f5c-a729-0a35dae696fe)"""); } public override async Task ReadItem_with_AsNoTracking_leaf() { await base.ReadItem_with_AsNoTracking_leaf(); - AssertSql("""ReadItem(["PK1"], DerivedSinglePartitionKeyEntity|11)"""); + AssertSql("""ReadItem(["PK1"], DerivedSinglePartitionKeyEntity|188d3253-81be-4a87-b58f-a2bd07e6b98c)"""); } public override async Task ReadItem_with_AsNoTrackingWithIdentityResolution_leaf() { await base.ReadItem_with_AsNoTrackingWithIdentityResolution_leaf(); - AssertSql("""ReadItem(["PK1"], DerivedSinglePartitionKeyEntity|11)"""); + AssertSql("""ReadItem(["PK1"], DerivedSinglePartitionKeyEntity|188d3253-81be-4a87-b58f-a2bd07e6b98c)"""); } public override async Task ReadItem_with_single_explicit_discriminator_mapping() @@ -888,7 +912,7 @@ public override async Task ReadItem_with_single_explicit_discriminator_mapping() """ SELECT VALUE c FROM root c -WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND ((c["Id"] = 1) AND (c["$type"] = "SinglePartitionKeyEntity"))) +WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND ((c["Id"] = "b29bced8-e1e5-420e-82d7-1c7a51703d34") AND (c["$type"] = "SinglePartitionKeyEntity"))) OFFSET 0 LIMIT 2 """); } @@ -902,7 +926,7 @@ public override async Task ReadItem_with_single_explicit_incorrect_discriminator """ SELECT VALUE c FROM root c -WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND ((c["Id"] = 1) AND (c["$type"] = "DerivedSinglePartitionKeyEntity"))) +WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND ((c["Id"] = "b29bced8-e1e5-420e-82d7-1c7a51703d34") AND (c["$type"] = "DerivedSinglePartitionKeyEntity"))) """); } @@ -917,7 +941,7 @@ public override async Task ReadItem_with_single_explicit_parameterized_discrimin SELECT VALUE c FROM root c -WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND ((c["Id"] = 1) AND (c["$type"] = @__discriminator_0))) +WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND ((c["Id"] = "b29bced8-e1e5-420e-82d7-1c7a51703d34") AND (c["$type"] = @__discriminator_0))) OFFSET 0 LIMIT 2 """); } @@ -926,19 +950,18 @@ public override async Task ReadItem_with_single_explicit_discriminator_mapping_l { await base.ReadItem_with_single_explicit_discriminator_mapping_leaf(); - AssertSql("""ReadItem(["PK1"], DerivedSinglePartitionKeyEntity|11)"""); + AssertSql("""ReadItem(["PK1"], DerivedSinglePartitionKeyEntity|188d3253-81be-4a87-b58f-a2bd07e6b98c)"""); } public override async Task ReadItem_with_single_explicit_incorrect_discriminator_mapping_leaf() { await base.ReadItem_with_single_explicit_incorrect_discriminator_mapping_leaf(); - // No ReadItem because discriminator value is incorrect AssertSql( """ SELECT VALUE c FROM root c -WHERE ((c["$type"] = "DerivedSinglePartitionKeyEntity") AND ((c["Id"] = 11) AND (c["$type"] = "SinglePartitionKeyEntity"))) +WHERE ((c["$type"] = "DerivedSinglePartitionKeyEntity") AND ((c["Id"] = "188d3253-81be-4a87-b58f-a2bd07e6b98c") AND (c["$type"] = "SinglePartitionKeyEntity"))) """); } @@ -953,7 +976,7 @@ public override async Task ReadItem_with_single_explicit_parameterized_discrimin SELECT VALUE c FROM root c -WHERE ((c["$type"] = "DerivedSinglePartitionKeyEntity") AND ((c["Id"] = 11) AND (c["$type"] = @__discriminator_0))) +WHERE ((c["$type"] = "DerivedSinglePartitionKeyEntity") AND ((c["Id"] = "188d3253-81be-4a87-b58f-a2bd07e6b98c") AND (c["$type"] = @__discriminator_0))) OFFSET 0 LIMIT 2 """); } diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryFixtureBase.cs b/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryFixtureBase.cs index d5896ffb670..03740b7672c 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryFixtureBase.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryFixtureBase.cs @@ -305,33 +305,33 @@ public virtual IQueryable Set() private static List CreateHierarchicalPartitionKeyEntities() => new() { - new() + new HierarchicalPartitionKeyEntity { - Id = 1, + Id = Guid.Parse("31887258-BDF9-49B8-89B2-01B6AA741A4A"), PartitionKey1 = "PK1", PartitionKey2 = 1, PartitionKey3 = true, Payload = "Payload1" }, - new() + new HierarchicalPartitionKeyEntity { - Id = 1, + Id = Guid.Parse("31887258-BDF9-49B8-89B2-01B6AA741A4A"), // Same Id as previous; different partition. PartitionKey1 = "PK2", PartitionKey2 = 2, PartitionKey3 = false, Payload = "Payload2" }, - new() + new HierarchicalPartitionKeyEntity { - Id = 2, + Id = Guid.Parse("BBA46A5D-BDB8-40F0-BA80-BA5731147B9A"), // Different Id. PartitionKey1 = "PK1", PartitionKey2 = 1, PartitionKey3 = true, Payload = "Payload3" }, - new() + new HierarchicalPartitionKeyEntity { - Id = 2, + Id = Guid.Parse("BBA46A5D-BDB8-40F0-BA80-BA5731147B9A"), // Same Id as previous; different partition. PartitionKey1 = "PK2", PartitionKey2 = 2, PartitionKey3 = false, @@ -342,27 +342,27 @@ private static List CreateHierarchicalPartitionK private static List CreateSinglePartitionKeyEntities() => new() { - new() + new SinglePartitionKeyEntity { - Id = 1, + Id = Guid.Parse("B29BCED8-E1E5-420E-82D7-1C7A51703D34"), PartitionKey = "PK1", Payload = "Payload1" }, - new() + new SinglePartitionKeyEntity { - Id = 1, + Id = Guid.Parse("B29BCED8-E1E5-420E-82D7-1C7A51703D34"), PartitionKey = "PK2", Payload = "Payload2" }, - new() + new SinglePartitionKeyEntity { - Id = 2, + Id = Guid.Parse("3307A33B-7F28-49EF-9857-48F4E3EBCAED"), PartitionKey = "PK1", Payload = "Payload3" }, - new() + new SinglePartitionKeyEntity { - Id = 2, + Id = Guid.Parse("3307A33B-7F28-49EF-9857-48F4E3EBCAED"), PartitionKey = "PK2", Payload = "Payload4" } @@ -371,28 +371,28 @@ private static List CreateSinglePartitionKeyEntities() private static List CreateOnlyHierarchicalPartitionKeyEntities() => new() { - new() + new OnlyHierarchicalPartitionKeyEntity { PartitionKey1 = "PK1a", PartitionKey2 = 1, PartitionKey3 = true, Payload = "Payload1" }, - new() + new OnlyHierarchicalPartitionKeyEntity { PartitionKey1 = "PK2a", PartitionKey2 = 2, PartitionKey3 = false, Payload = "Payload2" }, - new() + new OnlyHierarchicalPartitionKeyEntity { PartitionKey1 = "PK1b", PartitionKey2 = 1, PartitionKey3 = true, Payload = "Payload3" }, - new() + new OnlyHierarchicalPartitionKeyEntity { PartitionKey1 = "PK2b", PartitionKey2 = 2, @@ -404,37 +404,40 @@ private static List CreateOnlyHierarchicalPa private static List CreateOnlySinglePartitionKeyEntities() => new() { - new() { PartitionKey = "PK1a", Payload = "Payload1" }, - new() { PartitionKey = "PK2a", Payload = "Payload2" }, - new() { PartitionKey = "PK1b", Payload = "Payload3" }, - new() { PartitionKey = "PK2b", Payload = "Payload4" } + new OnlySinglePartitionKeyEntity { PartitionKey = "PK1a", Payload = "Payload1" }, + new OnlySinglePartitionKeyEntity { PartitionKey = "PK2a", Payload = "Payload2" }, + new OnlySinglePartitionKeyEntity { PartitionKey = "PK1b", Payload = "Payload3" }, + new OnlySinglePartitionKeyEntity { PartitionKey = "PK2b", Payload = "Payload4" } }; private static List CreateNoPartitionKeyEntities() - => new() { new() { Id = 1, Payload = "Payload1" }, new() { Id = 2, Payload = "Payload2" } }; + => new() + { + new NoPartitionKeyEntity { Id = 1, Payload = "Payload1" }, new NoPartitionKeyEntity { Id = 2, Payload = "Payload2" } + }; private static List CreateSharedContainerEntities1() => new() { - new() + new SharedContainerEntity1 { Id = "1", PartitionKey = "PK1", Payload1 = "Payload1" }, - new() + new SharedContainerEntity1 { Id = "1", PartitionKey = "PK2", Payload1 = "Payload2" }, - new() + new SharedContainerEntity1 { Id = "2", PartitionKey = "PK1", Payload1 = "Payload3" }, - new() + new SharedContainerEntity1 { Id = "2", PartitionKey = "PK2", @@ -445,13 +448,13 @@ private static List CreateSharedContainerEntities1() private static List CreateSharedContainerEntities2() => new() { - new() + new SharedContainerEntity2 { Id = 4, PartitionKey = "PK1", Payload2 = "Payload4" }, - new() + new SharedContainerEntity2 { Id = 4, PartitionKey = "PK2", @@ -462,14 +465,14 @@ private static List CreateSharedContainerEntities2() private static List CreateSharedContainerEntities2Children() => new() { - new() + new SharedContainerEntity2Child { Id = 5, PartitionKey = "PK1", Payload2 = "Payload6", ChildPayload = "Child1" }, - new() + new SharedContainerEntity2Child { Id = 5, PartitionKey = "PK2", @@ -482,7 +485,7 @@ private static List CreateSharedContainerEntities2C public class HierarchicalPartitionKeyEntity { - public int Id { get; set; } + public Guid Id { get; set; } public required string PartitionKey1 { get; set; } public int PartitionKey2 { get; set; } @@ -493,7 +496,7 @@ public class HierarchicalPartitionKeyEntity public class SinglePartitionKeyEntity { - public int Id { get; set; } + public Guid Id { get; set; } public required string PartitionKey { get; set; } diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryInheritanceFixtureBase.cs b/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryInheritanceFixtureBase.cs index ecb401608a1..22a4e04521b 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryInheritanceFixtureBase.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryInheritanceFixtureBase.cs @@ -31,7 +31,6 @@ public ReadItemPartitionKeyQueryInheritanceFixtureBase() ((DerivedSinglePartitionKeyEntity?)a)?.DerivedPayload); }); - asserters[typeof(DerivedOnlyHierarchicalPartitionKeyEntity)] = new Action( (e, a) => @@ -112,7 +111,8 @@ public override IQueryable Set() if (typeof(TEntity) == typeof(DerivedOnlyHierarchicalPartitionKeyEntity)) { - return (IQueryable)OnlyHierarchicalPartitionKeyEntities.OfType().AsQueryable(); + return (IQueryable)OnlyHierarchicalPartitionKeyEntities.OfType() + .AsQueryable(); } if (typeof(TEntity) == typeof(DerivedOnlySinglePartitionKeyEntity)) @@ -131,36 +131,36 @@ public override IQueryable Set() private static List CreateDerivedHierarchicalPartitionKeyEntities() => new() { - new() + new DerivedHierarchicalPartitionKeyEntity { - Id = 11, + Id = Guid.Parse("316C846C-787F-44B9-AADF-272F1658C5FF"), PartitionKey1 = "PK1", PartitionKey2 = 1, PartitionKey3 = true, Payload = "Payload1", DerivedPayload = "DerivedPayload1" }, - new() + new DerivedHierarchicalPartitionKeyEntity { - Id = 11, + Id = Guid.Parse("316C846C-787F-44B9-AADF-272F1658C5FF"), // Same Id as previous; different partition. PartitionKey1 = "PK2", PartitionKey2 = 2, PartitionKey3 = false, Payload = "Payload2", DerivedPayload = "DerivedPayload2" }, - new() + new DerivedHierarchicalPartitionKeyEntity { - Id = 22, + Id = Guid.Parse("C6E8E6D2-F33E-4695-9FA5-D0E9517EF04E"), // New Id. PartitionKey1 = "PK1", PartitionKey2 = 1, PartitionKey3 = true, Payload = "Payload3", DerivedPayload = "DerivedPayload3" }, - new() + new DerivedHierarchicalPartitionKeyEntity { - Id = 22, + Id = Guid.Parse("C6E8E6D2-F33E-4695-9FA5-D0E9517EF04E"), // Same Id as previous; different partition. PartitionKey1 = "PK2", PartitionKey2 = 2, PartitionKey3 = false, @@ -172,30 +172,30 @@ private static List CreateDerivedHierarch private static List CreateDerivedSinglePartitionKeyEntities() => new() { - new() + new DerivedSinglePartitionKeyEntity { - Id = 11, + Id = Guid.Parse("188D3253-81BE-4A87-B58F-A2BD07E6B98C"), PartitionKey = "PK1", Payload = "Payload1", DerivedPayload = "DerivedPayload1" }, - new() + new DerivedSinglePartitionKeyEntity { - Id = 11, + Id = Guid.Parse("188D3253-81BE-4A87-B58F-A2BD07E6B98C"), PartitionKey = "PK2", Payload = "Payload2", DerivedPayload = "DerivedPayload2" }, - new() + new DerivedSinglePartitionKeyEntity { - Id = 22, + Id = Guid.Parse("11F8D1FD-7472-46F5-9E20-16AF42B3B8D1"), PartitionKey = "PK1", Payload = "Payload3", DerivedPayload = "DerivedPayload3" }, - new() + new DerivedSinglePartitionKeyEntity { - Id = 22, + Id = Guid.Parse("11F8D1FD-7472-46F5-9E20-16AF42B3B8D1"), PartitionKey = "PK2", Payload = "Payload4", DerivedPayload = "DerivedPayload4" @@ -205,7 +205,7 @@ private static List CreateDerivedSinglePartitio private static List CreateDerivedOnlyHierarchicalPartitionKeyEntities() => new() { - new() + new DerivedOnlyHierarchicalPartitionKeyEntity { PartitionKey1 = "PK1c", PartitionKey2 = 1, @@ -213,7 +213,7 @@ private static List CreateDerivedOnly Payload = "Payload1", DerivedPayload = "DerivedPayload1" }, - new() + new DerivedOnlyHierarchicalPartitionKeyEntity { PartitionKey1 = "PK2c", PartitionKey2 = 2, @@ -221,7 +221,7 @@ private static List CreateDerivedOnly Payload = "Payload2", DerivedPayload = "DerivedPayload2" }, - new() + new DerivedOnlyHierarchicalPartitionKeyEntity { PartitionKey1 = "PK1d", PartitionKey2 = 1, @@ -229,7 +229,7 @@ private static List CreateDerivedOnly Payload = "Payload3", DerivedPayload = "DerivedPayload3" }, - new() + new DerivedOnlyHierarchicalPartitionKeyEntity { PartitionKey1 = "PK2d", PartitionKey2 = 2, @@ -242,25 +242,25 @@ private static List CreateDerivedOnly private static List CreateDerivedOnlySinglePartitionKeyEntities() => new() { - new() + new DerivedOnlySinglePartitionKeyEntity { PartitionKey = "PK1c", Payload = "Payload1", DerivedPayload = "DerivedPayload1" }, - new() + new DerivedOnlySinglePartitionKeyEntity { PartitionKey = "PK2c", Payload = "Payload2", DerivedPayload = "DerivedPayload2" }, - new() + new DerivedOnlySinglePartitionKeyEntity { PartitionKey = "PK1d", Payload = "Payload3", DerivedPayload = "DerivedPayload3" }, - new() + new DerivedOnlySinglePartitionKeyEntity { PartitionKey = "PK2d", Payload = "Payload4", @@ -271,13 +271,13 @@ private static List CreateDerivedOnlySingle private static List CreateDerivedNoPartitionKeyEntities() => new() { - new() + new DerivedNoPartitionKeyEntity { Id = 11, Payload = "Payload1", DerivedPayload = "DerivedPayload1" }, - new() + new DerivedNoPartitionKeyEntity { Id = 22, Payload = "Payload2", diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryInheritanceTestBase.cs b/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryInheritanceTestBase.cs index a3192ebd864..b8c5378f9c5 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryInheritanceTestBase.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryInheritanceTestBase.cs @@ -108,17 +108,11 @@ public virtual Task WithPartitionKey_with_only_single_partition_key_leaf() ss => ss.Set().Where(e => e.PartitionKey == "PK1c")); [ConditionalFact] - public virtual async Task WithPartitionKey_with_missing_value_in_hierarchical_partition_key_leaf() - { - var message = await Assert.ThrowsAsync( - () => AssertQuery( - async: true, - ss => ss.Set().WithPartitionKey("PK1", 1), - ss => ss.Set() - .Where(e => e.PartitionKey1 == "PK1" && e.PartitionKey2 == 1 && e.PartitionKey3))); - - Assert.Equal(CosmosStrings.IncorrectPartitionKeyNumber(nameof(DerivedHierarchicalPartitionKeyEntity), 2, 3), message.Message); - } + public virtual Task WithPartitionKey_with_partial_value_in_hierarchical_partition_key_leaf() + => AssertQuery( + async: true, + ss => ss.Set().WithPartitionKey("PK1", 1), + ss => ss.Set().Where(e => e.PartitionKey1 == "PK1" && e.PartitionKey2 == 1)); [ConditionalFact] public virtual Task Both_WithPartitionKey_and_predicate_comparisons_with_different_values_leaf() @@ -160,7 +154,11 @@ public virtual Task ReadItem_with_hierarchical_partition_key_leaf() return AssertQuery( async: true, ss => ss.Set() - .Where(e => e.Id == 11 && e.PartitionKey1 == "PK1" && e.PartitionKey2 == partitionKey2 && e.PartitionKey3)); + .Where( + e => e.Id == Guid.Parse("316C846C-787F-44B9-AADF-272F1658C5FF") + && e.PartitionKey1 == "PK1" + && e.PartitionKey2 == partitionKey2 + && e.PartitionKey3)); } [ConditionalFact] @@ -178,7 +176,8 @@ public virtual Task ReadItem_with_only_hierarchical_partition_key_leaf() public virtual Task ReadItem_with_single_partition_key_constant_leaf() => AssertQuery( async: true, - ss => ss.Set().Where(e => e.Id == 11 && e.PartitionKey == "PK1")); + ss => ss.Set() + .Where(e => e.Id == Guid.Parse("188D3253-81BE-4A87-B58F-A2BD07E6B98C") && e.PartitionKey == "PK1")); [ConditionalFact] public virtual Task ReadItem_with_only_single_partition_key_constant_leaf() @@ -193,7 +192,8 @@ public virtual Task ReadItem_with_single_partition_key_parameter_leaf() return AssertQuery( async: true, - ss => ss.Set().Where(e => e.Id == 11 && e.PartitionKey == partitionKey)); + ss => ss.Set().Where( + e => e.Id == Guid.Parse("188D3253-81BE-4A87-B58F-A2BD07E6B98C") && e.PartitionKey == partitionKey)); } [ConditionalFact] @@ -213,7 +213,8 @@ public virtual Task ReadItem_with_SingleAsync_leaf() return AssertSingle( async: true, - ss => ss.Set().Where(e => e.Id == 11 && e.PartitionKey == partitionKey)); + ss => ss.Set().Where( + e => e.Id == Guid.Parse("188D3253-81BE-4A87-B58F-A2BD07E6B98C") && e.PartitionKey == partitionKey)); } [ConditionalFact] @@ -230,7 +231,8 @@ public virtual Task ReadItem_with_SingleAsync_with_only_partition_key_leaf() public virtual Task ReadItem_with_inverse_comparison_leaf() => AssertQuery( async: true, - ss => ss.Set().Where(e => 11 == e.Id && "PK1" == e.PartitionKey)); + ss => ss.Set() + .Where(e => Guid.Parse("188D3253-81BE-4A87-B58F-A2BD07E6B98C") == e.Id && "PK1" == e.PartitionKey)); [ConditionalFact] public virtual Task ReadItem_with_inverse_comparison_with_only_partition_key_leaf() @@ -243,15 +245,17 @@ public virtual Task ReadItem_with_EF_Property_leaf() => AssertQuery( async: true, ss => ss.Set().Where( - e => EF.Property(e, nameof(DerivedSinglePartitionKeyEntity.Id)) == 11 + e => EF.Property(e, nameof(DerivedSinglePartitionKeyEntity.Id)) == Guid.Parse("188D3253-81BE-4A87-B58F-A2BD07E6B98C") && EF.Property(e, nameof(DerivedSinglePartitionKeyEntity.PartitionKey)) == "PK1")); [ConditionalFact] public virtual Task ReadItem_with_WithPartitionKey_leaf() => AssertQuery( async: true, - ss => ss.Set().WithPartitionKey("PK1").Where(e => e.Id == 11), - ss => ss.Set().Where(e => e.PartitionKey == "PK1").Where(e => e.Id == 11)); + ss => ss.Set().WithPartitionKey("PK1") + .Where(e => e.Id == Guid.Parse("188D3253-81BE-4A87-B58F-A2BD07E6B98C")), + ss => ss.Set().Where(e => e.PartitionKey == "PK1") + .Where(e => e.Id == Guid.Parse("188D3253-81BE-4A87-B58F-A2BD07E6B98C"))); [ConditionalFact] public virtual Task ReadItem_with_WithPartitionKey_with_only_partition_key_leaf() @@ -267,7 +271,7 @@ public virtual Task Multiple_incompatible_predicate_comparisons_cause_no_ReadIte return AssertQuery( async: true, - ss => ss.Set().Where(e => e.Id == 11 && e.Id == 22 && e.PartitionKey == partitionKey), + ss => ss.Set().Where(e => e.Id == Guid.Parse("188D3253-81BE-4A87-B58F-A2BD07E6B98C") && e.Id == Guid.Parse("11F8D1FD-7472-46F5-9E20-16AF42B3B8D1") && e.PartitionKey == partitionKey), assertEmpty: true); } @@ -293,27 +297,29 @@ public virtual Task ReadItem_with_no_partition_key_leaf() public virtual Task ReadItem_is_not_used_without_partition_key_leaf() => AssertQuery( async: true, - ss => ss.Set().Where(e => e.Id == 11)); + ss => ss.Set().Where(e => e.Id == Guid.Parse("188D3253-81BE-4A87-B58F-A2BD07E6B98C"))); [ConditionalFact] public virtual Task ReadItem_with_non_existent_id_leaf() => AssertQuery( async: true, - ss => ss.Set().Where(e => e.Id == 999 && e.PartitionKey == "PK1"), + ss => ss.Set() + .Where(e => e.Id == Guid.Parse("B964BEDA-B4E1-4F5C-A729-0A35DAE696FE") && e.PartitionKey == "PK1"), assertEmpty: true); [ConditionalFact] public virtual Task ReadItem_with_AsNoTracking_leaf() => AssertQuery( async: true, - ss => ss.Set().AsNoTracking().Where(e => e.Id == 11 && e.PartitionKey == "PK1")); + ss => ss.Set().AsNoTracking().Where( + e => e.Id == Guid.Parse("188D3253-81BE-4A87-B58F-A2BD07E6B98C") && e.PartitionKey == "PK1")); [ConditionalFact] public virtual Task ReadItem_with_AsNoTrackingWithIdentityResolution_leaf() => AssertQuery( async: true, ss => ss.Set().AsNoTrackingWithIdentityResolution() - .Where(e => e.Id == 11 && e.PartitionKey == "PK1")); + .Where(e => e.Id == Guid.Parse("188D3253-81BE-4A87-B58F-A2BD07E6B98C") && e.PartitionKey == "PK1")); [ConditionalFact] public virtual Task ReadItem_with_single_explicit_discriminator_mapping_leaf() @@ -324,11 +330,11 @@ public virtual Task ReadItem_with_single_explicit_discriminator_mapping_leaf() async: true, ss => ss.Set() .Where( - e => e.Id == 11 + e => e.Id == Guid.Parse("188D3253-81BE-4A87-B58F-A2BD07E6B98C") && EF.Property(e, "$type") == nameof(DerivedSinglePartitionKeyEntity) && e.PartitionKey == partitionKey), ss => ss.Set() - .Where(e => e.Id == 11 && e.PartitionKey == partitionKey)); + .Where(e => e.Id == Guid.Parse("188D3253-81BE-4A87-B58F-A2BD07E6B98C") && e.PartitionKey == partitionKey)); } [ConditionalFact] @@ -340,7 +346,7 @@ public virtual Task ReadItem_with_single_explicit_incorrect_discriminator_mappin async: true, ss => ss.Set() .Where( - e => e.Id == 11 + e => e.Id == Guid.Parse("188D3253-81BE-4A87-B58F-A2BD07E6B98C") && EF.Property(e, "$type") == nameof(SinglePartitionKeyEntity) && e.PartitionKey == partitionKey), ss => ss.Set().Where(e => false), @@ -356,7 +362,11 @@ public virtual Task ReadItem_with_single_explicit_parameterized_discriminator_ma return AssertSingle( async: true, ss => ss.Set() - .Where(e => e.Id == 11 && EF.Property(e, "$type") == discriminator && e.PartitionKey == partitionKey), - ss => ss.Set().Where(e => e.Id == 11 && e.PartitionKey == partitionKey)); + .Where( + e => e.Id == Guid.Parse("188D3253-81BE-4A87-B58F-A2BD07E6B98C") + && EF.Property(e, "$type") == discriminator + && e.PartitionKey == partitionKey), + ss => ss.Set().Where( + e => e.Id == Guid.Parse("188D3253-81BE-4A87-B58F-A2BD07E6B98C") && e.PartitionKey == partitionKey)); } } diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryNoDiscriminatorInIdTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryNoDiscriminatorInIdTest.cs index 3257a0cb567..14376779590 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryNoDiscriminatorInIdTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryNoDiscriminatorInIdTest.cs @@ -66,7 +66,20 @@ public override async Task Predicate_with_partial_values_in_hierarchical_partiti """ SELECT VALUE c FROM root c -WHERE (c["$type"] IN ("HierarchicalPartitionKeyEntity", "DerivedHierarchicalPartitionKeyEntity") AND ((c["PartitionKey1"] = "PK1") AND (c["PartitionKey2"] = 1))) +WHERE c["$type"] IN ("HierarchicalPartitionKeyEntity", "DerivedHierarchicalPartitionKeyEntity") +"""); + } + + public override async Task Predicate_with_partial_values_and_gap_in_hierarchical_partition_key() + { + await base.Predicate_with_partial_values_and_gap_in_hierarchical_partition_key(); + + // Not ReadItem because no primary key value + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE (c["$type"] IN ("HierarchicalPartitionKeyEntity", "DerivedHierarchicalPartitionKeyEntity") AND c["PartitionKey3"]) """); } @@ -79,7 +92,7 @@ public override async Task Predicate_with_partial_values_in_only_hierarchical_pa """ SELECT VALUE c FROM root c -WHERE (c["$type"] IN ("OnlyHierarchicalPartitionKeyEntity", "DerivedOnlyHierarchicalPartitionKeyEntity") AND ((c["PartitionKey1"] = "PK1a") AND (c["PartitionKey2"] = 1))) +WHERE c["$type"] IN ("OnlyHierarchicalPartitionKeyEntity", "DerivedOnlyHierarchicalPartitionKeyEntity") """); } @@ -161,11 +174,16 @@ FROM root c """); } - public override async Task WithPartitionKey_with_missing_value_in_hierarchical_partition_key() + public override async Task WithPartitionKey_with_partial_value_in_hierarchical_partition_key() { - await base.WithPartitionKey_with_missing_value_in_hierarchical_partition_key(); + await base.WithPartitionKey_with_partial_value_in_hierarchical_partition_key(); - AssertSql(); + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE c["$type"] IN ("HierarchicalPartitionKeyEntity", "DerivedHierarchicalPartitionKeyEntity") +"""); } public override async Task Both_WithPartitionKey_and_predicate_comparisons_with_different_values() @@ -218,7 +236,7 @@ public override async Task ReadItem_with_hierarchical_partition_key() { await base.ReadItem_with_hierarchical_partition_key(); - AssertSql("""ReadItem(["PK1",1.0,true], 1)"""); + AssertSql("""ReadItem(["PK1",1.0,true], 31887258-bdf9-49b8-89b2-01b6aa741a4a)"""); } public override async Task ReadItem_with_only_hierarchical_partition_key() @@ -232,7 +250,7 @@ public override async Task ReadItem_with_single_partition_key_constant() { await base.ReadItem_with_single_partition_key_constant(); - AssertSql("""ReadItem(["PK1"], 1)"""); + AssertSql("""ReadItem(["PK1"], b29bced8-e1e5-420e-82d7-1c7a51703d34)"""); } public override async Task ReadItem_with_only_single_partition_key_constant() @@ -246,7 +264,7 @@ public override async Task ReadItem_with_single_partition_key_parameter() { await base.ReadItem_with_single_partition_key_parameter(); - AssertSql("""ReadItem(["PK1"], 1)"""); + AssertSql("""ReadItem(["PK1"], b29bced8-e1e5-420e-82d7-1c7a51703d34)"""); } public override async Task ReadItem_with_only_single_partition_key_parameter() @@ -260,7 +278,7 @@ public override async Task ReadItem_with_SingleAsync() { await base.ReadItem_with_SingleAsync(); - AssertSql("""ReadItem(["PK1"], 1)"""); + AssertSql("""ReadItem(["PK1"], b29bced8-e1e5-420e-82d7-1c7a51703d34)"""); } public override async Task ReadItem_with_SingleAsync_with_only_partition_key() @@ -274,7 +292,7 @@ public override async Task ReadItem_with_inverse_comparison() { await base.ReadItem_with_inverse_comparison(); - AssertSql("""ReadItem(["PK1"], 1)"""); + AssertSql("""ReadItem(["PK1"], b29bced8-e1e5-420e-82d7-1c7a51703d34)"""); } public override async Task ReadItem_with_inverse_comparison_with_only_partition_key() @@ -288,14 +306,14 @@ public override async Task ReadItem_with_EF_Property() { await base.ReadItem_with_EF_Property(); - AssertSql("""ReadItem(["PK1"], 1)"""); + AssertSql("""ReadItem(["PK1"], b29bced8-e1e5-420e-82d7-1c7a51703d34)"""); } public override async Task ReadItem_with_WithPartitionKey() { await base.ReadItem_with_WithPartitionKey(); - AssertSql("""ReadItem(["PK1"], 1)"""); + AssertSql("""ReadItem(["PK1"], b29bced8-e1e5-420e-82d7-1c7a51703d34)"""); } public override async Task ReadItem_with_WithPartitionKey_with_only_partition_key() @@ -314,7 +332,7 @@ public override async Task Multiple_incompatible_predicate_comparisons_cause_no_ """ SELECT VALUE c FROM root c -WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND ((c["Id"] = 1) AND (c["Id"] = 2))) +WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND ((c["id"] = "b29bced8-e1e5-420e-82d7-1c7a51703d34") AND (c["id"] = "3307a33b-7f28-49ef-9857-48f4e3ebcaed"))) """); } @@ -348,7 +366,7 @@ public override async Task ReadItem_is_not_used_without_partition_key() """ SELECT VALUE c FROM root c -WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND (c["Id"] = 1)) +WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND (c["id"] = "b29bced8-e1e5-420e-82d7-1c7a51703d34")) """); } @@ -356,21 +374,21 @@ public override async Task ReadItem_with_non_existent_id() { await base.ReadItem_with_non_existent_id(); - AssertSql("""ReadItem(["PK1"], 999)"""); + AssertSql("""ReadItem(["PK1"], 50b66960-35be-40c5-bc3d-4c9f2799d4d1)"""); } public override async Task ReadItem_with_AsNoTracking() { await base.ReadItem_with_AsNoTracking(); - AssertSql("""ReadItem(["PK1"], 1)"""); + AssertSql("""ReadItem(["PK1"], b29bced8-e1e5-420e-82d7-1c7a51703d34)"""); } public override async Task ReadItem_with_AsNoTrackingWithIdentityResolution() { await base.ReadItem_with_AsNoTrackingWithIdentityResolution(); - AssertSql("""ReadItem(["PK1"], 1)"""); + AssertSql("""ReadItem(["PK1"], b29bced8-e1e5-420e-82d7-1c7a51703d34)"""); } public override async Task ReadItem_with_shared_container() @@ -394,7 +412,6 @@ public override async Task ReadItem_for_child_type_with_shared_container() AssertSql("""ReadItem(["PK2"], 5)"""); } - public override async Task Predicate_with_hierarchical_partition_key_leaf() { await base.Predicate_with_hierarchical_partition_key_leaf(); @@ -444,7 +461,7 @@ public override async Task Predicate_with_partial_values_in_hierarchical_partiti """ SELECT VALUE c FROM root c -WHERE ((c["$type"] = "DerivedHierarchicalPartitionKeyEntity") AND ((c["PartitionKey1"] = "PK1") AND (c["PartitionKey2"] = 1))) +WHERE (c["$type"] = "DerivedHierarchicalPartitionKeyEntity") """); } @@ -457,7 +474,7 @@ public override async Task Predicate_with_partial_values_in_only_hierarchical_pa """ SELECT VALUE c FROM root c -WHERE ((c["$type"] = "DerivedOnlyHierarchicalPartitionKeyEntity") AND ((c["PartitionKey1"] = "PK1c") AND (c["PartitionKey2"] = 1))) +WHERE (c["$type"] = "DerivedOnlyHierarchicalPartitionKeyEntity") """); } @@ -539,11 +556,16 @@ FROM root c """); } - public override async Task WithPartitionKey_with_missing_value_in_hierarchical_partition_key_leaf() + public override async Task WithPartitionKey_with_partial_value_in_hierarchical_partition_key_leaf() { - await base.WithPartitionKey_with_missing_value_in_hierarchical_partition_key_leaf(); + await base.WithPartitionKey_with_partial_value_in_hierarchical_partition_key_leaf(); - AssertSql(); + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE (c["$type"] = "DerivedHierarchicalPartitionKeyEntity") +"""); } public override async Task Both_WithPartitionKey_and_predicate_comparisons_with_different_values_leaf() @@ -596,7 +618,7 @@ public override async Task ReadItem_with_hierarchical_partition_key_leaf() { await base.ReadItem_with_hierarchical_partition_key_leaf(); - AssertSql("""ReadItem(["PK1",1.0,true], 11)"""); + AssertSql("""ReadItem(["PK1",1.0,true], 316c846c-787f-44b9-aadf-272f1658c5ff)"""); } public override async Task ReadItem_with_only_hierarchical_partition_key_leaf() @@ -610,7 +632,7 @@ public override async Task ReadItem_with_single_partition_key_constant_leaf() { await base.ReadItem_with_single_partition_key_constant_leaf(); - AssertSql("""ReadItem(["PK1"], 11)"""); + AssertSql("""ReadItem(["PK1"], 188d3253-81be-4a87-b58f-a2bd07e6b98c)"""); } public override async Task ReadItem_with_only_single_partition_key_constant_leaf() @@ -624,7 +646,7 @@ public override async Task ReadItem_with_single_partition_key_parameter_leaf() { await base.ReadItem_with_single_partition_key_parameter_leaf(); - AssertSql("""ReadItem(["PK1"], 11)"""); + AssertSql("""ReadItem(["PK1"], 188d3253-81be-4a87-b58f-a2bd07e6b98c)"""); } public override async Task ReadItem_with_only_single_partition_key_parameter_leaf() @@ -638,7 +660,7 @@ public override async Task ReadItem_with_SingleAsync_leaf() { await base.ReadItem_with_SingleAsync_leaf(); - AssertSql("""ReadItem(["PK1"], 11)"""); + AssertSql("""ReadItem(["PK1"], 188d3253-81be-4a87-b58f-a2bd07e6b98c)"""); } public override async Task ReadItem_with_SingleAsync_with_only_partition_key_leaf() @@ -652,7 +674,7 @@ public override async Task ReadItem_with_inverse_comparison_leaf() { await base.ReadItem_with_inverse_comparison_leaf(); - AssertSql("""ReadItem(["PK1"], 11)"""); + AssertSql("""ReadItem(["PK1"], 188d3253-81be-4a87-b58f-a2bd07e6b98c)"""); } public override async Task ReadItem_with_inverse_comparison_with_only_partition_key_leaf() @@ -666,14 +688,14 @@ public override async Task ReadItem_with_EF_Property_leaf() { await base.ReadItem_with_EF_Property_leaf(); - AssertSql("""ReadItem(["PK1"], 11)"""); + AssertSql("""ReadItem(["PK1"], 188d3253-81be-4a87-b58f-a2bd07e6b98c)"""); } public override async Task ReadItem_with_WithPartitionKey_leaf() { await base.ReadItem_with_WithPartitionKey_leaf(); - AssertSql("""ReadItem(["PK1"], 11)"""); + AssertSql("""ReadItem(["PK1"], 188d3253-81be-4a87-b58f-a2bd07e6b98c)"""); } public override async Task ReadItem_with_WithPartitionKey_with_only_partition_key_leaf() @@ -692,7 +714,7 @@ public override async Task Multiple_incompatible_predicate_comparisons_cause_no_ """ SELECT VALUE c FROM root c -WHERE ((c["$type"] = "DerivedSinglePartitionKeyEntity") AND ((c["Id"] = 11) AND (c["Id"] = 22))) +WHERE ((c["$type"] = "DerivedSinglePartitionKeyEntity") AND ((c["id"] = "188d3253-81be-4a87-b58f-a2bd07e6b98c") AND (c["id"] = "11f8d1fd-7472-46f5-9e20-16af42b3b8d1"))) """); } @@ -726,7 +748,7 @@ public override async Task ReadItem_is_not_used_without_partition_key_leaf() """ SELECT VALUE c FROM root c -WHERE ((c["$type"] = "DerivedSinglePartitionKeyEntity") AND (c["Id"] = 11)) +WHERE ((c["$type"] = "DerivedSinglePartitionKeyEntity") AND (c["id"] = "188d3253-81be-4a87-b58f-a2bd07e6b98c")) """); } @@ -734,39 +756,39 @@ public override async Task ReadItem_with_non_existent_id_leaf() { await base.ReadItem_with_non_existent_id_leaf(); - AssertSql("""ReadItem(["PK1"], 999)"""); + AssertSql("""ReadItem(["PK1"], b964beda-b4e1-4f5c-a729-0a35dae696fe)"""); } public override async Task ReadItem_with_AsNoTracking_leaf() { await base.ReadItem_with_AsNoTracking_leaf(); - AssertSql("""ReadItem(["PK1"], 11)"""); + AssertSql("""ReadItem(["PK1"], 188d3253-81be-4a87-b58f-a2bd07e6b98c)"""); } public override async Task ReadItem_with_AsNoTrackingWithIdentityResolution_leaf() { await base.ReadItem_with_AsNoTrackingWithIdentityResolution_leaf(); - AssertSql("""ReadItem(["PK1"], 11)"""); + AssertSql("""ReadItem(["PK1"], 188d3253-81be-4a87-b58f-a2bd07e6b98c)"""); } public override async Task ReadItem_with_single_explicit_discriminator_mapping() { await base.ReadItem_with_single_explicit_discriminator_mapping(); - AssertSql("""ReadItem(["PK1"], 1)"""); + AssertSql("""ReadItem(["PK1"], b29bced8-e1e5-420e-82d7-1c7a51703d34)"""); } + public override async Task ReadItem_with_single_explicit_incorrect_discriminator_mapping() { await base.ReadItem_with_single_explicit_incorrect_discriminator_mapping(); - // No ReadItem because discriminator value is incorrect AssertSql( """ SELECT VALUE c FROM root c -WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND ((c["Id"] = 1) AND (c["$type"] = "DerivedSinglePartitionKeyEntity"))) +WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND ((c["id"] = "b29bced8-e1e5-420e-82d7-1c7a51703d34") AND (c["$type"] = "DerivedSinglePartitionKeyEntity"))) """); } @@ -774,14 +796,13 @@ public override async Task ReadItem_with_single_explicit_parameterized_discrimin { await base.ReadItem_with_single_explicit_parameterized_discriminator_mapping(); - // No ReadItem because discriminator check is parameterized AssertSql( """ @__discriminator_0='SinglePartitionKeyEntity' SELECT VALUE c FROM root c -WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND ((c["Id"] = 1) AND (c["$type"] = @__discriminator_0))) +WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND ((c["id"] = "b29bced8-e1e5-420e-82d7-1c7a51703d34") AND (c["$type"] = @__discriminator_0))) OFFSET 0 LIMIT 2 """); } @@ -790,7 +811,7 @@ public override async Task ReadItem_with_single_explicit_discriminator_mapping_l { await base.ReadItem_with_single_explicit_discriminator_mapping_leaf(); - AssertSql("""ReadItem(["PK1"], 11)"""); + AssertSql("""ReadItem(["PK1"], 188d3253-81be-4a87-b58f-a2bd07e6b98c)"""); } public override async Task ReadItem_with_single_explicit_incorrect_discriminator_mapping_leaf() @@ -802,7 +823,7 @@ public override async Task ReadItem_with_single_explicit_incorrect_discriminator """ SELECT VALUE c FROM root c -WHERE ((c["$type"] = "DerivedSinglePartitionKeyEntity") AND ((c["Id"] = 11) AND (c["$type"] = "SinglePartitionKeyEntity"))) +WHERE ((c["$type"] = "DerivedSinglePartitionKeyEntity") AND ((c["id"] = "188d3253-81be-4a87-b58f-a2bd07e6b98c") AND (c["$type"] = "SinglePartitionKeyEntity"))) """); } @@ -817,7 +838,7 @@ public override async Task ReadItem_with_single_explicit_parameterized_discrimin SELECT VALUE c FROM root c -WHERE ((c["$type"] = "DerivedSinglePartitionKeyEntity") AND ((c["Id"] = 11) AND (c["$type"] = @__discriminator_0))) +WHERE ((c["$type"] = "DerivedSinglePartitionKeyEntity") AND ((c["id"] = "188d3253-81be-4a87-b58f-a2bd07e6b98c") AND (c["$type"] = @__discriminator_0))) OFFSET 0 LIMIT 2 """); } diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryRootDiscriminatorInIdTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryRootDiscriminatorInIdTest.cs index ef9ddfb5cde..ca992cf55da 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryRootDiscriminatorInIdTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryRootDiscriminatorInIdTest.cs @@ -66,7 +66,20 @@ public override async Task Predicate_with_partial_values_in_hierarchical_partiti """ SELECT VALUE c FROM root c -WHERE (c["$type"] IN ("HierarchicalPartitionKeyEntity", "DerivedHierarchicalPartitionKeyEntity") AND ((c["PartitionKey1"] = "PK1") AND (c["PartitionKey2"] = 1))) +WHERE c["$type"] IN ("HierarchicalPartitionKeyEntity", "DerivedHierarchicalPartitionKeyEntity") +"""); + } + + public override async Task Predicate_with_partial_values_and_gap_in_hierarchical_partition_key() + { + await base.Predicate_with_partial_values_and_gap_in_hierarchical_partition_key(); + + // Not ReadItem because no primary key value + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE (c["$type"] IN ("HierarchicalPartitionKeyEntity", "DerivedHierarchicalPartitionKeyEntity") AND c["PartitionKey3"]) """); } @@ -79,7 +92,7 @@ public override async Task Predicate_with_partial_values_in_only_hierarchical_pa """ SELECT VALUE c FROM root c -WHERE (c["$type"] IN ("OnlyHierarchicalPartitionKeyEntity", "DerivedOnlyHierarchicalPartitionKeyEntity") AND ((c["PartitionKey1"] = "PK1a") AND (c["PartitionKey2"] = 1))) +WHERE c["$type"] IN ("OnlyHierarchicalPartitionKeyEntity", "DerivedOnlyHierarchicalPartitionKeyEntity") """); } @@ -163,11 +176,16 @@ FROM root c """); } - public override async Task WithPartitionKey_with_missing_value_in_hierarchical_partition_key() + public override async Task WithPartitionKey_with_partial_value_in_hierarchical_partition_key() { - await base.WithPartitionKey_with_missing_value_in_hierarchical_partition_key(); + await base.WithPartitionKey_with_partial_value_in_hierarchical_partition_key(); - AssertSql(); + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE c["$type"] IN ("HierarchicalPartitionKeyEntity", "DerivedHierarchicalPartitionKeyEntity") +"""); } public override async Task Both_WithPartitionKey_and_predicate_comparisons_with_different_values() @@ -220,7 +238,7 @@ public override async Task ReadItem_with_hierarchical_partition_key() { await base.ReadItem_with_hierarchical_partition_key(); - AssertSql("""ReadItem(["PK1",1.0,true], HierarchicalPartitionKeyEntity|1)"""); + AssertSql("""ReadItem(["PK1",1.0,true], HierarchicalPartitionKeyEntity|31887258-bdf9-49b8-89b2-01b6aa741a4a)"""); } public override async Task ReadItem_with_only_hierarchical_partition_key() @@ -234,7 +252,7 @@ public override async Task ReadItem_with_single_partition_key_constant() { await base.ReadItem_with_single_partition_key_constant(); - AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|1)"""); + AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|b29bced8-e1e5-420e-82d7-1c7a51703d34)"""); } public override async Task ReadItem_with_only_single_partition_key_constant() @@ -248,7 +266,7 @@ public override async Task ReadItem_with_single_partition_key_parameter() { await base.ReadItem_with_single_partition_key_parameter(); - AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|1)"""); + AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|b29bced8-e1e5-420e-82d7-1c7a51703d34)"""); } public override async Task ReadItem_with_only_single_partition_key_parameter() @@ -262,7 +280,7 @@ public override async Task ReadItem_with_SingleAsync() { await base.ReadItem_with_SingleAsync(); - AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|1)"""); + AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|b29bced8-e1e5-420e-82d7-1c7a51703d34)"""); } public override async Task ReadItem_with_SingleAsync_with_only_partition_key() @@ -276,7 +294,7 @@ public override async Task ReadItem_with_inverse_comparison() { await base.ReadItem_with_inverse_comparison(); - AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|1)"""); + AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|b29bced8-e1e5-420e-82d7-1c7a51703d34)"""); } public override async Task ReadItem_with_inverse_comparison_with_only_partition_key() @@ -290,14 +308,14 @@ public override async Task ReadItem_with_EF_Property() { await base.ReadItem_with_EF_Property(); - AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|1)"""); + AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|b29bced8-e1e5-420e-82d7-1c7a51703d34)"""); } public override async Task ReadItem_with_WithPartitionKey() { await base.ReadItem_with_WithPartitionKey(); - AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|1)"""); + AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|b29bced8-e1e5-420e-82d7-1c7a51703d34)"""); } public override async Task ReadItem_with_WithPartitionKey_with_only_partition_key() @@ -316,11 +334,10 @@ public override async Task Multiple_incompatible_predicate_comparisons_cause_no_ """ SELECT VALUE c FROM root c -WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND ((c["Id"] = 1) AND (c["Id"] = 2))) +WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND ((c["Id"] = "b29bced8-e1e5-420e-82d7-1c7a51703d34") AND (c["Id"] = "3307a33b-7f28-49ef-9857-48f4e3ebcaed"))) """); } - public override async Task Multiple_incompatible_predicate_comparisons_cause_no_ReadItem_with_only_partition_key() { await base.Multiple_incompatible_predicate_comparisons_cause_no_ReadItem_with_only_partition_key(); @@ -351,7 +368,7 @@ public override async Task ReadItem_is_not_used_without_partition_key() """ SELECT VALUE c FROM root c -WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND (c["Id"] = 1)) +WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND (c["Id"] = "b29bced8-e1e5-420e-82d7-1c7a51703d34")) """); } @@ -359,21 +376,21 @@ public override async Task ReadItem_with_non_existent_id() { await base.ReadItem_with_non_existent_id(); - AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|999)"""); + AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|50b66960-35be-40c5-bc3d-4c9f2799d4d1)"""); } public override async Task ReadItem_with_AsNoTracking() { await base.ReadItem_with_AsNoTracking(); - AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|1)"""); + AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|b29bced8-e1e5-420e-82d7-1c7a51703d34)"""); } public override async Task ReadItem_with_AsNoTrackingWithIdentityResolution() { await base.ReadItem_with_AsNoTrackingWithIdentityResolution(); - AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|1)"""); + AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|b29bced8-e1e5-420e-82d7-1c7a51703d34)"""); } public override async Task ReadItem_with_shared_container() @@ -446,7 +463,7 @@ public override async Task Predicate_with_partial_values_in_hierarchical_partiti """ SELECT VALUE c FROM root c -WHERE ((c["$type"] = "DerivedHierarchicalPartitionKeyEntity") AND ((c["PartitionKey1"] = "PK1") AND (c["PartitionKey2"] = 1))) +WHERE (c["$type"] = "DerivedHierarchicalPartitionKeyEntity") """); } @@ -459,7 +476,7 @@ public override async Task Predicate_with_partial_values_in_only_hierarchical_pa """ SELECT VALUE c FROM root c -WHERE ((c["$type"] = "DerivedOnlyHierarchicalPartitionKeyEntity") AND ((c["PartitionKey1"] = "PK1c") AND (c["PartitionKey2"] = 1))) +WHERE (c["$type"] = "DerivedOnlyHierarchicalPartitionKeyEntity") """); } @@ -543,11 +560,16 @@ FROM root c """); } - public override async Task WithPartitionKey_with_missing_value_in_hierarchical_partition_key_leaf() + public override async Task WithPartitionKey_with_partial_value_in_hierarchical_partition_key_leaf() { - await base.WithPartitionKey_with_missing_value_in_hierarchical_partition_key_leaf(); + await base.WithPartitionKey_with_partial_value_in_hierarchical_partition_key_leaf(); - AssertSql(); + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE (c["$type"] = "DerivedHierarchicalPartitionKeyEntity") +"""); } public override async Task Both_WithPartitionKey_and_predicate_comparisons_with_different_values_leaf() @@ -600,7 +622,7 @@ public override async Task ReadItem_with_hierarchical_partition_key_leaf() { await base.ReadItem_with_hierarchical_partition_key_leaf(); - AssertSql("""ReadItem(["PK1",1.0,true], HierarchicalPartitionKeyEntity|11)"""); + AssertSql("""ReadItem(["PK1",1.0,true], HierarchicalPartitionKeyEntity|316c846c-787f-44b9-aadf-272f1658c5ff)"""); } public override async Task ReadItem_with_only_hierarchical_partition_key_leaf() @@ -614,7 +636,7 @@ public override async Task ReadItem_with_single_partition_key_constant_leaf() { await base.ReadItem_with_single_partition_key_constant_leaf(); - AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|11)"""); + AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|188d3253-81be-4a87-b58f-a2bd07e6b98c)"""); } public override async Task ReadItem_with_only_single_partition_key_constant_leaf() @@ -628,7 +650,7 @@ public override async Task ReadItem_with_single_partition_key_parameter_leaf() { await base.ReadItem_with_single_partition_key_parameter_leaf(); - AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|11)"""); + AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|188d3253-81be-4a87-b58f-a2bd07e6b98c)"""); } public override async Task ReadItem_with_only_single_partition_key_parameter_leaf() @@ -642,7 +664,7 @@ public override async Task ReadItem_with_SingleAsync_leaf() { await base.ReadItem_with_SingleAsync_leaf(); - AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|11)"""); + AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|188d3253-81be-4a87-b58f-a2bd07e6b98c)"""); } public override async Task ReadItem_with_SingleAsync_with_only_partition_key_leaf() @@ -656,7 +678,7 @@ public override async Task ReadItem_with_inverse_comparison_leaf() { await base.ReadItem_with_inverse_comparison_leaf(); - AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|11)"""); + AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|188d3253-81be-4a87-b58f-a2bd07e6b98c)"""); } public override async Task ReadItem_with_inverse_comparison_with_only_partition_key_leaf() @@ -670,14 +692,14 @@ public override async Task ReadItem_with_EF_Property_leaf() { await base.ReadItem_with_EF_Property_leaf(); - AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|11)"""); + AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|188d3253-81be-4a87-b58f-a2bd07e6b98c)"""); } public override async Task ReadItem_with_WithPartitionKey_leaf() { await base.ReadItem_with_WithPartitionKey_leaf(); - AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|11)"""); + AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|188d3253-81be-4a87-b58f-a2bd07e6b98c)"""); } public override async Task ReadItem_with_WithPartitionKey_with_only_partition_key_leaf() @@ -696,7 +718,7 @@ public override async Task Multiple_incompatible_predicate_comparisons_cause_no_ """ SELECT VALUE c FROM root c -WHERE ((c["$type"] = "DerivedSinglePartitionKeyEntity") AND ((c["Id"] = 11) AND (c["Id"] = 22))) +WHERE ((c["$type"] = "DerivedSinglePartitionKeyEntity") AND ((c["Id"] = "188d3253-81be-4a87-b58f-a2bd07e6b98c") AND (c["Id"] = "11f8d1fd-7472-46f5-9e20-16af42b3b8d1"))) """); } @@ -730,7 +752,7 @@ public override async Task ReadItem_is_not_used_without_partition_key_leaf() """ SELECT VALUE c FROM root c -WHERE ((c["$type"] = "DerivedSinglePartitionKeyEntity") AND (c["Id"] = 11)) +WHERE ((c["$type"] = "DerivedSinglePartitionKeyEntity") AND (c["Id"] = "188d3253-81be-4a87-b58f-a2bd07e6b98c")) """); } @@ -738,28 +760,28 @@ public override async Task ReadItem_with_non_existent_id_leaf() { await base.ReadItem_with_non_existent_id_leaf(); - AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|999)"""); + AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|b964beda-b4e1-4f5c-a729-0a35dae696fe)"""); } public override async Task ReadItem_with_AsNoTracking_leaf() { await base.ReadItem_with_AsNoTracking_leaf(); - AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|11)"""); + AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|188d3253-81be-4a87-b58f-a2bd07e6b98c)"""); } public override async Task ReadItem_with_AsNoTrackingWithIdentityResolution_leaf() { await base.ReadItem_with_AsNoTrackingWithIdentityResolution_leaf(); - AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|11)"""); + AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|188d3253-81be-4a87-b58f-a2bd07e6b98c)"""); } public override async Task ReadItem_with_single_explicit_discriminator_mapping() { await base.ReadItem_with_single_explicit_discriminator_mapping(); - AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|1)"""); + AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|b29bced8-e1e5-420e-82d7-1c7a51703d34)"""); } public override async Task ReadItem_with_single_explicit_incorrect_discriminator_mapping() @@ -771,7 +793,7 @@ public override async Task ReadItem_with_single_explicit_incorrect_discriminator """ SELECT VALUE c FROM root c -WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND ((c["Id"] = 1) AND (c["$type"] = "DerivedSinglePartitionKeyEntity"))) +WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND ((c["Id"] = "b29bced8-e1e5-420e-82d7-1c7a51703d34") AND (c["$type"] = "DerivedSinglePartitionKeyEntity"))) """); } @@ -786,7 +808,7 @@ public override async Task ReadItem_with_single_explicit_parameterized_discrimin SELECT VALUE c FROM root c -WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND ((c["Id"] = 1) AND (c["$type"] = @__discriminator_0))) +WHERE (c["$type"] IN ("SinglePartitionKeyEntity", "DerivedSinglePartitionKeyEntity") AND ((c["Id"] = "b29bced8-e1e5-420e-82d7-1c7a51703d34") AND (c["$type"] = @__discriminator_0))) OFFSET 0 LIMIT 2 """); } @@ -795,7 +817,7 @@ public override async Task ReadItem_with_single_explicit_discriminator_mapping_l { await base.ReadItem_with_single_explicit_discriminator_mapping_leaf(); - AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|11)"""); + AssertSql("""ReadItem(["PK1"], SinglePartitionKeyEntity|188d3253-81be-4a87-b58f-a2bd07e6b98c)"""); } public override async Task ReadItem_with_single_explicit_incorrect_discriminator_mapping_leaf() @@ -807,7 +829,7 @@ public override async Task ReadItem_with_single_explicit_incorrect_discriminator """ SELECT VALUE c FROM root c -WHERE ((c["$type"] = "DerivedSinglePartitionKeyEntity") AND ((c["Id"] = 11) AND (c["$type"] = "SinglePartitionKeyEntity"))) +WHERE ((c["$type"] = "DerivedSinglePartitionKeyEntity") AND ((c["Id"] = "188d3253-81be-4a87-b58f-a2bd07e6b98c") AND (c["$type"] = "SinglePartitionKeyEntity"))) """); } @@ -822,7 +844,7 @@ public override async Task ReadItem_with_single_explicit_parameterized_discrimin SELECT VALUE c FROM root c -WHERE ((c["$type"] = "DerivedSinglePartitionKeyEntity") AND ((c["Id"] = 11) AND (c["$type"] = @__discriminator_0))) +WHERE ((c["$type"] = "DerivedSinglePartitionKeyEntity") AND ((c["Id"] = "188d3253-81be-4a87-b58f-a2bd07e6b98c") AND (c["$type"] = @__discriminator_0))) OFFSET 0 LIMIT 2 """); } @@ -836,7 +858,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con { base.OnModelCreating(modelBuilder, context); - modelBuilder.IncludeRootDiscriminatorInJsonId(); + modelBuilder.HasRootDiscriminatorInJsonId(); } } } diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryTest.cs index 8abdbf7796f..a5bf0e45536 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryTest.cs @@ -3,7 +3,8 @@ namespace Microsoft.EntityFrameworkCore.Query; -public class ReadItemPartitionKeyQueryTest : ReadItemPartitionKeyQueryTestBase +public class ReadItemPartitionKeyQueryTest : ReadItemPartitionKeyQueryTestBase< + ReadItemPartitionKeyQueryTest.ReadItemPartitionKeyQueryFixture> { public ReadItemPartitionKeyQueryTest(ReadItemPartitionKeyQueryFixture fixture, ITestOutputHelper testOutputHelper) : base(fixture, testOutputHelper) @@ -59,12 +60,25 @@ public override async Task Predicate_with_partial_values_in_hierarchical_partiti { await base.Predicate_with_partial_values_in_hierarchical_partition_key(); - // Not ReadItem because no primary key value + // Not ReadItem because no primary key value, but partial partition key value is extracted + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE (c["$type"] = "HierarchicalPartitionKeyEntity") +"""); + } + + public override async Task Predicate_with_partial_values_and_gap_in_hierarchical_partition_key() + { + await base.Predicate_with_partial_values_and_gap_in_hierarchical_partition_key(); + + // Not ReadItem because no primary key value, but partial partition key value is extracted AssertSql( """ SELECT VALUE c FROM root c -WHERE ((c["$type"] = "HierarchicalPartitionKeyEntity") AND ((c["PartitionKey1"] = "PK1") AND (c["PartitionKey2"] = 1))) +WHERE ((c["$type"] = "HierarchicalPartitionKeyEntity") AND c["PartitionKey3"]) """); } @@ -78,7 +92,7 @@ public override async Task Predicate_with_partial_values_in_only_hierarchical_pa """ SELECT VALUE c FROM root c -WHERE ((c["$type"] = "OnlyHierarchicalPartitionKeyEntity") AND ((c["PartitionKey1"] = "PK1a") AND (c["PartitionKey2"] = 1))) +WHERE (c["$type"] = "OnlyHierarchicalPartitionKeyEntity") """); } @@ -158,11 +172,16 @@ FROM root c """); } - public override async Task WithPartitionKey_with_missing_value_in_hierarchical_partition_key() + public override async Task WithPartitionKey_with_partial_value_in_hierarchical_partition_key() { - await base.WithPartitionKey_with_missing_value_in_hierarchical_partition_key(); + await base.WithPartitionKey_with_partial_value_in_hierarchical_partition_key(); - AssertSql(); + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE (c["$type"] = "HierarchicalPartitionKeyEntity") +"""); } public override async Task Both_WithPartitionKey_and_predicate_comparisons_with_different_values() @@ -215,7 +234,7 @@ public override async Task ReadItem_with_hierarchical_partition_key() { await base.ReadItem_with_hierarchical_partition_key(); - AssertSql("""ReadItem(["PK1",1.0,true], 1)"""); + AssertSql("""ReadItem(["PK1",1.0,true], 31887258-bdf9-49b8-89b2-01b6aa741a4a)"""); } public override async Task ReadItem_with_only_hierarchical_partition_key() @@ -229,7 +248,7 @@ public override async Task ReadItem_with_single_partition_key_constant() { await base.ReadItem_with_single_partition_key_constant(); - AssertSql("""ReadItem(["PK1"], 1)"""); + AssertSql("""ReadItem(["PK1"], b29bced8-e1e5-420e-82d7-1c7a51703d34)"""); } public override async Task ReadItem_with_only_single_partition_key_constant() @@ -243,7 +262,7 @@ public override async Task ReadItem_with_single_partition_key_parameter() { await base.ReadItem_with_single_partition_key_parameter(); - AssertSql("""ReadItem(["PK1"], 1)"""); + AssertSql("""ReadItem(["PK1"], b29bced8-e1e5-420e-82d7-1c7a51703d34)"""); } public override async Task ReadItem_with_only_single_partition_key_parameter() @@ -257,7 +276,7 @@ public override async Task ReadItem_with_SingleAsync() { await base.ReadItem_with_SingleAsync(); - AssertSql("""ReadItem(["PK1"], 1)"""); + AssertSql("""ReadItem(["PK1"], b29bced8-e1e5-420e-82d7-1c7a51703d34)"""); } public override async Task ReadItem_with_SingleAsync_with_only_partition_key() @@ -271,7 +290,7 @@ public override async Task ReadItem_with_inverse_comparison() { await base.ReadItem_with_inverse_comparison(); - AssertSql("""ReadItem(["PK1"], 1)"""); + AssertSql("""ReadItem(["PK1"], b29bced8-e1e5-420e-82d7-1c7a51703d34)"""); } public override async Task ReadItem_with_inverse_comparison_with_only_partition_key() @@ -285,14 +304,14 @@ public override async Task ReadItem_with_EF_Property() { await base.ReadItem_with_EF_Property(); - AssertSql("""ReadItem(["PK1"], 1)"""); + AssertSql("""ReadItem(["PK1"], b29bced8-e1e5-420e-82d7-1c7a51703d34)"""); } public override async Task ReadItem_with_WithPartitionKey() { await base.ReadItem_with_WithPartitionKey(); - AssertSql("""ReadItem(["PK1"], 1)"""); + AssertSql("""ReadItem(["PK1"], b29bced8-e1e5-420e-82d7-1c7a51703d34)"""); } public override async Task ReadItem_with_WithPartitionKey_with_only_partition_key() @@ -311,11 +330,10 @@ public override async Task Multiple_incompatible_predicate_comparisons_cause_no_ """ SELECT VALUE c FROM root c -WHERE ((c["Id"] = 1) AND (c["Id"] = 2)) +WHERE ((c["id"] = "b29bced8-e1e5-420e-82d7-1c7a51703d34") AND (c["id"] = "3307a33b-7f28-49ef-9857-48f4e3ebcaed")) """); } - public override async Task Multiple_incompatible_predicate_comparisons_cause_no_ReadItem_with_only_partition_key() { await base.Multiple_incompatible_predicate_comparisons_cause_no_ReadItem_with_only_partition_key(); @@ -347,7 +365,7 @@ public override async Task ReadItem_is_not_used_without_partition_key() """ SELECT VALUE c FROM root c -WHERE (c["Id"] = 1) +WHERE (c["id"] = "b29bced8-e1e5-420e-82d7-1c7a51703d34") """); } @@ -355,21 +373,21 @@ public override async Task ReadItem_with_non_existent_id() { await base.ReadItem_with_non_existent_id(); - AssertSql("""ReadItem(["PK1"], 999)"""); + AssertSql("""ReadItem(["PK1"], 50b66960-35be-40c5-bc3d-4c9f2799d4d1)"""); } public override async Task ReadItem_with_AsNoTracking() { await base.ReadItem_with_AsNoTracking(); - AssertSql("""ReadItem(["PK1"], 1)"""); + AssertSql("""ReadItem(["PK1"], b29bced8-e1e5-420e-82d7-1c7a51703d34)"""); } public override async Task ReadItem_with_AsNoTrackingWithIdentityResolution() { await base.ReadItem_with_AsNoTrackingWithIdentityResolution(); - AssertSql("""ReadItem(["PK1"], 1)"""); + AssertSql("""ReadItem(["PK1"], b29bced8-e1e5-420e-82d7-1c7a51703d34)"""); } public override async Task ReadItem_with_shared_container() @@ -397,7 +415,7 @@ public override async Task ReadItem_with_single_explicit_discriminator_mapping() { await base.ReadItem_with_single_explicit_discriminator_mapping(); - AssertSql("""ReadItem(["PK1"], 1)"""); + AssertSql("""ReadItem(["PK1"], b29bced8-e1e5-420e-82d7-1c7a51703d34)"""); } public override async Task ReadItem_with_single_explicit_incorrect_discriminator_mapping() @@ -409,7 +427,7 @@ public override async Task ReadItem_with_single_explicit_incorrect_discriminator """ SELECT VALUE c FROM root c -WHERE ((c["Id"] = 1) AND (c["$type"] = "DerivedSinglePartitionKeyEntity")) +WHERE ((c["id"] = "b29bced8-e1e5-420e-82d7-1c7a51703d34") AND (c["$type"] = "DerivedSinglePartitionKeyEntity")) """); } @@ -417,14 +435,13 @@ public override async Task ReadItem_with_single_explicit_parameterized_discrimin { await base.ReadItem_with_single_explicit_parameterized_discriminator_mapping(); - // No ReadItem because discriminator check is parameterized AssertSql( """ @__discriminator_0='SinglePartitionKeyEntity' SELECT VALUE c FROM root c -WHERE ((c["Id"] = 1) AND (c["$type"] = @__discriminator_0)) +WHERE ((c["id"] = "b29bced8-e1e5-420e-82d7-1c7a51703d34") AND (c["$type"] = @__discriminator_0)) OFFSET 0 LIMIT 2 """); } diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryTestBase.cs b/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryTestBase.cs index 97c63f9a6ed..e2c1bc33712 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryTestBase.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryTestBase.cs @@ -48,6 +48,13 @@ public virtual Task Predicate_with_partial_values_in_hierarchical_partition_key( ss => ss.Set() .Where(e => e.PartitionKey1 == "PK1" && e.PartitionKey2 == 1)); + [ConditionalFact] + public virtual Task Predicate_with_partial_values_and_gap_in_hierarchical_partition_key() + => AssertQuery( + async: true, + ss => ss.Set() + .Where(e => e.PartitionKey1 == "PK1" && e.PartitionKey3)); + [ConditionalFact] public virtual Task Predicate_with_partial_values_in_only_hierarchical_partition_key() => AssertQuery( @@ -108,17 +115,11 @@ public virtual Task WithPartitionKey_with_only_single_partition_key() ss => ss.Set().Where(e => e.PartitionKey == "PK1a")); [ConditionalFact] - public virtual async Task WithPartitionKey_with_missing_value_in_hierarchical_partition_key() - { - var message = await Assert.ThrowsAsync( - () => AssertQuery( + public virtual Task WithPartitionKey_with_partial_value_in_hierarchical_partition_key() + => AssertQuery( async: true, ss => ss.Set().WithPartitionKey("PK1", 1), - ss => ss.Set() - .Where(e => e.PartitionKey1 == "PK1" && e.PartitionKey2 == 1 && e.PartitionKey3))); - - Assert.Equal(CosmosStrings.IncorrectPartitionKeyNumber(nameof(HierarchicalPartitionKeyEntity), 2, 3), message.Message); - } + ss => ss.Set().Where(e => e.PartitionKey1 == "PK1" && e.PartitionKey2 == 1)); [ConditionalFact] public virtual Task Both_WithPartitionKey_and_predicate_comparisons_with_different_values() @@ -160,7 +161,11 @@ public virtual Task ReadItem_with_hierarchical_partition_key() return AssertQuery( async: true, ss => ss.Set() - .Where(e => e.Id == 1 && e.PartitionKey1 == "PK1" && e.PartitionKey2 == partitionKey2 && e.PartitionKey3)); + .Where( + e => e.Id == Guid.Parse("31887258-BDF9-49B8-89B2-01B6AA741A4A") + && e.PartitionKey1 == "PK1" + && e.PartitionKey2 == partitionKey2 + && e.PartitionKey3)); } [ConditionalFact] @@ -178,7 +183,8 @@ public virtual Task ReadItem_with_only_hierarchical_partition_key() public virtual Task ReadItem_with_single_partition_key_constant() => AssertQuery( async: true, - ss => ss.Set().Where(e => e.Id == 1 && e.PartitionKey == "PK1")); + ss => ss.Set() + .Where(e => e.Id == Guid.Parse("B29BCED8-E1E5-420E-82D7-1C7A51703D34") && e.PartitionKey == "PK1")); [ConditionalFact] public virtual Task ReadItem_with_only_single_partition_key_constant() @@ -193,7 +199,8 @@ public virtual Task ReadItem_with_single_partition_key_parameter() return AssertQuery( async: true, - ss => ss.Set().Where(e => e.Id == 1 && e.PartitionKey == partitionKey)); + ss => ss.Set().Where( + e => e.Id == Guid.Parse("B29BCED8-E1E5-420E-82D7-1C7A51703D34") && e.PartitionKey == partitionKey)); } [ConditionalFact] @@ -213,7 +220,8 @@ public virtual Task ReadItem_with_SingleAsync() return AssertSingle( async: true, - ss => ss.Set().Where(e => e.Id == 1 && e.PartitionKey == partitionKey)); + ss => ss.Set().Where( + e => e.Id == Guid.Parse("B29BCED8-E1E5-420E-82D7-1C7A51703D34") && e.PartitionKey == partitionKey)); } [ConditionalFact] @@ -230,7 +238,8 @@ public virtual Task ReadItem_with_SingleAsync_with_only_partition_key() public virtual Task ReadItem_with_inverse_comparison() => AssertQuery( async: true, - ss => ss.Set().Where(e => 1 == e.Id && "PK1" == e.PartitionKey)); + ss => ss.Set() + .Where(e => Guid.Parse("B29BCED8-E1E5-420E-82D7-1C7A51703D34") == e.Id && "PK1" == e.PartitionKey)); [ConditionalFact] public virtual Task ReadItem_with_inverse_comparison_with_only_partition_key() @@ -243,15 +252,17 @@ public virtual Task ReadItem_with_EF_Property() => AssertQuery( async: true, ss => ss.Set().Where( - e => EF.Property(e, nameof(SinglePartitionKeyEntity.Id)) == 1 + e => EF.Property(e, nameof(SinglePartitionKeyEntity.Id)) == Guid.Parse("B29BCED8-E1E5-420E-82D7-1C7A51703D34") && EF.Property(e, nameof(SinglePartitionKeyEntity.PartitionKey)) == "PK1")); [ConditionalFact] public virtual Task ReadItem_with_WithPartitionKey() => AssertQuery( async: true, - ss => ss.Set().WithPartitionKey("PK1").Where(e => e.Id == 1), - ss => ss.Set().Where(e => e.PartitionKey == "PK1").Where(e => e.Id == 1)); + ss => ss.Set().WithPartitionKey("PK1") + .Where(e => e.Id == Guid.Parse("B29BCED8-E1E5-420E-82D7-1C7A51703D34")), + ss => ss.Set().Where(e => e.PartitionKey == "PK1") + .Where(e => e.Id == Guid.Parse("B29BCED8-E1E5-420E-82D7-1C7A51703D34"))); [ConditionalFact] public virtual Task ReadItem_with_WithPartitionKey_with_only_partition_key() @@ -267,7 +278,10 @@ public virtual Task Multiple_incompatible_predicate_comparisons_cause_no_ReadIte return AssertQuery( async: true, - ss => ss.Set().Where(e => e.Id == 1 && e.Id == 2 && e.PartitionKey == partitionKey), + ss => ss.Set().Where( + e => e.Id == Guid.Parse("B29BCED8-E1E5-420E-82D7-1C7A51703D34") + && e.Id == Guid.Parse("3307A33B-7F28-49EF-9857-48F4E3EBCAED") + && e.PartitionKey == partitionKey), assertEmpty: true); } @@ -293,26 +307,26 @@ public virtual Task ReadItem_with_no_partition_key() public virtual Task ReadItem_is_not_used_without_partition_key() => AssertQuery( async: true, - ss => ss.Set().Where(e => e.Id == 1)); + ss => ss.Set().Where(e => e.Id == Guid.Parse("B29BCED8-E1E5-420E-82D7-1C7A51703D34"))); [ConditionalFact] public virtual Task ReadItem_with_non_existent_id() => AssertQuery( async: true, - ss => ss.Set().Where(e => e.Id == 999 && e.PartitionKey == "PK1"), + ss => ss.Set().Where(e => e.Id == Guid.Parse("50B66960-35BE-40C5-BC3D-4C9F2799D4D1") && e.PartitionKey == "PK1"), assertEmpty: true); [ConditionalFact] public virtual Task ReadItem_with_AsNoTracking() => AssertQuery( async: true, - ss => ss.Set().AsNoTracking().Where(e => e.Id == 1 && e.PartitionKey == "PK1")); + ss => ss.Set().AsNoTracking().Where(e => e.Id == Guid.Parse("B29BCED8-E1E5-420E-82D7-1C7A51703D34") && e.PartitionKey == "PK1")); [ConditionalFact] public virtual Task ReadItem_with_AsNoTrackingWithIdentityResolution() => AssertQuery( async: true, - ss => ss.Set().AsNoTrackingWithIdentityResolution().Where(e => e.Id == 1 && e.PartitionKey == "PK1")); + ss => ss.Set().AsNoTrackingWithIdentityResolution().Where(e => e.Id == Guid.Parse("B29BCED8-E1E5-420E-82D7-1C7A51703D34") && e.PartitionKey == "PK1")); [ConditionalFact] public virtual Task ReadItem_with_shared_container() @@ -341,11 +355,11 @@ public virtual Task ReadItem_with_single_explicit_discriminator_mapping() async: true, ss => ss.Set() .Where( - e => e.Id == 1 + e => e.Id == Guid.Parse("B29BCED8-E1E5-420E-82D7-1C7A51703D34") && EF.Property(e, "$type") == nameof(SinglePartitionKeyEntity) && e.PartitionKey == partitionKey), ss => ss.Set() - .Where(e => e.Id == 1 && e.PartitionKey == partitionKey)); + .Where(e => e.Id == Guid.Parse("B29BCED8-E1E5-420E-82D7-1C7A51703D34") && e.PartitionKey == partitionKey)); } [ConditionalFact] @@ -357,7 +371,7 @@ public virtual Task ReadItem_with_single_explicit_incorrect_discriminator_mappin async: true, ss => ss.Set() .Where( - e => e.Id == 1 + e => e.Id == Guid.Parse("B29BCED8-E1E5-420E-82D7-1C7A51703D34") && EF.Property(e, "$type") == nameof(DerivedSinglePartitionKeyEntity) && e.PartitionKey == partitionKey), ss => ss.Set().Where(e => false), @@ -373,8 +387,12 @@ public virtual Task ReadItem_with_single_explicit_parameterized_discriminator_ma return AssertSingle( async: true, ss => ss.Set() - .Where(e => e.Id == 1 && EF.Property(e, "$type") == discriminator && e.PartitionKey == partitionKey), - ss => ss.Set().Where(e => e.Id == 1 && e.PartitionKey == partitionKey)); + .Where( + e => e.Id == Guid.Parse("B29BCED8-E1E5-420E-82D7-1C7A51703D34") + && EF.Property(e, "$type") == discriminator + && e.PartitionKey == partitionKey), + ss => ss.Set().Where( + e => e.Id == Guid.Parse("B29BCED8-E1E5-420E-82D7-1C7A51703D34") && e.PartitionKey == partitionKey)); } protected void AssertSql(params string[] expected) diff --git a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/Basic_cosmos_model/DataEntityType.cs b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/Basic_cosmos_model/DataEntityType.cs index 5bfe0266a7a..09e7d8fa59c 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/Basic_cosmos_model/DataEntityType.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/Basic_cosmos_model/DataEntityType.cs @@ -108,9 +108,9 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( string (long v) => string.Format(CultureInfo.InvariantCulture, "{0}", ((object)(v))), long (string v) => long.Parse(v, NumberStyles.Any, CultureInfo.InvariantCulture)))); - partitionId.SetValueComparer(new NullableValueComparer(partitionId.TypeMapping.Comparer)); - partitionId.SetKeyValueComparer(new NullableValueComparer(partitionId.TypeMapping.KeyComparer)); partitionId.SetCurrentValueComparer(new EntryCurrentValueComparer(partitionId)); + partitionId.SetComparer(new NullableValueComparer(partitionId.TypeMapping.Comparer)); + partitionId.SetKeyComparer(new NullableValueComparer(partitionId.TypeMapping.KeyComparer)); var blob = runtimeEntityType.AddProperty( "Blob", @@ -393,15 +393,15 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var partitionId = runtimeEntityType.FindProperty("PartitionId")!; - var blob = runtimeEntityType.FindProperty("Blob")!; - var bytes = runtimeEntityType.FindProperty("Bytes")!; - var list = runtimeEntityType.FindProperty("List")!; - var map = runtimeEntityType.FindProperty("Map")!; - var __id = runtimeEntityType.FindProperty("__id")!; - var __jObject = runtimeEntityType.FindProperty("__jObject")!; - var _etag = runtimeEntityType.FindProperty("_etag")!; + var id = runtimeEntityType.FindProperty("Id"); + var partitionId = runtimeEntityType.FindProperty("PartitionId"); + var blob = runtimeEntityType.FindProperty("Blob"); + var bytes = runtimeEntityType.FindProperty("Bytes"); + var list = runtimeEntityType.FindProperty("List"); + var map = runtimeEntityType.FindProperty("Map"); + var __id = runtimeEntityType.FindProperty("__id"); + var __jObject = runtimeEntityType.FindProperty("__jObject"); + var _etag = runtimeEntityType.FindProperty("_etag"); var key = runtimeEntityType.FindKey(new[] { id, partitionId }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateCompositeFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory>(key)); diff --git a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/DependentBaseEntityType.cs b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/DependentBaseEntityType.cs index 4b19b39ecd1..2acbc54866d 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/DependentBaseEntityType.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/DependentBaseEntityType.cs @@ -195,8 +195,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas byte (byte v) => v), clrType: typeof(byte), jsonValueReaderWriter: JsonByteReaderWriter.Instance); - id.SetValueComparer(new NullableValueComparer(id.TypeMapping.Comparer)); - id.SetKeyValueComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); + id.SetComparer(new NullableValueComparer(id.TypeMapping.Comparer)); + id.SetKeyComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); var __id = runtimeEntityType.AddProperty( "__id", @@ -355,16 +355,16 @@ public static RuntimeForeignKey CreateForeignKey2(RuntimeEntityType declaringEnt public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var principalId = runtimeEntityType.FindProperty("PrincipalId")!; - var principalAlternateId = runtimeEntityType.FindProperty("PrincipalAlternateId")!; - var enumDiscriminator = runtimeEntityType.FindProperty("EnumDiscriminator")!; - var id = runtimeEntityType.FindProperty("Id")!; - var __id = runtimeEntityType.FindProperty("__id")!; - var __jObject = runtimeEntityType.FindProperty("__jObject")!; + var principalId = runtimeEntityType.FindProperty("PrincipalId"); + var principalAlternateId = runtimeEntityType.FindProperty("PrincipalAlternateId"); + var enumDiscriminator = runtimeEntityType.FindProperty("EnumDiscriminator"); + var id = runtimeEntityType.FindProperty("Id"); + var __id = runtimeEntityType.FindProperty("__id"); + var __jObject = runtimeEntityType.FindProperty("__jObject"); var key = runtimeEntityType.FindKey(new[] { principalId, principalAlternateId }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateCompositeFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory>(key)); - var principal = runtimeEntityType.FindNavigation("Principal")!; + var principal = runtimeEntityType.FindNavigation("Principal"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { diff --git a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/DependentDerivedEntityType.cs b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/DependentDerivedEntityType.cs index dea36a8eee6..2a2d3359470 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/DependentDerivedEntityType.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/DependentDerivedEntityType.cs @@ -115,15 +115,15 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var principalId = runtimeEntityType.FindProperty("PrincipalId")!; - var principalAlternateId = runtimeEntityType.FindProperty("PrincipalAlternateId")!; - var enumDiscriminator = runtimeEntityType.FindProperty("EnumDiscriminator")!; - var id = runtimeEntityType.FindProperty("Id")!; - var __id = runtimeEntityType.FindProperty("__id")!; - var __jObject = runtimeEntityType.FindProperty("__jObject")!; - var data = runtimeEntityType.FindProperty("Data")!; - var money = runtimeEntityType.FindProperty("Money")!; - var principal = runtimeEntityType.FindNavigation("Principal")!; + var principalId = runtimeEntityType.FindProperty("PrincipalId"); + var principalAlternateId = runtimeEntityType.FindProperty("PrincipalAlternateId"); + var enumDiscriminator = runtimeEntityType.FindProperty("EnumDiscriminator"); + var id = runtimeEntityType.FindProperty("Id"); + var __id = runtimeEntityType.FindProperty("__id"); + var __jObject = runtimeEntityType.FindProperty("__jObject"); + var data = runtimeEntityType.FindProperty("Data"); + var money = runtimeEntityType.FindProperty("Money"); + var principal = runtimeEntityType.FindNavigation("Principal"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { diff --git a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/ManyTypesEntityType.cs b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/ManyTypesEntityType.cs index 85405c4137f..23192b1e6b6 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/ManyTypesEntityType.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/ManyTypesEntityType.cs @@ -3804,8 +3804,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (bool v) => v), clrType: typeof(bool), jsonValueReaderWriter: JsonBoolReaderWriter.Instance); - nullableBool.SetValueComparer(new NullableValueComparer(nullableBool.TypeMapping.Comparer)); - nullableBool.SetKeyValueComparer(new NullableValueComparer(nullableBool.TypeMapping.KeyComparer)); + nullableBool.SetComparer(new NullableValueComparer(nullableBool.TypeMapping.Comparer)); + nullableBool.SetKeyComparer(new NullableValueComparer(nullableBool.TypeMapping.KeyComparer)); var nullableBoolArray = runtimeEntityType.AddProperty( "NullableBoolArray", @@ -3956,8 +3956,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas char (char v) => v), clrType: typeof(char), jsonValueReaderWriter: JsonCharReaderWriter.Instance); - nullableChar.SetValueComparer(new NullableValueComparer(nullableChar.TypeMapping.Comparer)); - nullableChar.SetKeyValueComparer(new NullableValueComparer(nullableChar.TypeMapping.KeyComparer)); + nullableChar.SetComparer(new NullableValueComparer(nullableChar.TypeMapping.Comparer)); + nullableChar.SetKeyComparer(new NullableValueComparer(nullableChar.TypeMapping.KeyComparer)); var nullableCharArray = runtimeEntityType.AddProperty( "NullableCharArray", @@ -4059,8 +4059,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas DateOnly (DateOnly v) => v), clrType: typeof(DateOnly), jsonValueReaderWriter: JsonDateOnlyReaderWriter.Instance); - nullableDateOnly.SetValueComparer(new NullableValueComparer(nullableDateOnly.TypeMapping.Comparer)); - nullableDateOnly.SetKeyValueComparer(new NullableValueComparer(nullableDateOnly.TypeMapping.KeyComparer)); + nullableDateOnly.SetComparer(new NullableValueComparer(nullableDateOnly.TypeMapping.Comparer)); + nullableDateOnly.SetKeyComparer(new NullableValueComparer(nullableDateOnly.TypeMapping.KeyComparer)); var nullableDateTime = runtimeEntityType.AddProperty( "NullableDateTime", @@ -4104,8 +4104,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas DateTime (DateTime v) => v), clrType: typeof(DateTime), jsonValueReaderWriter: JsonDateTimeReaderWriter.Instance); - nullableDateTime.SetValueComparer(new NullableValueComparer(nullableDateTime.TypeMapping.Comparer)); - nullableDateTime.SetKeyValueComparer(new NullableValueComparer(nullableDateTime.TypeMapping.KeyComparer)); + nullableDateTime.SetComparer(new NullableValueComparer(nullableDateTime.TypeMapping.Comparer)); + nullableDateTime.SetKeyComparer(new NullableValueComparer(nullableDateTime.TypeMapping.KeyComparer)); var nullableDecimal = runtimeEntityType.AddProperty( "NullableDecimal", @@ -4149,8 +4149,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas decimal (decimal v) => v), clrType: typeof(decimal), jsonValueReaderWriter: JsonDecimalReaderWriter.Instance); - nullableDecimal.SetValueComparer(new NullableValueComparer(nullableDecimal.TypeMapping.Comparer)); - nullableDecimal.SetKeyValueComparer(new NullableValueComparer(nullableDecimal.TypeMapping.KeyComparer)); + nullableDecimal.SetComparer(new NullableValueComparer(nullableDecimal.TypeMapping.Comparer)); + nullableDecimal.SetKeyComparer(new NullableValueComparer(nullableDecimal.TypeMapping.KeyComparer)); var nullableDecimalArray = runtimeEntityType.AddProperty( "NullableDecimalArray", @@ -4252,8 +4252,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas double (double v) => v), clrType: typeof(double), jsonValueReaderWriter: JsonDoubleReaderWriter.Instance); - nullableDouble.SetValueComparer(new NullableValueComparer(nullableDouble.TypeMapping.Comparer)); - nullableDouble.SetKeyValueComparer(new NullableValueComparer(nullableDouble.TypeMapping.KeyComparer)); + nullableDouble.SetComparer(new NullableValueComparer(nullableDouble.TypeMapping.Comparer)); + nullableDouble.SetKeyComparer(new NullableValueComparer(nullableDouble.TypeMapping.KeyComparer)); var nullableDoubleArray = runtimeEntityType.AddProperty( "NullableDoubleArray", @@ -4361,8 +4361,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( short (CompiledModelTestBase.Enum16 value) => ((short)(value)), CompiledModelTestBase.Enum16 (short value) => ((CompiledModelTestBase.Enum16)(value))))); - nullableEnum16.SetValueComparer(new NullableValueComparer(nullableEnum16.TypeMapping.Comparer)); - nullableEnum16.SetKeyValueComparer(new NullableValueComparer(nullableEnum16.TypeMapping.KeyComparer)); + nullableEnum16.SetComparer(new NullableValueComparer(nullableEnum16.TypeMapping.Comparer)); + nullableEnum16.SetKeyComparer(new NullableValueComparer(nullableEnum16.TypeMapping.KeyComparer)); var nullableEnum16AsString = runtimeEntityType.AddProperty( "NullableEnum16AsString", @@ -4412,8 +4412,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( short (CompiledModelTestBase.Enum16 value) => ((short)(value)), CompiledModelTestBase.Enum16 (short value) => ((CompiledModelTestBase.Enum16)(value))))); - nullableEnum16AsString.SetValueComparer(new NullableValueComparer(nullableEnum16AsString.TypeMapping.Comparer)); - nullableEnum16AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnum16AsString.TypeMapping.KeyComparer)); + nullableEnum16AsString.SetComparer(new NullableValueComparer(nullableEnum16AsString.TypeMapping.Comparer)); + nullableEnum16AsString.SetKeyComparer(new NullableValueComparer(nullableEnum16AsString.TypeMapping.KeyComparer)); var nullableEnum32 = runtimeEntityType.AddProperty( "NullableEnum32", @@ -4463,8 +4463,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( int (CompiledModelTestBase.Enum32 value) => ((int)(value)), CompiledModelTestBase.Enum32 (int value) => ((CompiledModelTestBase.Enum32)(value))))); - nullableEnum32.SetValueComparer(new NullableValueComparer(nullableEnum32.TypeMapping.Comparer)); - nullableEnum32.SetKeyValueComparer(new NullableValueComparer(nullableEnum32.TypeMapping.KeyComparer)); + nullableEnum32.SetComparer(new NullableValueComparer(nullableEnum32.TypeMapping.Comparer)); + nullableEnum32.SetKeyComparer(new NullableValueComparer(nullableEnum32.TypeMapping.KeyComparer)); var nullableEnum32AsString = runtimeEntityType.AddProperty( "NullableEnum32AsString", @@ -4514,8 +4514,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( int (CompiledModelTestBase.Enum32 value) => ((int)(value)), CompiledModelTestBase.Enum32 (int value) => ((CompiledModelTestBase.Enum32)(value))))); - nullableEnum32AsString.SetValueComparer(new NullableValueComparer(nullableEnum32AsString.TypeMapping.Comparer)); - nullableEnum32AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnum32AsString.TypeMapping.KeyComparer)); + nullableEnum32AsString.SetComparer(new NullableValueComparer(nullableEnum32AsString.TypeMapping.Comparer)); + nullableEnum32AsString.SetKeyComparer(new NullableValueComparer(nullableEnum32AsString.TypeMapping.KeyComparer)); var nullableEnum64 = runtimeEntityType.AddProperty( "NullableEnum64", @@ -4565,8 +4565,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( long (CompiledModelTestBase.Enum64 value) => ((long)(value)), CompiledModelTestBase.Enum64 (long value) => ((CompiledModelTestBase.Enum64)(value))))); - nullableEnum64.SetValueComparer(new NullableValueComparer(nullableEnum64.TypeMapping.Comparer)); - nullableEnum64.SetKeyValueComparer(new NullableValueComparer(nullableEnum64.TypeMapping.KeyComparer)); + nullableEnum64.SetComparer(new NullableValueComparer(nullableEnum64.TypeMapping.Comparer)); + nullableEnum64.SetKeyComparer(new NullableValueComparer(nullableEnum64.TypeMapping.KeyComparer)); var nullableEnum64AsString = runtimeEntityType.AddProperty( "NullableEnum64AsString", @@ -4616,8 +4616,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( long (CompiledModelTestBase.Enum64 value) => ((long)(value)), CompiledModelTestBase.Enum64 (long value) => ((CompiledModelTestBase.Enum64)(value))))); - nullableEnum64AsString.SetValueComparer(new NullableValueComparer(nullableEnum64AsString.TypeMapping.Comparer)); - nullableEnum64AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnum64AsString.TypeMapping.KeyComparer)); + nullableEnum64AsString.SetComparer(new NullableValueComparer(nullableEnum64AsString.TypeMapping.Comparer)); + nullableEnum64AsString.SetKeyComparer(new NullableValueComparer(nullableEnum64AsString.TypeMapping.KeyComparer)); var nullableEnum8 = runtimeEntityType.AddProperty( "NullableEnum8", @@ -4667,8 +4667,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( sbyte (CompiledModelTestBase.Enum8 value) => ((sbyte)(value)), CompiledModelTestBase.Enum8 (sbyte value) => ((CompiledModelTestBase.Enum8)(value))))); - nullableEnum8.SetValueComparer(new NullableValueComparer(nullableEnum8.TypeMapping.Comparer)); - nullableEnum8.SetKeyValueComparer(new NullableValueComparer(nullableEnum8.TypeMapping.KeyComparer)); + nullableEnum8.SetComparer(new NullableValueComparer(nullableEnum8.TypeMapping.Comparer)); + nullableEnum8.SetKeyComparer(new NullableValueComparer(nullableEnum8.TypeMapping.KeyComparer)); var nullableEnum8AsString = runtimeEntityType.AddProperty( "NullableEnum8AsString", @@ -4718,8 +4718,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( sbyte (CompiledModelTestBase.Enum8 value) => ((sbyte)(value)), CompiledModelTestBase.Enum8 (sbyte value) => ((CompiledModelTestBase.Enum8)(value))))); - nullableEnum8AsString.SetValueComparer(new NullableValueComparer(nullableEnum8AsString.TypeMapping.Comparer)); - nullableEnum8AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnum8AsString.TypeMapping.KeyComparer)); + nullableEnum8AsString.SetComparer(new NullableValueComparer(nullableEnum8AsString.TypeMapping.Comparer)); + nullableEnum8AsString.SetKeyComparer(new NullableValueComparer(nullableEnum8AsString.TypeMapping.KeyComparer)); var nullableEnumU16 = runtimeEntityType.AddProperty( "NullableEnumU16", @@ -4769,8 +4769,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( ushort (CompiledModelTestBase.EnumU16 value) => ((ushort)(value)), CompiledModelTestBase.EnumU16 (ushort value) => ((CompiledModelTestBase.EnumU16)(value))))); - nullableEnumU16.SetValueComparer(new NullableValueComparer(nullableEnumU16.TypeMapping.Comparer)); - nullableEnumU16.SetKeyValueComparer(new NullableValueComparer(nullableEnumU16.TypeMapping.KeyComparer)); + nullableEnumU16.SetComparer(new NullableValueComparer(nullableEnumU16.TypeMapping.Comparer)); + nullableEnumU16.SetKeyComparer(new NullableValueComparer(nullableEnumU16.TypeMapping.KeyComparer)); var nullableEnumU16AsString = runtimeEntityType.AddProperty( "NullableEnumU16AsString", @@ -4820,8 +4820,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( ushort (CompiledModelTestBase.EnumU16 value) => ((ushort)(value)), CompiledModelTestBase.EnumU16 (ushort value) => ((CompiledModelTestBase.EnumU16)(value))))); - nullableEnumU16AsString.SetValueComparer(new NullableValueComparer(nullableEnumU16AsString.TypeMapping.Comparer)); - nullableEnumU16AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnumU16AsString.TypeMapping.KeyComparer)); + nullableEnumU16AsString.SetComparer(new NullableValueComparer(nullableEnumU16AsString.TypeMapping.Comparer)); + nullableEnumU16AsString.SetKeyComparer(new NullableValueComparer(nullableEnumU16AsString.TypeMapping.KeyComparer)); var nullableEnumU32 = runtimeEntityType.AddProperty( "NullableEnumU32", @@ -4871,8 +4871,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( uint (CompiledModelTestBase.EnumU32 value) => ((uint)(value)), CompiledModelTestBase.EnumU32 (uint value) => ((CompiledModelTestBase.EnumU32)(value))))); - nullableEnumU32.SetValueComparer(new NullableValueComparer(nullableEnumU32.TypeMapping.Comparer)); - nullableEnumU32.SetKeyValueComparer(new NullableValueComparer(nullableEnumU32.TypeMapping.KeyComparer)); + nullableEnumU32.SetComparer(new NullableValueComparer(nullableEnumU32.TypeMapping.Comparer)); + nullableEnumU32.SetKeyComparer(new NullableValueComparer(nullableEnumU32.TypeMapping.KeyComparer)); var nullableEnumU32AsString = runtimeEntityType.AddProperty( "NullableEnumU32AsString", @@ -4922,8 +4922,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( uint (CompiledModelTestBase.EnumU32 value) => ((uint)(value)), CompiledModelTestBase.EnumU32 (uint value) => ((CompiledModelTestBase.EnumU32)(value))))); - nullableEnumU32AsString.SetValueComparer(new NullableValueComparer(nullableEnumU32AsString.TypeMapping.Comparer)); - nullableEnumU32AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnumU32AsString.TypeMapping.KeyComparer)); + nullableEnumU32AsString.SetComparer(new NullableValueComparer(nullableEnumU32AsString.TypeMapping.Comparer)); + nullableEnumU32AsString.SetKeyComparer(new NullableValueComparer(nullableEnumU32AsString.TypeMapping.KeyComparer)); var nullableEnumU64 = runtimeEntityType.AddProperty( "NullableEnumU64", @@ -4973,8 +4973,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( ulong (CompiledModelTestBase.EnumU64 value) => ((ulong)(value)), CompiledModelTestBase.EnumU64 (ulong value) => ((CompiledModelTestBase.EnumU64)(value))))); - nullableEnumU64.SetValueComparer(new NullableValueComparer(nullableEnumU64.TypeMapping.Comparer)); - nullableEnumU64.SetKeyValueComparer(new NullableValueComparer(nullableEnumU64.TypeMapping.KeyComparer)); + nullableEnumU64.SetComparer(new NullableValueComparer(nullableEnumU64.TypeMapping.Comparer)); + nullableEnumU64.SetKeyComparer(new NullableValueComparer(nullableEnumU64.TypeMapping.KeyComparer)); var nullableEnumU64AsString = runtimeEntityType.AddProperty( "NullableEnumU64AsString", @@ -5024,8 +5024,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( ulong (CompiledModelTestBase.EnumU64 value) => ((ulong)(value)), CompiledModelTestBase.EnumU64 (ulong value) => ((CompiledModelTestBase.EnumU64)(value))))); - nullableEnumU64AsString.SetValueComparer(new NullableValueComparer(nullableEnumU64AsString.TypeMapping.Comparer)); - nullableEnumU64AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnumU64AsString.TypeMapping.KeyComparer)); + nullableEnumU64AsString.SetComparer(new NullableValueComparer(nullableEnumU64AsString.TypeMapping.Comparer)); + nullableEnumU64AsString.SetKeyComparer(new NullableValueComparer(nullableEnumU64AsString.TypeMapping.KeyComparer)); var nullableEnumU8 = runtimeEntityType.AddProperty( "NullableEnumU8", @@ -5075,8 +5075,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( byte (CompiledModelTestBase.EnumU8 value) => ((byte)(value)), CompiledModelTestBase.EnumU8 (byte value) => ((CompiledModelTestBase.EnumU8)(value))))); - nullableEnumU8.SetValueComparer(new NullableValueComparer(nullableEnumU8.TypeMapping.Comparer)); - nullableEnumU8.SetKeyValueComparer(new NullableValueComparer(nullableEnumU8.TypeMapping.KeyComparer)); + nullableEnumU8.SetComparer(new NullableValueComparer(nullableEnumU8.TypeMapping.Comparer)); + nullableEnumU8.SetKeyComparer(new NullableValueComparer(nullableEnumU8.TypeMapping.KeyComparer)); var nullableEnumU8AsString = runtimeEntityType.AddProperty( "NullableEnumU8AsString", @@ -5126,8 +5126,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( byte (CompiledModelTestBase.EnumU8 value) => ((byte)(value)), CompiledModelTestBase.EnumU8 (byte value) => ((CompiledModelTestBase.EnumU8)(value))))); - nullableEnumU8AsString.SetValueComparer(new NullableValueComparer(nullableEnumU8AsString.TypeMapping.Comparer)); - nullableEnumU8AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnumU8AsString.TypeMapping.KeyComparer)); + nullableEnumU8AsString.SetComparer(new NullableValueComparer(nullableEnumU8AsString.TypeMapping.Comparer)); + nullableEnumU8AsString.SetKeyComparer(new NullableValueComparer(nullableEnumU8AsString.TypeMapping.KeyComparer)); var nullableFloat = runtimeEntityType.AddProperty( "NullableFloat", @@ -5171,8 +5171,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas float (float v) => v), clrType: typeof(float), jsonValueReaderWriter: JsonFloatReaderWriter.Instance); - nullableFloat.SetValueComparer(new NullableValueComparer(nullableFloat.TypeMapping.Comparer)); - nullableFloat.SetKeyValueComparer(new NullableValueComparer(nullableFloat.TypeMapping.KeyComparer)); + nullableFloat.SetComparer(new NullableValueComparer(nullableFloat.TypeMapping.Comparer)); + nullableFloat.SetKeyComparer(new NullableValueComparer(nullableFloat.TypeMapping.KeyComparer)); var nullableFloatArray = runtimeEntityType.AddProperty( "NullableFloatArray", @@ -5280,8 +5280,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( string (Guid v) => v.ToString("D"), Guid (string v) => new Guid(v)))); - nullableGuid.SetValueComparer(new NullableValueComparer(nullableGuid.TypeMapping.Comparer)); - nullableGuid.SetKeyValueComparer(new NullableValueComparer(nullableGuid.TypeMapping.KeyComparer)); + nullableGuid.SetComparer(new NullableValueComparer(nullableGuid.TypeMapping.Comparer)); + nullableGuid.SetKeyComparer(new NullableValueComparer(nullableGuid.TypeMapping.KeyComparer)); var nullableIPAddress = runtimeEntityType.AddProperty( "NullableIPAddress", @@ -5374,8 +5374,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas short (short v) => v), clrType: typeof(short), jsonValueReaderWriter: JsonInt16ReaderWriter.Instance); - nullableInt16.SetValueComparer(new NullableValueComparer(nullableInt16.TypeMapping.Comparer)); - nullableInt16.SetKeyValueComparer(new NullableValueComparer(nullableInt16.TypeMapping.KeyComparer)); + nullableInt16.SetComparer(new NullableValueComparer(nullableInt16.TypeMapping.Comparer)); + nullableInt16.SetKeyComparer(new NullableValueComparer(nullableInt16.TypeMapping.KeyComparer)); var nullableInt16Array = runtimeEntityType.AddProperty( "NullableInt16Array", @@ -5477,8 +5477,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas int (int v) => v), clrType: typeof(int), jsonValueReaderWriter: JsonInt32ReaderWriter.Instance); - nullableInt32.SetValueComparer(new NullableValueComparer(nullableInt32.TypeMapping.Comparer)); - nullableInt32.SetKeyValueComparer(new NullableValueComparer(nullableInt32.TypeMapping.KeyComparer)); + nullableInt32.SetComparer(new NullableValueComparer(nullableInt32.TypeMapping.Comparer)); + nullableInt32.SetKeyComparer(new NullableValueComparer(nullableInt32.TypeMapping.KeyComparer)); var nullableInt32Array = runtimeEntityType.AddProperty( "NullableInt32Array", @@ -5655,8 +5655,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas long (long v) => v), clrType: typeof(long), jsonValueReaderWriter: JsonInt64ReaderWriter.Instance); - nullableInt64.SetValueComparer(new NullableValueComparer(nullableInt64.TypeMapping.Comparer)); - nullableInt64.SetKeyValueComparer(new NullableValueComparer(nullableInt64.TypeMapping.KeyComparer)); + nullableInt64.SetComparer(new NullableValueComparer(nullableInt64.TypeMapping.Comparer)); + nullableInt64.SetKeyComparer(new NullableValueComparer(nullableInt64.TypeMapping.KeyComparer)); var nullableInt64Array = runtimeEntityType.AddProperty( "NullableInt64Array", @@ -5851,8 +5851,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas sbyte (sbyte v) => v), clrType: typeof(sbyte), jsonValueReaderWriter: JsonSByteReaderWriter.Instance); - nullableInt8.SetValueComparer(new NullableValueComparer(nullableInt8.TypeMapping.Comparer)); - nullableInt8.SetKeyValueComparer(new NullableValueComparer(nullableInt8.TypeMapping.KeyComparer)); + nullableInt8.SetComparer(new NullableValueComparer(nullableInt8.TypeMapping.Comparer)); + nullableInt8.SetKeyComparer(new NullableValueComparer(nullableInt8.TypeMapping.KeyComparer)); var nullableInt8Array = runtimeEntityType.AddProperty( "NullableInt8Array", @@ -6179,8 +6179,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas TimeOnly (TimeOnly v) => v), clrType: typeof(TimeOnly), jsonValueReaderWriter: JsonTimeOnlyReaderWriter.Instance); - nullableTimeOnly.SetValueComparer(new NullableValueComparer(nullableTimeOnly.TypeMapping.Comparer)); - nullableTimeOnly.SetKeyValueComparer(new NullableValueComparer(nullableTimeOnly.TypeMapping.KeyComparer)); + nullableTimeOnly.SetComparer(new NullableValueComparer(nullableTimeOnly.TypeMapping.Comparer)); + nullableTimeOnly.SetKeyComparer(new NullableValueComparer(nullableTimeOnly.TypeMapping.KeyComparer)); var nullableTimeSpan = runtimeEntityType.AddProperty( "NullableTimeSpan", @@ -6224,8 +6224,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas TimeSpan (TimeSpan v) => v), clrType: typeof(TimeSpan), jsonValueReaderWriter: JsonTimeSpanReaderWriter.Instance); - nullableTimeSpan.SetValueComparer(new NullableValueComparer(nullableTimeSpan.TypeMapping.Comparer)); - nullableTimeSpan.SetKeyValueComparer(new NullableValueComparer(nullableTimeSpan.TypeMapping.KeyComparer)); + nullableTimeSpan.SetComparer(new NullableValueComparer(nullableTimeSpan.TypeMapping.Comparer)); + nullableTimeSpan.SetKeyComparer(new NullableValueComparer(nullableTimeSpan.TypeMapping.KeyComparer)); var nullableUInt16 = runtimeEntityType.AddProperty( "NullableUInt16", @@ -6269,8 +6269,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas ushort (ushort v) => v), clrType: typeof(ushort), jsonValueReaderWriter: JsonUInt16ReaderWriter.Instance); - nullableUInt16.SetValueComparer(new NullableValueComparer(nullableUInt16.TypeMapping.Comparer)); - nullableUInt16.SetKeyValueComparer(new NullableValueComparer(nullableUInt16.TypeMapping.KeyComparer)); + nullableUInt16.SetComparer(new NullableValueComparer(nullableUInt16.TypeMapping.Comparer)); + nullableUInt16.SetKeyComparer(new NullableValueComparer(nullableUInt16.TypeMapping.KeyComparer)); var nullableUInt16Array = runtimeEntityType.AddProperty( "NullableUInt16Array", @@ -6372,8 +6372,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas uint (uint v) => v), clrType: typeof(uint), jsonValueReaderWriter: JsonUInt32ReaderWriter.Instance); - nullableUInt32.SetValueComparer(new NullableValueComparer(nullableUInt32.TypeMapping.Comparer)); - nullableUInt32.SetKeyValueComparer(new NullableValueComparer(nullableUInt32.TypeMapping.KeyComparer)); + nullableUInt32.SetComparer(new NullableValueComparer(nullableUInt32.TypeMapping.Comparer)); + nullableUInt32.SetKeyComparer(new NullableValueComparer(nullableUInt32.TypeMapping.KeyComparer)); var nullableUInt32Array = runtimeEntityType.AddProperty( "NullableUInt32Array", @@ -6475,8 +6475,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas ulong (ulong v) => v), clrType: typeof(ulong), jsonValueReaderWriter: JsonUInt64ReaderWriter.Instance); - nullableUInt64.SetValueComparer(new NullableValueComparer(nullableUInt64.TypeMapping.Comparer)); - nullableUInt64.SetKeyValueComparer(new NullableValueComparer(nullableUInt64.TypeMapping.KeyComparer)); + nullableUInt64.SetComparer(new NullableValueComparer(nullableUInt64.TypeMapping.Comparer)); + nullableUInt64.SetKeyComparer(new NullableValueComparer(nullableUInt64.TypeMapping.KeyComparer)); var nullableUInt64Array = runtimeEntityType.AddProperty( "NullableUInt64Array", @@ -6578,8 +6578,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas byte (byte v) => v), clrType: typeof(byte), jsonValueReaderWriter: JsonByteReaderWriter.Instance); - nullableUInt8.SetValueComparer(new NullableValueComparer(nullableUInt8.TypeMapping.Comparer)); - nullableUInt8.SetKeyValueComparer(new NullableValueComparer(nullableUInt8.TypeMapping.KeyComparer)); + nullableUInt8.SetComparer(new NullableValueComparer(nullableUInt8.TypeMapping.Comparer)); + nullableUInt8.SetKeyComparer(new NullableValueComparer(nullableUInt8.TypeMapping.KeyComparer)); var nullableUInt8Array = runtimeEntityType.AddProperty( "NullableUInt8Array", @@ -8543,172 +8543,172 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var type = runtimeEntityType.FindProperty("$type")!; - var @bool = runtimeEntityType.FindProperty("Bool")!; - var boolArray = runtimeEntityType.FindProperty("BoolArray")!; - var boolNestedCollection = runtimeEntityType.FindProperty("BoolNestedCollection")!; - var boolToStringConverterProperty = runtimeEntityType.FindProperty("BoolToStringConverterProperty")!; - var boolToTwoValuesConverterProperty = runtimeEntityType.FindProperty("BoolToTwoValuesConverterProperty")!; - var boolToZeroOneConverterProperty = runtimeEntityType.FindProperty("BoolToZeroOneConverterProperty")!; - var bytes = runtimeEntityType.FindProperty("Bytes")!; - var bytesToStringConverterProperty = runtimeEntityType.FindProperty("BytesToStringConverterProperty")!; - var castingConverterProperty = runtimeEntityType.FindProperty("CastingConverterProperty")!; - var @char = runtimeEntityType.FindProperty("Char")!; - var charArray = runtimeEntityType.FindProperty("CharArray")!; - var charNestedCollection = runtimeEntityType.FindProperty("CharNestedCollection")!; - var charToStringConverterProperty = runtimeEntityType.FindProperty("CharToStringConverterProperty")!; - var dateOnly = runtimeEntityType.FindProperty("DateOnly")!; - var dateOnlyToStringConverterProperty = runtimeEntityType.FindProperty("DateOnlyToStringConverterProperty")!; - var dateTime = runtimeEntityType.FindProperty("DateTime")!; - var dateTimeOffsetToBinaryConverterProperty = runtimeEntityType.FindProperty("DateTimeOffsetToBinaryConverterProperty")!; - var dateTimeOffsetToBytesConverterProperty = runtimeEntityType.FindProperty("DateTimeOffsetToBytesConverterProperty")!; - var dateTimeOffsetToStringConverterProperty = runtimeEntityType.FindProperty("DateTimeOffsetToStringConverterProperty")!; - var dateTimeToBinaryConverterProperty = runtimeEntityType.FindProperty("DateTimeToBinaryConverterProperty")!; - var dateTimeToStringConverterProperty = runtimeEntityType.FindProperty("DateTimeToStringConverterProperty")!; - var dateTimeToTicksConverterProperty = runtimeEntityType.FindProperty("DateTimeToTicksConverterProperty")!; - var @decimal = runtimeEntityType.FindProperty("Decimal")!; - var decimalArray = runtimeEntityType.FindProperty("DecimalArray")!; - var decimalNumberToBytesConverterProperty = runtimeEntityType.FindProperty("DecimalNumberToBytesConverterProperty")!; - var decimalNumberToStringConverterProperty = runtimeEntityType.FindProperty("DecimalNumberToStringConverterProperty")!; - var @double = runtimeEntityType.FindProperty("Double")!; - var doubleArray = runtimeEntityType.FindProperty("DoubleArray")!; - var doubleNumberToBytesConverterProperty = runtimeEntityType.FindProperty("DoubleNumberToBytesConverterProperty")!; - var doubleNumberToStringConverterProperty = runtimeEntityType.FindProperty("DoubleNumberToStringConverterProperty")!; - var enum16 = runtimeEntityType.FindProperty("Enum16")!; - var enum16AsString = runtimeEntityType.FindProperty("Enum16AsString")!; - var enum32 = runtimeEntityType.FindProperty("Enum32")!; - var enum32AsString = runtimeEntityType.FindProperty("Enum32AsString")!; - var enum64 = runtimeEntityType.FindProperty("Enum64")!; - var enum64AsString = runtimeEntityType.FindProperty("Enum64AsString")!; - var enum8 = runtimeEntityType.FindProperty("Enum8")!; - var enum8AsString = runtimeEntityType.FindProperty("Enum8AsString")!; - var enumToNumberConverterProperty = runtimeEntityType.FindProperty("EnumToNumberConverterProperty")!; - var enumToStringConverterProperty = runtimeEntityType.FindProperty("EnumToStringConverterProperty")!; - var enumU16 = runtimeEntityType.FindProperty("EnumU16")!; - var enumU16AsString = runtimeEntityType.FindProperty("EnumU16AsString")!; - var enumU32 = runtimeEntityType.FindProperty("EnumU32")!; - var enumU32AsString = runtimeEntityType.FindProperty("EnumU32AsString")!; - var enumU64 = runtimeEntityType.FindProperty("EnumU64")!; - var enumU64AsString = runtimeEntityType.FindProperty("EnumU64AsString")!; - var enumU8 = runtimeEntityType.FindProperty("EnumU8")!; - var enumU8AsString = runtimeEntityType.FindProperty("EnumU8AsString")!; - var @float = runtimeEntityType.FindProperty("Float")!; - var floatArray = runtimeEntityType.FindProperty("FloatArray")!; - var guid = runtimeEntityType.FindProperty("Guid")!; - var guidToBytesConverterProperty = runtimeEntityType.FindProperty("GuidToBytesConverterProperty")!; - var guidToStringConverterProperty = runtimeEntityType.FindProperty("GuidToStringConverterProperty")!; - var iPAddress = runtimeEntityType.FindProperty("IPAddress")!; - var iPAddressToBytesConverterProperty = runtimeEntityType.FindProperty("IPAddressToBytesConverterProperty")!; - var iPAddressToStringConverterProperty = runtimeEntityType.FindProperty("IPAddressToStringConverterProperty")!; - var int16 = runtimeEntityType.FindProperty("Int16")!; - var int16Array = runtimeEntityType.FindProperty("Int16Array")!; - var int32 = runtimeEntityType.FindProperty("Int32")!; - var int32Array = runtimeEntityType.FindProperty("Int32Array")!; - var int32NestedCollection = runtimeEntityType.FindProperty("Int32NestedCollection")!; - var int64 = runtimeEntityType.FindProperty("Int64")!; - var int64Array = runtimeEntityType.FindProperty("Int64Array")!; - var int64NestedCollection = runtimeEntityType.FindProperty("Int64NestedCollection")!; - var int8 = runtimeEntityType.FindProperty("Int8")!; - var int8Array = runtimeEntityType.FindProperty("Int8Array")!; - var int8NestedCollection = runtimeEntityType.FindProperty("Int8NestedCollection")!; - var intNumberToBytesConverterProperty = runtimeEntityType.FindProperty("IntNumberToBytesConverterProperty")!; - var intNumberToStringConverterProperty = runtimeEntityType.FindProperty("IntNumberToStringConverterProperty")!; - var nullIntToNullStringConverterProperty = runtimeEntityType.FindProperty("NullIntToNullStringConverterProperty")!; - var nullableBool = runtimeEntityType.FindProperty("NullableBool")!; - var nullableBoolArray = runtimeEntityType.FindProperty("NullableBoolArray")!; - var nullableBytes = runtimeEntityType.FindProperty("NullableBytes")!; - var nullableChar = runtimeEntityType.FindProperty("NullableChar")!; - var nullableCharArray = runtimeEntityType.FindProperty("NullableCharArray")!; - var nullableDateOnly = runtimeEntityType.FindProperty("NullableDateOnly")!; - var nullableDateTime = runtimeEntityType.FindProperty("NullableDateTime")!; - var nullableDecimal = runtimeEntityType.FindProperty("NullableDecimal")!; - var nullableDecimalArray = runtimeEntityType.FindProperty("NullableDecimalArray")!; - var nullableDouble = runtimeEntityType.FindProperty("NullableDouble")!; - var nullableDoubleArray = runtimeEntityType.FindProperty("NullableDoubleArray")!; - var nullableEnum16 = runtimeEntityType.FindProperty("NullableEnum16")!; - var nullableEnum16AsString = runtimeEntityType.FindProperty("NullableEnum16AsString")!; - var nullableEnum32 = runtimeEntityType.FindProperty("NullableEnum32")!; - var nullableEnum32AsString = runtimeEntityType.FindProperty("NullableEnum32AsString")!; - var nullableEnum64 = runtimeEntityType.FindProperty("NullableEnum64")!; - var nullableEnum64AsString = runtimeEntityType.FindProperty("NullableEnum64AsString")!; - var nullableEnum8 = runtimeEntityType.FindProperty("NullableEnum8")!; - var nullableEnum8AsString = runtimeEntityType.FindProperty("NullableEnum8AsString")!; - var nullableEnumU16 = runtimeEntityType.FindProperty("NullableEnumU16")!; - var nullableEnumU16AsString = runtimeEntityType.FindProperty("NullableEnumU16AsString")!; - var nullableEnumU32 = runtimeEntityType.FindProperty("NullableEnumU32")!; - var nullableEnumU32AsString = runtimeEntityType.FindProperty("NullableEnumU32AsString")!; - var nullableEnumU64 = runtimeEntityType.FindProperty("NullableEnumU64")!; - var nullableEnumU64AsString = runtimeEntityType.FindProperty("NullableEnumU64AsString")!; - var nullableEnumU8 = runtimeEntityType.FindProperty("NullableEnumU8")!; - var nullableEnumU8AsString = runtimeEntityType.FindProperty("NullableEnumU8AsString")!; - var nullableFloat = runtimeEntityType.FindProperty("NullableFloat")!; - var nullableFloatArray = runtimeEntityType.FindProperty("NullableFloatArray")!; - var nullableGuid = runtimeEntityType.FindProperty("NullableGuid")!; - var nullableIPAddress = runtimeEntityType.FindProperty("NullableIPAddress")!; - var nullableInt16 = runtimeEntityType.FindProperty("NullableInt16")!; - var nullableInt16Array = runtimeEntityType.FindProperty("NullableInt16Array")!; - var nullableInt32 = runtimeEntityType.FindProperty("NullableInt32")!; - var nullableInt32Array = runtimeEntityType.FindProperty("NullableInt32Array")!; - var nullableInt32NestedCollection = runtimeEntityType.FindProperty("NullableInt32NestedCollection")!; - var nullableInt64 = runtimeEntityType.FindProperty("NullableInt64")!; - var nullableInt64Array = runtimeEntityType.FindProperty("NullableInt64Array")!; - var nullableInt64NestedCollection = runtimeEntityType.FindProperty("NullableInt64NestedCollection")!; - var nullableInt8 = runtimeEntityType.FindProperty("NullableInt8")!; - var nullableInt8Array = runtimeEntityType.FindProperty("NullableInt8Array")!; - var nullablePhysicalAddress = runtimeEntityType.FindProperty("NullablePhysicalAddress")!; - var nullableString = runtimeEntityType.FindProperty("NullableString")!; - var nullableStringArray = runtimeEntityType.FindProperty("NullableStringArray")!; - var nullableStringNestedCollection = runtimeEntityType.FindProperty("NullableStringNestedCollection")!; - var nullableTimeOnly = runtimeEntityType.FindProperty("NullableTimeOnly")!; - var nullableTimeSpan = runtimeEntityType.FindProperty("NullableTimeSpan")!; - var nullableUInt16 = runtimeEntityType.FindProperty("NullableUInt16")!; - var nullableUInt16Array = runtimeEntityType.FindProperty("NullableUInt16Array")!; - var nullableUInt32 = runtimeEntityType.FindProperty("NullableUInt32")!; - var nullableUInt32Array = runtimeEntityType.FindProperty("NullableUInt32Array")!; - var nullableUInt64 = runtimeEntityType.FindProperty("NullableUInt64")!; - var nullableUInt64Array = runtimeEntityType.FindProperty("NullableUInt64Array")!; - var nullableUInt8 = runtimeEntityType.FindProperty("NullableUInt8")!; - var nullableUInt8Array = runtimeEntityType.FindProperty("NullableUInt8Array")!; - var nullableUri = runtimeEntityType.FindProperty("NullableUri")!; - var physicalAddress = runtimeEntityType.FindProperty("PhysicalAddress")!; - var physicalAddressToBytesConverterProperty = runtimeEntityType.FindProperty("PhysicalAddressToBytesConverterProperty")!; - var physicalAddressToStringConverterProperty = runtimeEntityType.FindProperty("PhysicalAddressToStringConverterProperty")!; - var @string = runtimeEntityType.FindProperty("String")!; - var stringArray = runtimeEntityType.FindProperty("StringArray")!; - var stringNestedCollection = runtimeEntityType.FindProperty("StringNestedCollection")!; - var stringToBoolConverterProperty = runtimeEntityType.FindProperty("StringToBoolConverterProperty")!; - var stringToBytesConverterProperty = runtimeEntityType.FindProperty("StringToBytesConverterProperty")!; - var stringToCharConverterProperty = runtimeEntityType.FindProperty("StringToCharConverterProperty")!; - var stringToDateOnlyConverterProperty = runtimeEntityType.FindProperty("StringToDateOnlyConverterProperty")!; - var stringToDateTimeConverterProperty = runtimeEntityType.FindProperty("StringToDateTimeConverterProperty")!; - var stringToDateTimeOffsetConverterProperty = runtimeEntityType.FindProperty("StringToDateTimeOffsetConverterProperty")!; - var stringToDecimalNumberConverterProperty = runtimeEntityType.FindProperty("StringToDecimalNumberConverterProperty")!; - var stringToDoubleNumberConverterProperty = runtimeEntityType.FindProperty("StringToDoubleNumberConverterProperty")!; - var stringToEnumConverterProperty = runtimeEntityType.FindProperty("StringToEnumConverterProperty")!; - var stringToGuidConverterProperty = runtimeEntityType.FindProperty("StringToGuidConverterProperty")!; - var stringToIntNumberConverterProperty = runtimeEntityType.FindProperty("StringToIntNumberConverterProperty")!; - var stringToTimeOnlyConverterProperty = runtimeEntityType.FindProperty("StringToTimeOnlyConverterProperty")!; - var stringToTimeSpanConverterProperty = runtimeEntityType.FindProperty("StringToTimeSpanConverterProperty")!; - var stringToUriConverterProperty = runtimeEntityType.FindProperty("StringToUriConverterProperty")!; - var timeOnly = runtimeEntityType.FindProperty("TimeOnly")!; - var timeOnlyToStringConverterProperty = runtimeEntityType.FindProperty("TimeOnlyToStringConverterProperty")!; - var timeOnlyToTicksConverterProperty = runtimeEntityType.FindProperty("TimeOnlyToTicksConverterProperty")!; - var timeSpan = runtimeEntityType.FindProperty("TimeSpan")!; - var timeSpanToStringConverterProperty = runtimeEntityType.FindProperty("TimeSpanToStringConverterProperty")!; - var timeSpanToTicksConverterProperty = runtimeEntityType.FindProperty("TimeSpanToTicksConverterProperty")!; - var uInt16 = runtimeEntityType.FindProperty("UInt16")!; - var uInt16Array = runtimeEntityType.FindProperty("UInt16Array")!; - var uInt32 = runtimeEntityType.FindProperty("UInt32")!; - var uInt32Array = runtimeEntityType.FindProperty("UInt32Array")!; - var uInt64 = runtimeEntityType.FindProperty("UInt64")!; - var uInt64Array = runtimeEntityType.FindProperty("UInt64Array")!; - var uInt8 = runtimeEntityType.FindProperty("UInt8")!; - var uInt8Array = runtimeEntityType.FindProperty("UInt8Array")!; - var uri = runtimeEntityType.FindProperty("Uri")!; - var uriToStringConverterProperty = runtimeEntityType.FindProperty("UriToStringConverterProperty")!; - var __id = runtimeEntityType.FindProperty("__id")!; - var __jObject = runtimeEntityType.FindProperty("__jObject")!; + var id = runtimeEntityType.FindProperty("Id"); + var type = runtimeEntityType.FindProperty("$type"); + var @bool = runtimeEntityType.FindProperty("Bool"); + var boolArray = runtimeEntityType.FindProperty("BoolArray"); + var boolNestedCollection = runtimeEntityType.FindProperty("BoolNestedCollection"); + var boolToStringConverterProperty = runtimeEntityType.FindProperty("BoolToStringConverterProperty"); + var boolToTwoValuesConverterProperty = runtimeEntityType.FindProperty("BoolToTwoValuesConverterProperty"); + var boolToZeroOneConverterProperty = runtimeEntityType.FindProperty("BoolToZeroOneConverterProperty"); + var bytes = runtimeEntityType.FindProperty("Bytes"); + var bytesToStringConverterProperty = runtimeEntityType.FindProperty("BytesToStringConverterProperty"); + var castingConverterProperty = runtimeEntityType.FindProperty("CastingConverterProperty"); + var @char = runtimeEntityType.FindProperty("Char"); + var charArray = runtimeEntityType.FindProperty("CharArray"); + var charNestedCollection = runtimeEntityType.FindProperty("CharNestedCollection"); + var charToStringConverterProperty = runtimeEntityType.FindProperty("CharToStringConverterProperty"); + var dateOnly = runtimeEntityType.FindProperty("DateOnly"); + var dateOnlyToStringConverterProperty = runtimeEntityType.FindProperty("DateOnlyToStringConverterProperty"); + var dateTime = runtimeEntityType.FindProperty("DateTime"); + var dateTimeOffsetToBinaryConverterProperty = runtimeEntityType.FindProperty("DateTimeOffsetToBinaryConverterProperty"); + var dateTimeOffsetToBytesConverterProperty = runtimeEntityType.FindProperty("DateTimeOffsetToBytesConverterProperty"); + var dateTimeOffsetToStringConverterProperty = runtimeEntityType.FindProperty("DateTimeOffsetToStringConverterProperty"); + var dateTimeToBinaryConverterProperty = runtimeEntityType.FindProperty("DateTimeToBinaryConverterProperty"); + var dateTimeToStringConverterProperty = runtimeEntityType.FindProperty("DateTimeToStringConverterProperty"); + var dateTimeToTicksConverterProperty = runtimeEntityType.FindProperty("DateTimeToTicksConverterProperty"); + var @decimal = runtimeEntityType.FindProperty("Decimal"); + var decimalArray = runtimeEntityType.FindProperty("DecimalArray"); + var decimalNumberToBytesConverterProperty = runtimeEntityType.FindProperty("DecimalNumberToBytesConverterProperty"); + var decimalNumberToStringConverterProperty = runtimeEntityType.FindProperty("DecimalNumberToStringConverterProperty"); + var @double = runtimeEntityType.FindProperty("Double"); + var doubleArray = runtimeEntityType.FindProperty("DoubleArray"); + var doubleNumberToBytesConverterProperty = runtimeEntityType.FindProperty("DoubleNumberToBytesConverterProperty"); + var doubleNumberToStringConverterProperty = runtimeEntityType.FindProperty("DoubleNumberToStringConverterProperty"); + var enum16 = runtimeEntityType.FindProperty("Enum16"); + var enum16AsString = runtimeEntityType.FindProperty("Enum16AsString"); + var enum32 = runtimeEntityType.FindProperty("Enum32"); + var enum32AsString = runtimeEntityType.FindProperty("Enum32AsString"); + var enum64 = runtimeEntityType.FindProperty("Enum64"); + var enum64AsString = runtimeEntityType.FindProperty("Enum64AsString"); + var enum8 = runtimeEntityType.FindProperty("Enum8"); + var enum8AsString = runtimeEntityType.FindProperty("Enum8AsString"); + var enumToNumberConverterProperty = runtimeEntityType.FindProperty("EnumToNumberConverterProperty"); + var enumToStringConverterProperty = runtimeEntityType.FindProperty("EnumToStringConverterProperty"); + var enumU16 = runtimeEntityType.FindProperty("EnumU16"); + var enumU16AsString = runtimeEntityType.FindProperty("EnumU16AsString"); + var enumU32 = runtimeEntityType.FindProperty("EnumU32"); + var enumU32AsString = runtimeEntityType.FindProperty("EnumU32AsString"); + var enumU64 = runtimeEntityType.FindProperty("EnumU64"); + var enumU64AsString = runtimeEntityType.FindProperty("EnumU64AsString"); + var enumU8 = runtimeEntityType.FindProperty("EnumU8"); + var enumU8AsString = runtimeEntityType.FindProperty("EnumU8AsString"); + var @float = runtimeEntityType.FindProperty("Float"); + var floatArray = runtimeEntityType.FindProperty("FloatArray"); + var guid = runtimeEntityType.FindProperty("Guid"); + var guidToBytesConverterProperty = runtimeEntityType.FindProperty("GuidToBytesConverterProperty"); + var guidToStringConverterProperty = runtimeEntityType.FindProperty("GuidToStringConverterProperty"); + var iPAddress = runtimeEntityType.FindProperty("IPAddress"); + var iPAddressToBytesConverterProperty = runtimeEntityType.FindProperty("IPAddressToBytesConverterProperty"); + var iPAddressToStringConverterProperty = runtimeEntityType.FindProperty("IPAddressToStringConverterProperty"); + var int16 = runtimeEntityType.FindProperty("Int16"); + var int16Array = runtimeEntityType.FindProperty("Int16Array"); + var int32 = runtimeEntityType.FindProperty("Int32"); + var int32Array = runtimeEntityType.FindProperty("Int32Array"); + var int32NestedCollection = runtimeEntityType.FindProperty("Int32NestedCollection"); + var int64 = runtimeEntityType.FindProperty("Int64"); + var int64Array = runtimeEntityType.FindProperty("Int64Array"); + var int64NestedCollection = runtimeEntityType.FindProperty("Int64NestedCollection"); + var int8 = runtimeEntityType.FindProperty("Int8"); + var int8Array = runtimeEntityType.FindProperty("Int8Array"); + var int8NestedCollection = runtimeEntityType.FindProperty("Int8NestedCollection"); + var intNumberToBytesConverterProperty = runtimeEntityType.FindProperty("IntNumberToBytesConverterProperty"); + var intNumberToStringConverterProperty = runtimeEntityType.FindProperty("IntNumberToStringConverterProperty"); + var nullIntToNullStringConverterProperty = runtimeEntityType.FindProperty("NullIntToNullStringConverterProperty"); + var nullableBool = runtimeEntityType.FindProperty("NullableBool"); + var nullableBoolArray = runtimeEntityType.FindProperty("NullableBoolArray"); + var nullableBytes = runtimeEntityType.FindProperty("NullableBytes"); + var nullableChar = runtimeEntityType.FindProperty("NullableChar"); + var nullableCharArray = runtimeEntityType.FindProperty("NullableCharArray"); + var nullableDateOnly = runtimeEntityType.FindProperty("NullableDateOnly"); + var nullableDateTime = runtimeEntityType.FindProperty("NullableDateTime"); + var nullableDecimal = runtimeEntityType.FindProperty("NullableDecimal"); + var nullableDecimalArray = runtimeEntityType.FindProperty("NullableDecimalArray"); + var nullableDouble = runtimeEntityType.FindProperty("NullableDouble"); + var nullableDoubleArray = runtimeEntityType.FindProperty("NullableDoubleArray"); + var nullableEnum16 = runtimeEntityType.FindProperty("NullableEnum16"); + var nullableEnum16AsString = runtimeEntityType.FindProperty("NullableEnum16AsString"); + var nullableEnum32 = runtimeEntityType.FindProperty("NullableEnum32"); + var nullableEnum32AsString = runtimeEntityType.FindProperty("NullableEnum32AsString"); + var nullableEnum64 = runtimeEntityType.FindProperty("NullableEnum64"); + var nullableEnum64AsString = runtimeEntityType.FindProperty("NullableEnum64AsString"); + var nullableEnum8 = runtimeEntityType.FindProperty("NullableEnum8"); + var nullableEnum8AsString = runtimeEntityType.FindProperty("NullableEnum8AsString"); + var nullableEnumU16 = runtimeEntityType.FindProperty("NullableEnumU16"); + var nullableEnumU16AsString = runtimeEntityType.FindProperty("NullableEnumU16AsString"); + var nullableEnumU32 = runtimeEntityType.FindProperty("NullableEnumU32"); + var nullableEnumU32AsString = runtimeEntityType.FindProperty("NullableEnumU32AsString"); + var nullableEnumU64 = runtimeEntityType.FindProperty("NullableEnumU64"); + var nullableEnumU64AsString = runtimeEntityType.FindProperty("NullableEnumU64AsString"); + var nullableEnumU8 = runtimeEntityType.FindProperty("NullableEnumU8"); + var nullableEnumU8AsString = runtimeEntityType.FindProperty("NullableEnumU8AsString"); + var nullableFloat = runtimeEntityType.FindProperty("NullableFloat"); + var nullableFloatArray = runtimeEntityType.FindProperty("NullableFloatArray"); + var nullableGuid = runtimeEntityType.FindProperty("NullableGuid"); + var nullableIPAddress = runtimeEntityType.FindProperty("NullableIPAddress"); + var nullableInt16 = runtimeEntityType.FindProperty("NullableInt16"); + var nullableInt16Array = runtimeEntityType.FindProperty("NullableInt16Array"); + var nullableInt32 = runtimeEntityType.FindProperty("NullableInt32"); + var nullableInt32Array = runtimeEntityType.FindProperty("NullableInt32Array"); + var nullableInt32NestedCollection = runtimeEntityType.FindProperty("NullableInt32NestedCollection"); + var nullableInt64 = runtimeEntityType.FindProperty("NullableInt64"); + var nullableInt64Array = runtimeEntityType.FindProperty("NullableInt64Array"); + var nullableInt64NestedCollection = runtimeEntityType.FindProperty("NullableInt64NestedCollection"); + var nullableInt8 = runtimeEntityType.FindProperty("NullableInt8"); + var nullableInt8Array = runtimeEntityType.FindProperty("NullableInt8Array"); + var nullablePhysicalAddress = runtimeEntityType.FindProperty("NullablePhysicalAddress"); + var nullableString = runtimeEntityType.FindProperty("NullableString"); + var nullableStringArray = runtimeEntityType.FindProperty("NullableStringArray"); + var nullableStringNestedCollection = runtimeEntityType.FindProperty("NullableStringNestedCollection"); + var nullableTimeOnly = runtimeEntityType.FindProperty("NullableTimeOnly"); + var nullableTimeSpan = runtimeEntityType.FindProperty("NullableTimeSpan"); + var nullableUInt16 = runtimeEntityType.FindProperty("NullableUInt16"); + var nullableUInt16Array = runtimeEntityType.FindProperty("NullableUInt16Array"); + var nullableUInt32 = runtimeEntityType.FindProperty("NullableUInt32"); + var nullableUInt32Array = runtimeEntityType.FindProperty("NullableUInt32Array"); + var nullableUInt64 = runtimeEntityType.FindProperty("NullableUInt64"); + var nullableUInt64Array = runtimeEntityType.FindProperty("NullableUInt64Array"); + var nullableUInt8 = runtimeEntityType.FindProperty("NullableUInt8"); + var nullableUInt8Array = runtimeEntityType.FindProperty("NullableUInt8Array"); + var nullableUri = runtimeEntityType.FindProperty("NullableUri"); + var physicalAddress = runtimeEntityType.FindProperty("PhysicalAddress"); + var physicalAddressToBytesConverterProperty = runtimeEntityType.FindProperty("PhysicalAddressToBytesConverterProperty"); + var physicalAddressToStringConverterProperty = runtimeEntityType.FindProperty("PhysicalAddressToStringConverterProperty"); + var @string = runtimeEntityType.FindProperty("String"); + var stringArray = runtimeEntityType.FindProperty("StringArray"); + var stringNestedCollection = runtimeEntityType.FindProperty("StringNestedCollection"); + var stringToBoolConverterProperty = runtimeEntityType.FindProperty("StringToBoolConverterProperty"); + var stringToBytesConverterProperty = runtimeEntityType.FindProperty("StringToBytesConverterProperty"); + var stringToCharConverterProperty = runtimeEntityType.FindProperty("StringToCharConverterProperty"); + var stringToDateOnlyConverterProperty = runtimeEntityType.FindProperty("StringToDateOnlyConverterProperty"); + var stringToDateTimeConverterProperty = runtimeEntityType.FindProperty("StringToDateTimeConverterProperty"); + var stringToDateTimeOffsetConverterProperty = runtimeEntityType.FindProperty("StringToDateTimeOffsetConverterProperty"); + var stringToDecimalNumberConverterProperty = runtimeEntityType.FindProperty("StringToDecimalNumberConverterProperty"); + var stringToDoubleNumberConverterProperty = runtimeEntityType.FindProperty("StringToDoubleNumberConverterProperty"); + var stringToEnumConverterProperty = runtimeEntityType.FindProperty("StringToEnumConverterProperty"); + var stringToGuidConverterProperty = runtimeEntityType.FindProperty("StringToGuidConverterProperty"); + var stringToIntNumberConverterProperty = runtimeEntityType.FindProperty("StringToIntNumberConverterProperty"); + var stringToTimeOnlyConverterProperty = runtimeEntityType.FindProperty("StringToTimeOnlyConverterProperty"); + var stringToTimeSpanConverterProperty = runtimeEntityType.FindProperty("StringToTimeSpanConverterProperty"); + var stringToUriConverterProperty = runtimeEntityType.FindProperty("StringToUriConverterProperty"); + var timeOnly = runtimeEntityType.FindProperty("TimeOnly"); + var timeOnlyToStringConverterProperty = runtimeEntityType.FindProperty("TimeOnlyToStringConverterProperty"); + var timeOnlyToTicksConverterProperty = runtimeEntityType.FindProperty("TimeOnlyToTicksConverterProperty"); + var timeSpan = runtimeEntityType.FindProperty("TimeSpan"); + var timeSpanToStringConverterProperty = runtimeEntityType.FindProperty("TimeSpanToStringConverterProperty"); + var timeSpanToTicksConverterProperty = runtimeEntityType.FindProperty("TimeSpanToTicksConverterProperty"); + var uInt16 = runtimeEntityType.FindProperty("UInt16"); + var uInt16Array = runtimeEntityType.FindProperty("UInt16Array"); + var uInt32 = runtimeEntityType.FindProperty("UInt32"); + var uInt32Array = runtimeEntityType.FindProperty("UInt32Array"); + var uInt64 = runtimeEntityType.FindProperty("UInt64"); + var uInt64Array = runtimeEntityType.FindProperty("UInt64Array"); + var uInt8 = runtimeEntityType.FindProperty("UInt8"); + var uInt8Array = runtimeEntityType.FindProperty("UInt8Array"); + var uri = runtimeEntityType.FindProperty("Uri"); + var uriToStringConverterProperty = runtimeEntityType.FindProperty("UriToStringConverterProperty"); + var __id = runtimeEntityType.FindProperty("__id"); + var __jObject = runtimeEntityType.FindProperty("__jObject"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); diff --git a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedType0EntityType.cs b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedType0EntityType.cs index bfb0f636ee8..bbb9a7fee83 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedType0EntityType.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedType0EntityType.cs @@ -688,18 +688,18 @@ public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEnt public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var principalDerivedId = runtimeEntityType.FindProperty("PrincipalDerivedId")!; - var principalDerivedAlternateId = runtimeEntityType.FindProperty("PrincipalDerivedAlternateId")!; - var id = runtimeEntityType.FindProperty("Id")!; - var details = runtimeEntityType.FindProperty("Details")!; - var number = runtimeEntityType.FindProperty("Number")!; - var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable")!; - var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList")!; - var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList")!; - var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList")!; - var __jObject = runtimeEntityType.FindProperty("__jObject")!; + var principalDerivedId = runtimeEntityType.FindProperty("PrincipalDerivedId"); + var principalDerivedAlternateId = runtimeEntityType.FindProperty("PrincipalDerivedAlternateId"); + var id = runtimeEntityType.FindProperty("Id"); + var details = runtimeEntityType.FindProperty("Details"); + var number = runtimeEntityType.FindProperty("Number"); + var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable"); + var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList"); + var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList"); + var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList"); + var __jObject = runtimeEntityType.FindProperty("__jObject"); var key = runtimeEntityType.FindKey(new[] { principalDerivedId, principalDerivedAlternateId, id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateCompositeFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory>(key)); diff --git a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedTypeEntityType.cs b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedTypeEntityType.cs index e42e580935b..163d430ba70 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedTypeEntityType.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedTypeEntityType.cs @@ -662,17 +662,17 @@ public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEnt public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var principalBaseId = runtimeEntityType.FindProperty("PrincipalBaseId")!; - var principalBaseAlternateId = runtimeEntityType.FindProperty("PrincipalBaseAlternateId")!; - var details = runtimeEntityType.FindProperty("Details")!; - var number = runtimeEntityType.FindProperty("Number")!; - var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable")!; - var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList")!; - var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList")!; - var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList")!; - var __jObject = runtimeEntityType.FindProperty("__jObject")!; + var principalBaseId = runtimeEntityType.FindProperty("PrincipalBaseId"); + var principalBaseAlternateId = runtimeEntityType.FindProperty("PrincipalBaseAlternateId"); + var details = runtimeEntityType.FindProperty("Details"); + var number = runtimeEntityType.FindProperty("Number"); + var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable"); + var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList"); + var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList"); + var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList"); + var __jObject = runtimeEntityType.FindProperty("__jObject"); var key = runtimeEntityType.FindKey(new[] { principalBaseId, principalBaseAlternateId }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateCompositeFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory>(key)); diff --git a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBaseEntityType.cs b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBaseEntityType.cs index aec8bc43c35..5ffd77d0bbf 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBaseEntityType.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBaseEntityType.cs @@ -83,9 +83,9 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas long (long v) => v), clrType: typeof(long), jsonValueReaderWriter: JsonInt64ReaderWriter.Instance); - id.SetValueComparer(new NullableValueComparer(id.TypeMapping.Comparer)); - id.SetKeyValueComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); id.SetCurrentValueComparer(new EntryCurrentValueComparer(id)); + id.SetComparer(new NullableValueComparer(id.TypeMapping.Comparer)); + id.SetKeyComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); var alternateId = runtimeEntityType.AddProperty( "AlternateId", @@ -265,8 +265,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( int (CompiledModelTestBase.AnEnum value) => ((int)(value)), CompiledModelTestBase.AnEnum (int value) => ((CompiledModelTestBase.AnEnum)(value))))); - enum2.SetValueComparer(new NullableValueComparer(enum2.TypeMapping.Comparer)); - enum2.SetKeyValueComparer(new NullableValueComparer(enum2.TypeMapping.KeyComparer)); + enum2.SetComparer(new NullableValueComparer(enum2.TypeMapping.Comparer)); + enum2.SetKeyComparer(new NullableValueComparer(enum2.TypeMapping.KeyComparer)); var flagsEnum1 = runtimeEntityType.AddProperty( "FlagsEnum1", @@ -851,28 +851,28 @@ public static RuntimeSkipNavigation CreateSkipNavigation1(RuntimeEntityType decl public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var alternateId = runtimeEntityType.FindProperty("AlternateId")!; - var type = runtimeEntityType.FindProperty("$type")!; - var enum1 = runtimeEntityType.FindProperty("Enum1")!; - var enum2 = runtimeEntityType.FindProperty("Enum2")!; - var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1")!; - var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2")!; - var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable")!; - var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList")!; - var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList")!; - var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList")!; - var __id = runtimeEntityType.FindProperty("__id")!; - var __jObject = runtimeEntityType.FindProperty("__jObject")!; + var id = runtimeEntityType.FindProperty("Id"); + var alternateId = runtimeEntityType.FindProperty("AlternateId"); + var type = runtimeEntityType.FindProperty("$type"); + var enum1 = runtimeEntityType.FindProperty("Enum1"); + var enum2 = runtimeEntityType.FindProperty("Enum2"); + var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1"); + var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2"); + var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable"); + var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList"); + var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList"); + var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList"); + var __id = runtimeEntityType.FindProperty("__id"); + var __jObject = runtimeEntityType.FindProperty("__jObject"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); var key0 = runtimeEntityType.FindKey(new[] { id, alternateId }); key0.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateCompositeFactory(key0)); key0.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory>(key0)); - var owned = runtimeEntityType.FindNavigation("Owned")!; + var owned = runtimeEntityType.FindNavigation("Owned"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { @@ -891,7 +891,7 @@ public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) ISnapshot (InternalEntityEntry source) => { var entity5 = ((CompiledModelTestBase.PrincipalBase)(source.Entity)); - return ((ISnapshot)(new Snapshot((source.GetCurrentValue(id) == null ? null : ((ValueComparer)(((IProperty)id).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(id))), ((ValueComparer)(((IProperty)alternateId).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(alternateId)), PrincipalBaseUnsafeAccessors._ownedField(entity5), null))); + return ((ISnapshot)(new Snapshot((source.GetCurrentValue(id) == null ? null : ((ValueComparer)(((IProperty)id).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(id))), ((ValueComparer)(((IProperty)alternateId).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(alternateId)), PrincipalBaseUnsafeAccessors._ownedField(entity5), (object)(null)))); }); runtimeEntityType.Counts = new PropertyCounts( propertyCount: 15, diff --git a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs index 8cb4a6311c0..ee2cc478e48 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs @@ -532,14 +532,14 @@ public static RuntimeForeignKey CreateForeignKey2(RuntimeEntityType declaringEnt public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var derivedsId = runtimeEntityType.FindProperty("DerivedsId")!; - var derivedsAlternateId = runtimeEntityType.FindProperty("DerivedsAlternateId")!; - var principalsId = runtimeEntityType.FindProperty("PrincipalsId")!; - var principalsAlternateId = runtimeEntityType.FindProperty("PrincipalsAlternateId")!; - var type = runtimeEntityType.FindProperty("$type")!; - var __id = runtimeEntityType.FindProperty("__id")!; - var __jObject = runtimeEntityType.FindProperty("__jObject")!; - var rowid = runtimeEntityType.FindProperty("rowid")!; + var derivedsId = runtimeEntityType.FindProperty("DerivedsId"); + var derivedsAlternateId = runtimeEntityType.FindProperty("DerivedsAlternateId"); + var principalsId = runtimeEntityType.FindProperty("PrincipalsId"); + var principalsAlternateId = runtimeEntityType.FindProperty("PrincipalsAlternateId"); + var type = runtimeEntityType.FindProperty("$type"); + var __id = runtimeEntityType.FindProperty("__id"); + var __jObject = runtimeEntityType.FindProperty("__jObject"); + var rowid = runtimeEntityType.FindProperty("rowid"); var key = runtimeEntityType.FindKey(new[] { derivedsId, derivedsAlternateId, principalsId, principalsAlternateId }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateCompositeFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory>(key)); diff --git a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalDerivedEntityType.cs b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalDerivedEntityType.cs index e832cd63fa2..25b8ec20c57 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalDerivedEntityType.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalDerivedEntityType.cs @@ -87,24 +87,24 @@ public static RuntimeSkipNavigation CreateSkipNavigation1(RuntimeEntityType decl public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var alternateId = runtimeEntityType.FindProperty("AlternateId")!; - var type = runtimeEntityType.FindProperty("$type")!; - var enum1 = runtimeEntityType.FindProperty("Enum1")!; - var enum2 = runtimeEntityType.FindProperty("Enum2")!; - var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1")!; - var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2")!; - var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable")!; - var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList")!; - var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList")!; - var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList")!; - var __id = runtimeEntityType.FindProperty("__id")!; - var __jObject = runtimeEntityType.FindProperty("__jObject")!; - var owned = runtimeEntityType.FindNavigation("Owned")!; - var dependent = runtimeEntityType.FindNavigation("Dependent")!; - var manyOwned = runtimeEntityType.FindNavigation("ManyOwned")!; + var id = runtimeEntityType.FindProperty("Id"); + var alternateId = runtimeEntityType.FindProperty("AlternateId"); + var type = runtimeEntityType.FindProperty("$type"); + var enum1 = runtimeEntityType.FindProperty("Enum1"); + var enum2 = runtimeEntityType.FindProperty("Enum2"); + var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1"); + var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2"); + var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable"); + var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList"); + var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList"); + var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList"); + var __id = runtimeEntityType.FindProperty("__id"); + var __jObject = runtimeEntityType.FindProperty("__jObject"); + var owned = runtimeEntityType.FindNavigation("Owned"); + var dependent = runtimeEntityType.FindNavigation("Dependent"); + var manyOwned = runtimeEntityType.FindNavigation("ManyOwned"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { @@ -123,7 +123,7 @@ public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) ISnapshot (InternalEntityEntry source) => { var entity5 = ((CompiledModelTestBase.PrincipalDerived>)(source.Entity)); - return ((ISnapshot)(new Snapshot((source.GetCurrentValue(id) == null ? null : ((ValueComparer)(((IProperty)id).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(id))), ((ValueComparer)(((IProperty)alternateId).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(alternateId)), PrincipalBaseUnsafeAccessors._ownedField(entity5), null, PrincipalDerivedUnsafeAccessors>.Dependent(entity5), SnapshotFactoryFactory.SnapshotCollection(PrincipalDerivedUnsafeAccessors>.ManyOwned(entity5)), null))); + return ((ISnapshot)(new Snapshot((source.GetCurrentValue(id) == null ? null : ((ValueComparer)(((IProperty)id).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(id))), ((ValueComparer)(((IProperty)alternateId).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(alternateId)), PrincipalBaseUnsafeAccessors._ownedField(entity5), (object)(null), PrincipalDerivedUnsafeAccessors>.Dependent(entity5), SnapshotFactoryFactory.SnapshotCollection(PrincipalDerivedUnsafeAccessors>.ManyOwned(entity5)), (object)(null)))); }); runtimeEntityType.Counts = new PropertyCounts( propertyCount: 15, diff --git a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalBaseEntityType.cs b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalBaseEntityType.cs index 7e549c3bd30..2313b2c5705 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalBaseEntityType.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalBaseEntityType.cs @@ -84,9 +84,9 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas long (long v) => v), clrType: typeof(long), jsonValueReaderWriter: JsonInt64ReaderWriter.Instance); - id.SetValueComparer(new NullableValueComparer(id.TypeMapping.Comparer)); - id.SetKeyValueComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); id.SetCurrentValueComparer(new EntryCurrentValueComparer(id)); + id.SetComparer(new NullableValueComparer(id.TypeMapping.Comparer)); + id.SetKeyComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); var type = runtimeEntityType.AddProperty( "$type", @@ -218,8 +218,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( int (CompiledModelTestBase.AnEnum value) => ((int)(value)), CompiledModelTestBase.AnEnum (int value) => ((CompiledModelTestBase.AnEnum)(value))))); - enum2.SetValueComparer(new NullableValueComparer(enum2.TypeMapping.Comparer)); - enum2.SetKeyValueComparer(new NullableValueComparer(enum2.TypeMapping.KeyComparer)); + enum2.SetComparer(new NullableValueComparer(enum2.TypeMapping.Comparer)); + enum2.SetKeyComparer(new NullableValueComparer(enum2.TypeMapping.KeyComparer)); var flagsEnum1 = runtimeEntityType.AddProperty( "FlagsEnum1", @@ -350,9 +350,9 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas long (long v) => v), clrType: typeof(long), jsonValueReaderWriter: JsonInt64ReaderWriter.Instance); - principalBaseId.SetValueComparer(new NullableValueComparer(principalBaseId.TypeMapping.Comparer)); - principalBaseId.SetKeyValueComparer(new NullableValueComparer(principalBaseId.TypeMapping.KeyComparer)); principalBaseId.SetCurrentValueComparer(new EntryCurrentValueComparer(principalBaseId)); + principalBaseId.SetComparer(new NullableValueComparer(principalBaseId.TypeMapping.Comparer)); + principalBaseId.SetKeyComparer(new NullableValueComparer(principalBaseId.TypeMapping.KeyComparer)); var refTypeEnumerable = runtimeEntityType.AddProperty( "RefTypeEnumerable", @@ -1553,8 +1553,8 @@ public static RuntimeComplexProperty Create(RuntimeComplexType declaringType) new ValueConverter( int (CompiledModelTestBase.AnEnum value) => ((int)(value)), CompiledModelTestBase.AnEnum (int value) => ((CompiledModelTestBase.AnEnum)(value))))); - enum2.SetValueComparer(new NullableValueComparer(enum2.TypeMapping.Comparer)); - enum2.SetKeyValueComparer(new NullableValueComparer(enum2.TypeMapping.KeyComparer)); + enum2.SetComparer(new NullableValueComparer(enum2.TypeMapping.Comparer)); + enum2.SetKeyComparer(new NullableValueComparer(enum2.TypeMapping.KeyComparer)); var flagsEnum1 = complexType.AddProperty( "FlagsEnum1", @@ -1726,8 +1726,8 @@ public static RuntimeComplexProperty Create(RuntimeComplexType declaringType) long (long v) => v), clrType: typeof(long), jsonValueReaderWriter: JsonInt64ReaderWriter.Instance); - id.SetValueComparer(new NullableValueComparer(id.TypeMapping.Comparer)); - id.SetKeyValueComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); + id.SetComparer(new NullableValueComparer(id.TypeMapping.Comparer)); + id.SetKeyComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); var refTypeEnumerable = complexType.AddProperty( "RefTypeEnumerable", @@ -2193,49 +2193,49 @@ public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEnt public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var type = runtimeEntityType.FindProperty("$type")!; - var enum1 = runtimeEntityType.FindProperty("Enum1")!; - var enum2 = runtimeEntityType.FindProperty("Enum2")!; - var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1")!; - var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2")!; - var principalBaseId = runtimeEntityType.FindProperty("PrincipalBaseId")!; - var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable")!; - var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList")!; - var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList")!; - var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList")!; - var __id = runtimeEntityType.FindProperty("__id")!; - var __jObject = runtimeEntityType.FindProperty("__jObject")!; - var owned = runtimeEntityType.FindComplexProperty("Owned")!; + var id = runtimeEntityType.FindProperty("Id"); + var type = runtimeEntityType.FindProperty("$type"); + var enum1 = runtimeEntityType.FindProperty("Enum1"); + var enum2 = runtimeEntityType.FindProperty("Enum2"); + var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1"); + var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2"); + var principalBaseId = runtimeEntityType.FindProperty("PrincipalBaseId"); + var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable"); + var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList"); + var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList"); + var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList"); + var __id = runtimeEntityType.FindProperty("__id"); + var __jObject = runtimeEntityType.FindProperty("__jObject"); + var owned = runtimeEntityType.FindComplexProperty("Owned"); var ownedType = owned.ComplexType; - var details = ownedType.FindProperty("Details")!; - var number = ownedType.FindProperty("Number")!; - var refTypeEnumerable0 = ownedType.FindProperty("RefTypeEnumerable")!; - var refTypeIList0 = ownedType.FindProperty("RefTypeIList")!; - var valueTypeArray0 = ownedType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable0 = ownedType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList0 = ownedType.FindProperty("ValueTypeIList")!; - var valueTypeList0 = ownedType.FindProperty("ValueTypeList")!; - var principal = ownedType.FindComplexProperty("Principal")!; + var details = ownedType.FindProperty("Details"); + var number = ownedType.FindProperty("Number"); + var refTypeEnumerable0 = ownedType.FindProperty("RefTypeEnumerable"); + var refTypeIList0 = ownedType.FindProperty("RefTypeIList"); + var valueTypeArray0 = ownedType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable0 = ownedType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList0 = ownedType.FindProperty("ValueTypeIList"); + var valueTypeList0 = ownedType.FindProperty("ValueTypeList"); + var principal = ownedType.FindComplexProperty("Principal"); var principalBase = principal.ComplexType; - var alternateId = principalBase.FindProperty("AlternateId")!; - var enum10 = principalBase.FindProperty("Enum1")!; - var enum20 = principalBase.FindProperty("Enum2")!; - var flagsEnum10 = principalBase.FindProperty("FlagsEnum1")!; - var flagsEnum20 = principalBase.FindProperty("FlagsEnum2")!; - var id0 = principalBase.FindProperty("Id")!; - var refTypeEnumerable1 = principalBase.FindProperty("RefTypeEnumerable")!; - var refTypeIList1 = principalBase.FindProperty("RefTypeIList")!; - var valueTypeArray1 = principalBase.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable1 = principalBase.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList1 = principalBase.FindProperty("ValueTypeIList")!; - var valueTypeList1 = principalBase.FindProperty("ValueTypeList")!; + var alternateId = principalBase.FindProperty("AlternateId"); + var enum10 = principalBase.FindProperty("Enum1"); + var enum20 = principalBase.FindProperty("Enum2"); + var flagsEnum10 = principalBase.FindProperty("FlagsEnum1"); + var flagsEnum20 = principalBase.FindProperty("FlagsEnum2"); + var id0 = principalBase.FindProperty("Id"); + var refTypeEnumerable1 = principalBase.FindProperty("RefTypeEnumerable"); + var refTypeIList1 = principalBase.FindProperty("RefTypeIList"); + var valueTypeArray1 = principalBase.FindProperty("ValueTypeArray"); + var valueTypeEnumerable1 = principalBase.FindProperty("ValueTypeEnumerable"); + var valueTypeIList1 = principalBase.FindProperty("ValueTypeIList"); + var valueTypeList1 = principalBase.FindProperty("ValueTypeList"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); - var deriveds = runtimeEntityType.FindNavigation("Deriveds")!; + var deriveds = runtimeEntityType.FindNavigation("Deriveds"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { diff --git a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalDerivedEntityType.cs b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalDerivedEntityType.cs index 56d2e799fe1..73837503884 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalDerivedEntityType.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalDerivedEntityType.cs @@ -33,46 +33,46 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var type = runtimeEntityType.FindProperty("$type")!; - var enum1 = runtimeEntityType.FindProperty("Enum1")!; - var enum2 = runtimeEntityType.FindProperty("Enum2")!; - var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1")!; - var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2")!; - var principalBaseId = runtimeEntityType.FindProperty("PrincipalBaseId")!; - var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable")!; - var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList")!; - var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList")!; - var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList")!; - var __id = runtimeEntityType.FindProperty("__id")!; - var __jObject = runtimeEntityType.FindProperty("__jObject")!; - var owned = runtimeEntityType.FindComplexProperty("Owned")!; + var id = runtimeEntityType.FindProperty("Id"); + var type = runtimeEntityType.FindProperty("$type"); + var enum1 = runtimeEntityType.FindProperty("Enum1"); + var enum2 = runtimeEntityType.FindProperty("Enum2"); + var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1"); + var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2"); + var principalBaseId = runtimeEntityType.FindProperty("PrincipalBaseId"); + var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable"); + var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList"); + var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList"); + var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList"); + var __id = runtimeEntityType.FindProperty("__id"); + var __jObject = runtimeEntityType.FindProperty("__jObject"); + var owned = runtimeEntityType.FindComplexProperty("Owned"); var ownedType = owned.ComplexType; - var details = ownedType.FindProperty("Details")!; - var number = ownedType.FindProperty("Number")!; - var refTypeEnumerable0 = ownedType.FindProperty("RefTypeEnumerable")!; - var refTypeIList0 = ownedType.FindProperty("RefTypeIList")!; - var valueTypeArray0 = ownedType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable0 = ownedType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList0 = ownedType.FindProperty("ValueTypeIList")!; - var valueTypeList0 = ownedType.FindProperty("ValueTypeList")!; - var principal = ownedType.FindComplexProperty("Principal")!; + var details = ownedType.FindProperty("Details"); + var number = ownedType.FindProperty("Number"); + var refTypeEnumerable0 = ownedType.FindProperty("RefTypeEnumerable"); + var refTypeIList0 = ownedType.FindProperty("RefTypeIList"); + var valueTypeArray0 = ownedType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable0 = ownedType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList0 = ownedType.FindProperty("ValueTypeIList"); + var valueTypeList0 = ownedType.FindProperty("ValueTypeList"); + var principal = ownedType.FindComplexProperty("Principal"); var principalBase = principal.ComplexType; - var alternateId = principalBase.FindProperty("AlternateId")!; - var enum10 = principalBase.FindProperty("Enum1")!; - var enum20 = principalBase.FindProperty("Enum2")!; - var flagsEnum10 = principalBase.FindProperty("FlagsEnum1")!; - var flagsEnum20 = principalBase.FindProperty("FlagsEnum2")!; - var id0 = principalBase.FindProperty("Id")!; - var refTypeEnumerable1 = principalBase.FindProperty("RefTypeEnumerable")!; - var refTypeIList1 = principalBase.FindProperty("RefTypeIList")!; - var valueTypeArray1 = principalBase.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable1 = principalBase.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList1 = principalBase.FindProperty("ValueTypeIList")!; - var valueTypeList1 = principalBase.FindProperty("ValueTypeList")!; - var deriveds = runtimeEntityType.FindNavigation("Deriveds")!; + var alternateId = principalBase.FindProperty("AlternateId"); + var enum10 = principalBase.FindProperty("Enum1"); + var enum20 = principalBase.FindProperty("Enum2"); + var flagsEnum10 = principalBase.FindProperty("FlagsEnum1"); + var flagsEnum20 = principalBase.FindProperty("FlagsEnum2"); + var id0 = principalBase.FindProperty("Id"); + var refTypeEnumerable1 = principalBase.FindProperty("RefTypeEnumerable"); + var refTypeIList1 = principalBase.FindProperty("RefTypeIList"); + var valueTypeArray1 = principalBase.FindProperty("ValueTypeArray"); + var valueTypeEnumerable1 = principalBase.FindProperty("ValueTypeEnumerable"); + var valueTypeIList1 = principalBase.FindProperty("ValueTypeIList"); + var valueTypeList1 = principalBase.FindProperty("ValueTypeList"); + var deriveds = runtimeEntityType.FindNavigation("Deriveds"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { diff --git a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextAssemblyAttributes.cs b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextAssemblyAttributes.cs new file mode 100644 index 00000000000..c224873f6fa --- /dev/null +++ b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextAssemblyAttributes.cs @@ -0,0 +1,9 @@ +// +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using TestNamespace; + +#pragma warning disable 219, 612, 618 +#nullable disable + +[assembly: DbContextModel(typeof(DbContext), typeof(DbContextModel))] diff --git a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextModel.cs b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextModel.cs new file mode 100644 index 00000000000..583ee4d90cc --- /dev/null +++ b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextModel.cs @@ -0,0 +1,48 @@ +// +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [DbContext(typeof(DbContext))] + public partial class DbContextModel : RuntimeModel + { + private static readonly bool _useOldBehavior31751 = + System.AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue31751", out var enabled31751) && enabled31751; + + static DbContextModel() + { + var model = new DbContextModel(); + + if (_useOldBehavior31751) + { + model.Initialize(); + } + else + { + var thread = new System.Threading.Thread(RunInitialization, 10 * 1024 * 1024); + thread.Start(); + thread.Join(); + + void RunInitialization() + { + model.Initialize(); + } + } + + model.Customize(); + _instance = (DbContextModel)model.FinalizeModel(); + } + + private static DbContextModel _instance; + public static IModel Instance => _instance; + + partial void Initialize(); + + partial void Customize(); + } +} diff --git a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextModelBuilder.cs b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextModelBuilder.cs new file mode 100644 index 00000000000..f13b59f63c7 --- /dev/null +++ b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextModelBuilder.cs @@ -0,0 +1,51 @@ +// +using System; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + public partial class DbContextModel + { + private DbContextModel() + : base(skipDetectChanges: false, modelId: new Guid("00000000-0000-0000-0000-000000000000"), entityTypeCount: 8) + { + } + + partial void Initialize() + { + var dependentBase = DependentBaseEntityType.Create(this); + var manyTypes = ManyTypesEntityType.Create(this); + var principalBase = PrincipalBaseEntityType.Create(this); + var ownedType = OwnedTypeEntityType.Create(this); + var ownedType0 = OwnedType0EntityType.Create(this); + var principalBasePrincipalDerivedDependentBasebyte = PrincipalBasePrincipalDerivedDependentBasebyteEntityType.Create(this); + var dependentDerived = DependentDerivedEntityType.Create(this, dependentBase); + var principalDerived = PrincipalDerivedEntityType.Create(this, principalBase); + + DependentBaseEntityType.CreateForeignKey1(dependentBase, principalBase); + DependentBaseEntityType.CreateForeignKey2(dependentBase, principalDerived); + OwnedTypeEntityType.CreateForeignKey1(ownedType, principalBase); + OwnedType0EntityType.CreateForeignKey1(ownedType0, principalDerived); + PrincipalBasePrincipalDerivedDependentBasebyteEntityType.CreateForeignKey1(principalBasePrincipalDerivedDependentBasebyte, principalDerived); + PrincipalBasePrincipalDerivedDependentBasebyteEntityType.CreateForeignKey2(principalBasePrincipalDerivedDependentBasebyte, principalBase); + + PrincipalBaseEntityType.CreateSkipNavigation1(principalBase, principalDerived, principalBasePrincipalDerivedDependentBasebyte); + PrincipalDerivedEntityType.CreateSkipNavigation1(principalDerived, principalBase, principalBasePrincipalDerivedDependentBasebyte); + + DependentBaseEntityType.CreateAnnotations(dependentBase); + ManyTypesEntityType.CreateAnnotations(manyTypes); + PrincipalBaseEntityType.CreateAnnotations(principalBase); + OwnedTypeEntityType.CreateAnnotations(ownedType); + OwnedType0EntityType.CreateAnnotations(ownedType0); + PrincipalBasePrincipalDerivedDependentBasebyteEntityType.CreateAnnotations(principalBasePrincipalDerivedDependentBasebyte); + DependentDerivedEntityType.CreateAnnotations(dependentDerived); + PrincipalDerivedEntityType.CreateAnnotations(principalDerived); + + AddAnnotation("Cosmos:ContainerName", "DbContext"); + } + } +} diff --git a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DependentBaseEntityType.cs b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DependentBaseEntityType.cs new file mode 100644 index 00000000000..21acbb976d6 --- /dev/null +++ b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DependentBaseEntityType.cs @@ -0,0 +1,130 @@ +// +using System; +using System.Reflection; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Cosmos.ValueGeneration.Internal; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; +using Microsoft.EntityFrameworkCore.ValueGeneration; +using Newtonsoft.Json.Linq; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class DependentBaseEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+DependentBase", + typeof(CompiledModelTestBase.DependentBase), + baseEntityType, + discriminatorProperty: "EnumDiscriminator", + discriminatorValue: CompiledModelTestBase.Enum1.One, + derivedTypesCount: 1, + propertyCount: 6, + navigationCount: 1, + foreignKeyCount: 2, + keyCount: 1); + + var principalId = runtimeEntityType.AddProperty( + "PrincipalId", + typeof(long), + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: 0L); + + var principalAlternateId = runtimeEntityType.AddProperty( + "PrincipalAlternateId", + typeof(Guid), + afterSaveBehavior: PropertySaveBehavior.Throw); + principalAlternateId.SetSentinelFromProviderValue("00000000-0000-0000-0000-000000000000"); + + var enumDiscriminator = runtimeEntityType.AddProperty( + "EnumDiscriminator", + typeof(CompiledModelTestBase.Enum1), + afterSaveBehavior: PropertySaveBehavior.Throw, + valueGeneratorFactory: new DiscriminatorValueGeneratorFactory().Create); + enumDiscriminator.SetSentinelFromProviderValue(0); + + var id = runtimeEntityType.AddProperty( + "Id", + typeof(byte?), + propertyInfo: typeof(CompiledModelTestBase.DependentBase).GetProperty("Id", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.DependentBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var __id = runtimeEntityType.AddProperty( + "__id", + typeof(string), + afterSaveBehavior: PropertySaveBehavior.Throw, + valueGeneratorFactory: new IdValueGeneratorFactory().Create); + __id.AddAnnotation("Cosmos:PropertyName", "id"); + + var __jObject = runtimeEntityType.AddProperty( + "__jObject", + typeof(JObject), + nullable: true); + __jObject.AddAnnotation("Cosmos:PropertyName", ""); + + var key = runtimeEntityType.AddKey( + new[] { principalId, principalAlternateId }); + runtimeEntityType.SetPrimaryKey(key); + + return runtimeEntityType; + } + + public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("PrincipalId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("Id") }), + principalEntityType, + deleteBehavior: DeleteBehavior.Cascade, + unique: true, + required: true); + + return runtimeForeignKey; + } + + public static RuntimeForeignKey CreateForeignKey2(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("PrincipalId"), declaringEntityType.FindProperty("PrincipalAlternateId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("Id"), principalEntityType.FindProperty("AlternateId") }), + principalEntityType, + deleteBehavior: DeleteBehavior.ClientNoAction, + unique: true, + required: true); + + var principal = declaringEntityType.AddNavigation("Principal", + runtimeForeignKey, + onDependent: true, + typeof(CompiledModelTestBase.PrincipalDerived>), + propertyInfo: typeof(CompiledModelTestBase.DependentBase).GetProperty("Principal", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.DependentBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var dependent = principalEntityType.AddNavigation("Dependent", + runtimeForeignKey, + onDependent: false, + typeof(CompiledModelTestBase.DependentBase), + propertyInfo: typeof(CompiledModelTestBase.PrincipalDerived>).GetProperty("Dependent", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalDerived>).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + eagerLoaded: true, + lazyLoadingEnabled: false); + + return runtimeForeignKey; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + runtimeEntityType.AddAnnotation("Cosmos:ContainerName", "Dependents"); + runtimeEntityType.AddAnnotation("DiscriminatorMappingComplete", false); + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DependentDerivedEntityType.cs b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DependentDerivedEntityType.cs new file mode 100644 index 00000000000..0a376130e14 --- /dev/null +++ b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DependentDerivedEntityType.cs @@ -0,0 +1,54 @@ +// +using System; +using System.Reflection; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class DependentDerivedEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+DependentDerived", + typeof(CompiledModelTestBase.DependentDerived), + baseEntityType, + discriminatorProperty: "EnumDiscriminator", + discriminatorValue: CompiledModelTestBase.Enum1.Two, + propertyCount: 2); + + var data = runtimeEntityType.AddProperty( + "Data", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.DependentDerived).GetProperty("Data", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.DependentDerived).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true, + maxLength: 20, + unicode: false); + + var money = runtimeEntityType.AddProperty( + "Money", + typeof(decimal), + precision: 9, + scale: 3, + sentinel: 0m); + + return runtimeEntityType; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + runtimeEntityType.AddAnnotation("DiscriminatorMappingComplete", false); + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/ManyTypesEntityType.cs b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/ManyTypesEntityType.cs new file mode 100644 index 00000000000..2d447e1dba5 --- /dev/null +++ b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/ManyTypesEntityType.cs @@ -0,0 +1,1236 @@ +// +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.NetworkInformation; +using System.Reflection; +using System.Text; +using Microsoft.EntityFrameworkCore.ChangeTracking; +using Microsoft.EntityFrameworkCore.Cosmos.Storage.Internal; +using Microsoft.EntityFrameworkCore.Cosmos.ValueGeneration.Internal; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; +using Microsoft.EntityFrameworkCore.Storage.Json; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Microsoft.EntityFrameworkCore.ValueGeneration; +using Newtonsoft.Json.Linq; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class ManyTypesEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+ManyTypes", + typeof(CompiledModelTestBase.ManyTypes), + baseEntityType, + discriminatorProperty: "$type", + discriminatorValue: "ManyTypes", + propertyCount: 166, + keyCount: 1); + + var id = runtimeEntityType.AddProperty( + "Id", + typeof(CompiledModelTestBase.ManyTypesId), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Id", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueGenerated: ValueGenerated.OnAdd, + afterSaveBehavior: PropertySaveBehavior.Throw, + valueConverter: new CompiledModelTestBase.ManyTypesIdConverter()); + id.SetSentinelFromProviderValue(0); + + var type = runtimeEntityType.AddProperty( + "$type", + typeof(string), + afterSaveBehavior: PropertySaveBehavior.Throw, + valueGeneratorFactory: new DiscriminatorValueGeneratorFactory().Create); + + var @bool = runtimeEntityType.AddProperty( + "Bool", + typeof(bool), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Bool", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: false); + + var boolArray = runtimeEntityType.AddProperty( + "BoolArray", + typeof(bool[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BoolArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var boolNestedCollection = runtimeEntityType.AddProperty( + "BoolNestedCollection", + typeof(bool[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BoolNestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var boolToStringConverterProperty = runtimeEntityType.AddProperty( + "BoolToStringConverterProperty", + typeof(bool), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BoolToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + boolToStringConverterProperty.TypeMapping = CosmosTypeMapping.Default.Clone( + comparer: new ValueComparer( + bool (bool v1, bool v2) => v1 == v2, + int (bool v) => ((object)v).GetHashCode(), + bool (bool v) => v), + keyComparer: new ValueComparer( + bool (bool v1, bool v2) => v1 == v2, + int (bool v) => ((object)v).GetHashCode(), + bool (bool v) => v), + providerValueComparer: new ValueComparer( + bool (string v1, string v2) => v1 == v2, + int (string v) => ((object)v).GetHashCode(), + string (string v) => v), + converter: new ValueConverter( + string (bool v) => ((string)((v ? "B" : "A"))), + bool (string v) => !(string.IsNullOrEmpty(v)) && ((int)(v.ToUpperInvariant()[0])) == ((int)("B".ToUpperInvariant()[0]))), + jsonValueReaderWriter: new JsonConvertedValueReaderWriter( + JsonStringReaderWriter.Instance, + new ValueConverter( + string (bool v) => ((string)((v ? "B" : "A"))), + bool (string v) => !(string.IsNullOrEmpty(v)) && ((int)(v.ToUpperInvariant()[0])) == ((int)("B".ToUpperInvariant()[0]))))); + boolToStringConverterProperty.SetSentinelFromProviderValue("A"); + + var boolToTwoValuesConverterProperty = runtimeEntityType.AddProperty( + "BoolToTwoValuesConverterProperty", + typeof(bool), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BoolToTwoValuesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + boolToTwoValuesConverterProperty.SetValueConverter(new ValueConverter( + byte (bool v) => ((byte)((v ? 1 : 0))), + bool (byte v) => v == 1)); + boolToTwoValuesConverterProperty.SetSentinelFromProviderValue((byte)0); + + var boolToZeroOneConverterProperty = runtimeEntityType.AddProperty( + "BoolToZeroOneConverterProperty", + typeof(bool), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BoolToZeroOneConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new BoolToZeroOneConverter()); + boolToZeroOneConverterProperty.SetSentinelFromProviderValue((short)0); + + var bytes = runtimeEntityType.AddProperty( + "Bytes", + typeof(byte[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Bytes", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var bytesToStringConverterProperty = runtimeEntityType.AddProperty( + "BytesToStringConverterProperty", + typeof(byte[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BytesToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new BytesToStringConverter(), + valueComparer: new ArrayStructuralComparer()); + + var castingConverterProperty = runtimeEntityType.AddProperty( + "CastingConverterProperty", + typeof(int), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("CastingConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new CastingConverter()); + castingConverterProperty.SetSentinelFromProviderValue(0m); + + var @char = runtimeEntityType.AddProperty( + "Char", + typeof(char), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Char", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: '\0'); + + var charArray = runtimeEntityType.AddProperty( + "CharArray", + typeof(char[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("CharArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var charNestedCollection = runtimeEntityType.AddProperty( + "CharNestedCollection", + typeof(char[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("CharNestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var charToStringConverterProperty = runtimeEntityType.AddProperty( + "CharToStringConverterProperty", + typeof(char), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("CharToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new CharToStringConverter()); + charToStringConverterProperty.SetSentinelFromProviderValue("\0"); + + var dateOnly = runtimeEntityType.AddProperty( + "DateOnly", + typeof(DateOnly), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateOnly", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: new DateOnly(1, 1, 1)); + + var dateOnlyToStringConverterProperty = runtimeEntityType.AddProperty( + "DateOnlyToStringConverterProperty", + typeof(DateOnly), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateOnlyToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new DateOnlyToStringConverter()); + dateOnlyToStringConverterProperty.SetSentinelFromProviderValue("0001-01-01"); + + var dateTime = runtimeEntityType.AddProperty( + "DateTime", + typeof(DateTime), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTime", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + var dateTimeOffsetToBinaryConverterProperty = runtimeEntityType.AddProperty( + "DateTimeOffsetToBinaryConverterProperty", + typeof(DateTimeOffset), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeOffsetToBinaryConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new DateTimeOffsetToBinaryConverter()); + dateTimeOffsetToBinaryConverterProperty.SetSentinelFromProviderValue(0L); + + var dateTimeOffsetToBytesConverterProperty = runtimeEntityType.AddProperty( + "DateTimeOffsetToBytesConverterProperty", + typeof(DateTimeOffset), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeOffsetToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new DateTimeOffsetToBytesConverter()); + dateTimeOffsetToBytesConverterProperty.SetSentinelFromProviderValue("AAAAAAAAAAAAAA=="); + + var dateTimeOffsetToStringConverterProperty = runtimeEntityType.AddProperty( + "DateTimeOffsetToStringConverterProperty", + typeof(DateTimeOffset), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeOffsetToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new DateTimeOffsetToStringConverter()); + dateTimeOffsetToStringConverterProperty.SetSentinelFromProviderValue("0001-01-01 00:00:00+00:00"); + + var dateTimeToBinaryConverterProperty = runtimeEntityType.AddProperty( + "DateTimeToBinaryConverterProperty", + typeof(DateTime), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeToBinaryConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new DateTimeToBinaryConverter()); + dateTimeToBinaryConverterProperty.SetSentinelFromProviderValue(0L); + + var dateTimeToStringConverterProperty = runtimeEntityType.AddProperty( + "DateTimeToStringConverterProperty", + typeof(DateTime), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new DateTimeToStringConverter()); + dateTimeToStringConverterProperty.SetSentinelFromProviderValue("0001-01-01 00:00:00"); + + var dateTimeToTicksConverterProperty = runtimeEntityType.AddProperty( + "DateTimeToTicksConverterProperty", + typeof(DateTime), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeToTicksConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + var @decimal = runtimeEntityType.AddProperty( + "Decimal", + typeof(decimal), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Decimal", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0m); + + var decimalArray = runtimeEntityType.AddProperty( + "DecimalArray", + typeof(decimal[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DecimalArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var decimalNumberToBytesConverterProperty = runtimeEntityType.AddProperty( + "DecimalNumberToBytesConverterProperty", + typeof(decimal), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DecimalNumberToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new NumberToBytesConverter()); + decimalNumberToBytesConverterProperty.SetSentinelFromProviderValue("AAAAAAAAAAAAAAAAAAAAAA=="); + + var decimalNumberToStringConverterProperty = runtimeEntityType.AddProperty( + "DecimalNumberToStringConverterProperty", + typeof(decimal), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DecimalNumberToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new NumberToStringConverter()); + decimalNumberToStringConverterProperty.SetSentinelFromProviderValue("0"); + + var @double = runtimeEntityType.AddProperty( + "Double", + typeof(double), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Double", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0.0); + + var doubleArray = runtimeEntityType.AddProperty( + "DoubleArray", + typeof(double[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DoubleArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var doubleNumberToBytesConverterProperty = runtimeEntityType.AddProperty( + "DoubleNumberToBytesConverterProperty", + typeof(double), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DoubleNumberToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new NumberToBytesConverter()); + doubleNumberToBytesConverterProperty.SetSentinelFromProviderValue("AAAAAAAAAAA="); + + var doubleNumberToStringConverterProperty = runtimeEntityType.AddProperty( + "DoubleNumberToStringConverterProperty", + typeof(double), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DoubleNumberToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new NumberToStringConverter()); + doubleNumberToStringConverterProperty.SetSentinelFromProviderValue("0"); + + var enum16 = runtimeEntityType.AddProperty( + "Enum16", + typeof(CompiledModelTestBase.Enum16), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enum16.SetSentinelFromProviderValue((short)0); + + var enum16AsString = runtimeEntityType.AddProperty( + "Enum16AsString", + typeof(CompiledModelTestBase.Enum16), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum16AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enum16AsString.SetSentinelFromProviderValue("Default"); + + var enum32 = runtimeEntityType.AddProperty( + "Enum32", + typeof(CompiledModelTestBase.Enum32), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enum32.SetSentinelFromProviderValue(0); + + var enum32AsString = runtimeEntityType.AddProperty( + "Enum32AsString", + typeof(CompiledModelTestBase.Enum32), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum32AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enum32AsString.SetSentinelFromProviderValue("Default"); + + var enum64 = runtimeEntityType.AddProperty( + "Enum64", + typeof(CompiledModelTestBase.Enum64), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enum64.SetSentinelFromProviderValue(0L); + + var enum64AsString = runtimeEntityType.AddProperty( + "Enum64AsString", + typeof(CompiledModelTestBase.Enum64), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum64AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enum64AsString.SetSentinelFromProviderValue("Default"); + + var enum8 = runtimeEntityType.AddProperty( + "Enum8", + typeof(CompiledModelTestBase.Enum8), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enum8.SetSentinelFromProviderValue((sbyte)0); + + var enum8AsString = runtimeEntityType.AddProperty( + "Enum8AsString", + typeof(CompiledModelTestBase.Enum8), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum8AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enum8AsString.SetSentinelFromProviderValue("Default"); + + var enumToNumberConverterProperty = runtimeEntityType.AddProperty( + "EnumToNumberConverterProperty", + typeof(CompiledModelTestBase.Enum32), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumToNumberConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new EnumToNumberConverter()); + enumToNumberConverterProperty.SetSentinelFromProviderValue(0); + + var enumToStringConverterProperty = runtimeEntityType.AddProperty( + "EnumToStringConverterProperty", + typeof(CompiledModelTestBase.Enum32), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new EnumToStringConverter()); + enumToStringConverterProperty.SetSentinelFromProviderValue("Default"); + + var enumU16 = runtimeEntityType.AddProperty( + "EnumU16", + typeof(CompiledModelTestBase.EnumU16), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enumU16.SetSentinelFromProviderValue((ushort)0); + + var enumU16AsString = runtimeEntityType.AddProperty( + "EnumU16AsString", + typeof(CompiledModelTestBase.EnumU16), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU16AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enumU16AsString.SetSentinelFromProviderValue("Min"); + + var enumU32 = runtimeEntityType.AddProperty( + "EnumU32", + typeof(CompiledModelTestBase.EnumU32), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enumU32.SetSentinelFromProviderValue(0u); + + var enumU32AsString = runtimeEntityType.AddProperty( + "EnumU32AsString", + typeof(CompiledModelTestBase.EnumU32), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU32AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enumU32AsString.SetSentinelFromProviderValue("Min"); + + var enumU64 = runtimeEntityType.AddProperty( + "EnumU64", + typeof(CompiledModelTestBase.EnumU64), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enumU64.SetSentinelFromProviderValue(0ul); + + var enumU64AsString = runtimeEntityType.AddProperty( + "EnumU64AsString", + typeof(CompiledModelTestBase.EnumU64), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU64AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enumU64AsString.SetSentinelFromProviderValue("Min"); + + var enumU8 = runtimeEntityType.AddProperty( + "EnumU8", + typeof(CompiledModelTestBase.EnumU8), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enumU8.SetSentinelFromProviderValue((byte)0); + + var enumU8AsString = runtimeEntityType.AddProperty( + "EnumU8AsString", + typeof(CompiledModelTestBase.EnumU8), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU8AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enumU8AsString.SetSentinelFromProviderValue("Min"); + + var @float = runtimeEntityType.AddProperty( + "Float", + typeof(float), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Float", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0f); + + var floatArray = runtimeEntityType.AddProperty( + "FloatArray", + typeof(float[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("FloatArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var guid = runtimeEntityType.AddProperty( + "Guid", + typeof(Guid), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Guid", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + guid.SetSentinelFromProviderValue("00000000-0000-0000-0000-000000000000"); + + var guidToBytesConverterProperty = runtimeEntityType.AddProperty( + "GuidToBytesConverterProperty", + typeof(Guid), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("GuidToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new GuidToBytesConverter()); + guidToBytesConverterProperty.SetSentinelFromProviderValue("AAAAAAAAAAAAAAAAAAAAAA=="); + + var guidToStringConverterProperty = runtimeEntityType.AddProperty( + "GuidToStringConverterProperty", + typeof(Guid), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("GuidToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new GuidToStringConverter()); + guidToStringConverterProperty.SetSentinelFromProviderValue("00000000-0000-0000-0000-000000000000"); + + var iPAddress = runtimeEntityType.AddProperty( + "IPAddress", + typeof(IPAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("IPAddress", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var iPAddressToBytesConverterProperty = runtimeEntityType.AddProperty( + "IPAddressToBytesConverterProperty", + typeof(IPAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("IPAddressToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new IPAddressToBytesConverter()); + + var iPAddressToStringConverterProperty = runtimeEntityType.AddProperty( + "IPAddressToStringConverterProperty", + typeof(IPAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("IPAddressToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new IPAddressToStringConverter()); + + var int16 = runtimeEntityType.AddProperty( + "Int16", + typeof(short), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: (short)0); + + var int16Array = runtimeEntityType.AddProperty( + "Int16Array", + typeof(short[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var int32 = runtimeEntityType.AddProperty( + "Int32", + typeof(int), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0); + + var int32Array = runtimeEntityType.AddProperty( + "Int32Array", + typeof(int[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var int32NestedCollection = runtimeEntityType.AddProperty( + "Int32NestedCollection", + typeof(int[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int32NestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var int64 = runtimeEntityType.AddProperty( + "Int64", + typeof(long), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0L); + + var int64Array = runtimeEntityType.AddProperty( + "Int64Array", + typeof(long[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var int64NestedCollection = runtimeEntityType.AddProperty( + "Int64NestedCollection", + typeof(IList[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int64NestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var int8 = runtimeEntityType.AddProperty( + "Int8", + typeof(sbyte), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: (sbyte)0); + + var int8Array = runtimeEntityType.AddProperty( + "Int8Array", + typeof(sbyte[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var int8NestedCollection = runtimeEntityType.AddProperty( + "Int8NestedCollection", + typeof(sbyte[][][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int8NestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var intNumberToBytesConverterProperty = runtimeEntityType.AddProperty( + "IntNumberToBytesConverterProperty", + typeof(int), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("IntNumberToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new NumberToBytesConverter()); + intNumberToBytesConverterProperty.SetSentinelFromProviderValue("AAAAAA=="); + + var intNumberToStringConverterProperty = runtimeEntityType.AddProperty( + "IntNumberToStringConverterProperty", + typeof(int), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("IntNumberToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new NumberToStringConverter()); + intNumberToStringConverterProperty.SetSentinelFromProviderValue("0"); + + var nullIntToNullStringConverterProperty = runtimeEntityType.AddProperty( + "NullIntToNullStringConverterProperty", + typeof(int?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullIntToNullStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true, + valueConverter: new CompiledModelTestBase.NullIntToNullStringConverter()); + + var nullableBool = runtimeEntityType.AddProperty( + "NullableBool", + typeof(bool?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableBool", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableBoolArray = runtimeEntityType.AddProperty( + "NullableBoolArray", + typeof(bool?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableBoolArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableBytes = runtimeEntityType.AddProperty( + "NullableBytes", + typeof(byte[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableBytes", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableChar = runtimeEntityType.AddProperty( + "NullableChar", + typeof(char?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableChar", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableCharArray = runtimeEntityType.AddProperty( + "NullableCharArray", + typeof(char?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableCharArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableDateOnly = runtimeEntityType.AddProperty( + "NullableDateOnly", + typeof(DateOnly?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDateOnly", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableDateTime = runtimeEntityType.AddProperty( + "NullableDateTime", + typeof(DateTime?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDateTime", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableDecimal = runtimeEntityType.AddProperty( + "NullableDecimal", + typeof(decimal?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDecimal", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableDecimalArray = runtimeEntityType.AddProperty( + "NullableDecimalArray", + typeof(decimal?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDecimalArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableDouble = runtimeEntityType.AddProperty( + "NullableDouble", + typeof(double?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDouble", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableDoubleArray = runtimeEntityType.AddProperty( + "NullableDoubleArray", + typeof(double?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDoubleArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum16 = runtimeEntityType.AddProperty( + "NullableEnum16", + typeof(CompiledModelTestBase.Enum16?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnum16AsString = runtimeEntityType.AddProperty( + "NullableEnum16AsString", + typeof(CompiledModelTestBase.Enum16?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum16AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnum32 = runtimeEntityType.AddProperty( + "NullableEnum32", + typeof(CompiledModelTestBase.Enum32?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnum32AsString = runtimeEntityType.AddProperty( + "NullableEnum32AsString", + typeof(CompiledModelTestBase.Enum32?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum32AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnum64 = runtimeEntityType.AddProperty( + "NullableEnum64", + typeof(CompiledModelTestBase.Enum64?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnum64AsString = runtimeEntityType.AddProperty( + "NullableEnum64AsString", + typeof(CompiledModelTestBase.Enum64?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum64AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnum8 = runtimeEntityType.AddProperty( + "NullableEnum8", + typeof(CompiledModelTestBase.Enum8?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnum8AsString = runtimeEntityType.AddProperty( + "NullableEnum8AsString", + typeof(CompiledModelTestBase.Enum8?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum8AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnumU16 = runtimeEntityType.AddProperty( + "NullableEnumU16", + typeof(CompiledModelTestBase.EnumU16?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnumU16AsString = runtimeEntityType.AddProperty( + "NullableEnumU16AsString", + typeof(CompiledModelTestBase.EnumU16?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU16AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnumU32 = runtimeEntityType.AddProperty( + "NullableEnumU32", + typeof(CompiledModelTestBase.EnumU32?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnumU32AsString = runtimeEntityType.AddProperty( + "NullableEnumU32AsString", + typeof(CompiledModelTestBase.EnumU32?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU32AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnumU64 = runtimeEntityType.AddProperty( + "NullableEnumU64", + typeof(CompiledModelTestBase.EnumU64?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnumU64AsString = runtimeEntityType.AddProperty( + "NullableEnumU64AsString", + typeof(CompiledModelTestBase.EnumU64?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU64AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnumU8 = runtimeEntityType.AddProperty( + "NullableEnumU8", + typeof(CompiledModelTestBase.EnumU8?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnumU8AsString = runtimeEntityType.AddProperty( + "NullableEnumU8AsString", + typeof(CompiledModelTestBase.EnumU8?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU8AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableFloat = runtimeEntityType.AddProperty( + "NullableFloat", + typeof(float?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableFloat", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableFloatArray = runtimeEntityType.AddProperty( + "NullableFloatArray", + typeof(float?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableFloatArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableGuid = runtimeEntityType.AddProperty( + "NullableGuid", + typeof(Guid?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableGuid", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableIPAddress = runtimeEntityType.AddProperty( + "NullableIPAddress", + typeof(IPAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableIPAddress", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableInt16 = runtimeEntityType.AddProperty( + "NullableInt16", + typeof(short?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableInt16Array = runtimeEntityType.AddProperty( + "NullableInt16Array", + typeof(short?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableInt32 = runtimeEntityType.AddProperty( + "NullableInt32", + typeof(int?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableInt32Array = runtimeEntityType.AddProperty( + "NullableInt32Array", + typeof(int?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableInt32NestedCollection = runtimeEntityType.AddProperty( + "NullableInt32NestedCollection", + typeof(int?[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt32NestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableInt64 = runtimeEntityType.AddProperty( + "NullableInt64", + typeof(long?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableInt64Array = runtimeEntityType.AddProperty( + "NullableInt64Array", + typeof(long?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableInt64NestedCollection = runtimeEntityType.AddProperty( + "NullableInt64NestedCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt64NestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableInt8 = runtimeEntityType.AddProperty( + "NullableInt8", + typeof(sbyte?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableInt8Array = runtimeEntityType.AddProperty( + "NullableInt8Array", + typeof(sbyte?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullablePhysicalAddress = runtimeEntityType.AddProperty( + "NullablePhysicalAddress", + typeof(PhysicalAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullablePhysicalAddress", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableString = runtimeEntityType.AddProperty( + "NullableString", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableStringArray = runtimeEntityType.AddProperty( + "NullableStringArray", + typeof(string[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableStringNestedCollection = runtimeEntityType.AddProperty( + "NullableStringNestedCollection", + typeof(string[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableStringNestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableTimeOnly = runtimeEntityType.AddProperty( + "NullableTimeOnly", + typeof(TimeOnly?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableTimeOnly", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableTimeSpan = runtimeEntityType.AddProperty( + "NullableTimeSpan", + typeof(TimeSpan?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableTimeSpan", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableUInt16 = runtimeEntityType.AddProperty( + "NullableUInt16", + typeof(ushort?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableUInt16Array = runtimeEntityType.AddProperty( + "NullableUInt16Array", + typeof(ushort?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableUInt32 = runtimeEntityType.AddProperty( + "NullableUInt32", + typeof(uint?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableUInt32Array = runtimeEntityType.AddProperty( + "NullableUInt32Array", + typeof(uint?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableUInt64 = runtimeEntityType.AddProperty( + "NullableUInt64", + typeof(ulong?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableUInt64Array = runtimeEntityType.AddProperty( + "NullableUInt64Array", + typeof(ulong?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableUInt8 = runtimeEntityType.AddProperty( + "NullableUInt8", + typeof(byte?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableUInt8Array = runtimeEntityType.AddProperty( + "NullableUInt8Array", + typeof(byte?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableUri = runtimeEntityType.AddProperty( + "NullableUri", + typeof(Uri), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUri", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var physicalAddress = runtimeEntityType.AddProperty( + "PhysicalAddress", + typeof(PhysicalAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("PhysicalAddress", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var physicalAddressToBytesConverterProperty = runtimeEntityType.AddProperty( + "PhysicalAddressToBytesConverterProperty", + typeof(PhysicalAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("PhysicalAddressToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new PhysicalAddressToBytesConverter()); + + var physicalAddressToStringConverterProperty = runtimeEntityType.AddProperty( + "PhysicalAddressToStringConverterProperty", + typeof(PhysicalAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("PhysicalAddressToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new PhysicalAddressToStringConverter()); + + var @string = runtimeEntityType.AddProperty( + "String", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("String", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var stringArray = runtimeEntityType.AddProperty( + "StringArray", + typeof(string[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var stringNestedCollection = runtimeEntityType.AddProperty( + "StringNestedCollection", + typeof(string[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringNestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var stringToBoolConverterProperty = runtimeEntityType.AddProperty( + "StringToBoolConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToBoolConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToBoolConverter()); + + var stringToBytesConverterProperty = runtimeEntityType.AddProperty( + "StringToBytesConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + stringToBytesConverterProperty.SetValueConverter(new ValueConverter( + string (string v) => Convert.ToBase64String(Encoding.GetEncoding(12000).GetBytes(v)), + string (string v) => Encoding.GetEncoding(12000).GetString(Convert.FromBase64String(v)))); + + var stringToCharConverterProperty = runtimeEntityType.AddProperty( + "StringToCharConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToCharConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToCharConverter()); + + var stringToDateOnlyConverterProperty = runtimeEntityType.AddProperty( + "StringToDateOnlyConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToDateOnlyConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToDateOnlyConverter()); + + var stringToDateTimeConverterProperty = runtimeEntityType.AddProperty( + "StringToDateTimeConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToDateTimeConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToDateTimeConverter()); + + var stringToDateTimeOffsetConverterProperty = runtimeEntityType.AddProperty( + "StringToDateTimeOffsetConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToDateTimeOffsetConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToDateTimeOffsetConverter()); + + var stringToDecimalNumberConverterProperty = runtimeEntityType.AddProperty( + "StringToDecimalNumberConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToDecimalNumberConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToNumberConverter()); + + var stringToDoubleNumberConverterProperty = runtimeEntityType.AddProperty( + "StringToDoubleNumberConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToDoubleNumberConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToNumberConverter()); + + var stringToEnumConverterProperty = runtimeEntityType.AddProperty( + "StringToEnumConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToEnumConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToEnumConverter()); + + var stringToGuidConverterProperty = runtimeEntityType.AddProperty( + "StringToGuidConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToGuidConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var stringToIntNumberConverterProperty = runtimeEntityType.AddProperty( + "StringToIntNumberConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToIntNumberConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToNumberConverter()); + + var stringToTimeOnlyConverterProperty = runtimeEntityType.AddProperty( + "StringToTimeOnlyConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToTimeOnlyConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToTimeOnlyConverter()); + + var stringToTimeSpanConverterProperty = runtimeEntityType.AddProperty( + "StringToTimeSpanConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToTimeSpanConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToTimeSpanConverter()); + + var stringToUriConverterProperty = runtimeEntityType.AddProperty( + "StringToUriConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToUriConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToUriConverter()); + + var timeOnly = runtimeEntityType.AddProperty( + "TimeOnly", + typeof(TimeOnly), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeOnly", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: new TimeOnly(0, 0, 0)); + + var timeOnlyToStringConverterProperty = runtimeEntityType.AddProperty( + "TimeOnlyToStringConverterProperty", + typeof(TimeOnly), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeOnlyToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new TimeOnlyToStringConverter()); + timeOnlyToStringConverterProperty.SetSentinelFromProviderValue("00:00:00"); + + var timeOnlyToTicksConverterProperty = runtimeEntityType.AddProperty( + "TimeOnlyToTicksConverterProperty", + typeof(TimeOnly), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeOnlyToTicksConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new TimeOnlyToTicksConverter()); + timeOnlyToTicksConverterProperty.SetSentinelFromProviderValue(0L); + + var timeSpan = runtimeEntityType.AddProperty( + "TimeSpan", + typeof(TimeSpan), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeSpan", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: new TimeSpan(0, 0, 0, 0, 0)); + + var timeSpanToStringConverterProperty = runtimeEntityType.AddProperty( + "TimeSpanToStringConverterProperty", + typeof(TimeSpan), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeSpanToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new TimeSpanToStringConverter()); + timeSpanToStringConverterProperty.SetSentinelFromProviderValue("00:00:00"); + + var timeSpanToTicksConverterProperty = runtimeEntityType.AddProperty( + "TimeSpanToTicksConverterProperty", + typeof(TimeSpan), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeSpanToTicksConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new TimeSpanToTicksConverter()); + timeSpanToTicksConverterProperty.SetSentinelFromProviderValue(0L); + + var uInt16 = runtimeEntityType.AddProperty( + "UInt16", + typeof(ushort), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: (ushort)0); + + var uInt16Array = runtimeEntityType.AddProperty( + "UInt16Array", + typeof(ushort[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var uInt32 = runtimeEntityType.AddProperty( + "UInt32", + typeof(uint), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0u); + + var uInt32Array = runtimeEntityType.AddProperty( + "UInt32Array", + typeof(uint[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var uInt64 = runtimeEntityType.AddProperty( + "UInt64", + typeof(ulong), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0ul); + + var uInt64Array = runtimeEntityType.AddProperty( + "UInt64Array", + typeof(ulong[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var uInt8 = runtimeEntityType.AddProperty( + "UInt8", + typeof(byte), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: (byte)0); + + var uInt8Array = runtimeEntityType.AddProperty( + "UInt8Array", + typeof(byte[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var uri = runtimeEntityType.AddProperty( + "Uri", + typeof(Uri), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Uri", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var uriToStringConverterProperty = runtimeEntityType.AddProperty( + "UriToStringConverterProperty", + typeof(Uri), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UriToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new UriToStringConverter()); + + var __id = runtimeEntityType.AddProperty( + "__id", + typeof(string), + afterSaveBehavior: PropertySaveBehavior.Throw, + valueGeneratorFactory: new IdValueGeneratorFactory().Create); + __id.AddAnnotation("Cosmos:PropertyName", "id"); + + var __jObject = runtimeEntityType.AddProperty( + "__jObject", + typeof(JObject), + nullable: true, + valueGenerated: ValueGenerated.OnAddOrUpdate, + beforeSaveBehavior: PropertySaveBehavior.Ignore, + afterSaveBehavior: PropertySaveBehavior.Ignore); + __jObject.AddAnnotation("Cosmos:PropertyName", ""); + + var key = runtimeEntityType.AddKey( + new[] { id }); + runtimeEntityType.SetPrimaryKey(key); + + return runtimeEntityType; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/OwnedType0EntityType.cs b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/OwnedType0EntityType.cs new file mode 100644 index 00000000000..b3f5ad457b0 --- /dev/null +++ b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/OwnedType0EntityType.cs @@ -0,0 +1,155 @@ +// +using System; +using System.Collections.Generic; +using System.Reflection; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; +using Newtonsoft.Json.Linq; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class OwnedType0EntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalDerived>.ManyOwned#OwnedType", + typeof(CompiledModelTestBase.OwnedType), + baseEntityType, + sharedClrType: true, + propertyCount: 12, + servicePropertyCount: 1, + foreignKeyCount: 1, + keyCount: 1); + + var principalDerivedId = runtimeEntityType.AddProperty( + "PrincipalDerivedId", + typeof(long), + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: 0L); + + var principalDerivedAlternateId = runtimeEntityType.AddProperty( + "PrincipalDerivedAlternateId", + typeof(Guid), + afterSaveBehavior: PropertySaveBehavior.Throw); + principalDerivedAlternateId.SetSentinelFromProviderValue("00000000-0000-0000-0000-000000000000"); + + var id = runtimeEntityType.AddProperty( + "Id", + typeof(int), + valueGenerated: ValueGenerated.OnAddOrUpdate, + beforeSaveBehavior: PropertySaveBehavior.Ignore, + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: 0); + + var details = runtimeEntityType.AddProperty( + "Details", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("Details", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_details", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var number = runtimeEntityType.AddProperty( + "Number", + typeof(int), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("Number", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0); + + var refTypeEnumerable = runtimeEntityType.AddProperty( + "RefTypeEnumerable", + typeof(IEnumerable), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeEnumerable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeEnumerable", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var refTypeIList = runtimeEntityType.AddProperty( + "RefTypeIList", + typeof(IList), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeIList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeIList", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var valueTypeArray = runtimeEntityType.AddProperty( + "ValueTypeArray", + typeof(DateTime[]), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_valueTypeArray", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var valueTypeEnumerable = runtimeEntityType.AddProperty( + "ValueTypeEnumerable", + typeof(IEnumerable), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeEnumerable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_valueTypeEnumerable", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var valueTypeIList = runtimeEntityType.AddProperty( + "ValueTypeIList", + typeof(IList), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeIList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var valueTypeList = runtimeEntityType.AddProperty( + "ValueTypeList", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_valueTypeList", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var __jObject = runtimeEntityType.AddProperty( + "__jObject", + typeof(JObject), + nullable: true, + valueGenerated: ValueGenerated.OnAddOrUpdate, + beforeSaveBehavior: PropertySaveBehavior.Ignore, + afterSaveBehavior: PropertySaveBehavior.Ignore); + __jObject.AddAnnotation("Cosmos:PropertyName", ""); + + var context = runtimeEntityType.AddServiceProperty( + "Context", + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("Context", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + serviceType: typeof(DbContext)); + + var key = runtimeEntityType.AddKey( + new[] { principalDerivedId, principalDerivedAlternateId, id }); + runtimeEntityType.SetPrimaryKey(key); + + return runtimeEntityType; + } + + public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("PrincipalDerivedId"), declaringEntityType.FindProperty("PrincipalDerivedAlternateId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("Id"), principalEntityType.FindProperty("AlternateId") }), + principalEntityType, + deleteBehavior: DeleteBehavior.Cascade, + required: true, + ownership: true); + + var manyOwned = principalEntityType.AddNavigation("ManyOwned", + runtimeForeignKey, + onDependent: false, + typeof(ICollection), + fieldInfo: typeof(CompiledModelTestBase.PrincipalDerived>).GetField("ManyOwned", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + eagerLoaded: true); + + return runtimeForeignKey; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/OwnedTypeEntityType.cs b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/OwnedTypeEntityType.cs new file mode 100644 index 00000000000..a06446aa7da --- /dev/null +++ b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/OwnedTypeEntityType.cs @@ -0,0 +1,163 @@ +// +using System; +using System.Collections.Generic; +using System.Reflection; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; +using Newtonsoft.Json.Linq; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class OwnedTypeEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalBase.Owned#OwnedType", + typeof(CompiledModelTestBase.OwnedType), + baseEntityType, + sharedClrType: true, + changeTrackingStrategy: ChangeTrackingStrategy.ChangingAndChangedNotificationsWithOriginalValues, + propertyCount: 11, + servicePropertyCount: 1, + foreignKeyCount: 1, + keyCount: 1); + + var principalBaseId = runtimeEntityType.AddProperty( + "PrincipalBaseId", + typeof(long), + propertyAccessMode: PropertyAccessMode.Field, + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: 0L); + + var principalBaseAlternateId = runtimeEntityType.AddProperty( + "PrincipalBaseAlternateId", + typeof(Guid), + propertyAccessMode: PropertyAccessMode.Field, + afterSaveBehavior: PropertySaveBehavior.Throw); + principalBaseAlternateId.SetSentinelFromProviderValue("00000000-0000-0000-0000-000000000000"); + + var details = runtimeEntityType.AddProperty( + "Details", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("Details", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_details", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var number = runtimeEntityType.AddProperty( + "Number", + typeof(int), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("Number", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + sentinel: 0); + + var refTypeEnumerable = runtimeEntityType.AddProperty( + "RefTypeEnumerable", + typeof(IEnumerable), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeEnumerable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeEnumerable", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var refTypeIList = runtimeEntityType.AddProperty( + "RefTypeIList", + typeof(IList), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeIList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeIList", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var valueTypeArray = runtimeEntityType.AddProperty( + "ValueTypeArray", + typeof(DateTime[]), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_valueTypeArray", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var valueTypeEnumerable = runtimeEntityType.AddProperty( + "ValueTypeEnumerable", + typeof(IEnumerable), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeEnumerable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_valueTypeEnumerable", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var valueTypeIList = runtimeEntityType.AddProperty( + "ValueTypeIList", + typeof(IList), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeIList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var valueTypeList = runtimeEntityType.AddProperty( + "ValueTypeList", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_valueTypeList", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var __jObject = runtimeEntityType.AddProperty( + "__jObject", + typeof(JObject), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true, + valueGenerated: ValueGenerated.OnAddOrUpdate, + beforeSaveBehavior: PropertySaveBehavior.Ignore, + afterSaveBehavior: PropertySaveBehavior.Ignore); + __jObject.AddAnnotation("Cosmos:PropertyName", ""); + + var context = runtimeEntityType.AddServiceProperty( + "Context", + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("Context", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + serviceType: typeof(DbContext)); + + var key = runtimeEntityType.AddKey( + new[] { principalBaseId, principalBaseAlternateId }); + runtimeEntityType.SetPrimaryKey(key); + + return runtimeEntityType; + } + + public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("PrincipalBaseId"), declaringEntityType.FindProperty("PrincipalBaseAlternateId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("Id"), principalEntityType.FindProperty("AlternateId") }), + principalEntityType, + deleteBehavior: DeleteBehavior.Cascade, + unique: true, + required: true, + requiredDependent: true, + ownership: true); + + var owned = principalEntityType.AddNavigation("Owned", + runtimeForeignKey, + onDependent: false, + typeof(CompiledModelTestBase.OwnedType), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("Owned", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("_ownedField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + eagerLoaded: true); + + return runtimeForeignKey; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalBaseEntityType.cs b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalBaseEntityType.cs new file mode 100644 index 00000000000..a685bcc3f86 --- /dev/null +++ b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalBaseEntityType.cs @@ -0,0 +1,185 @@ +// +using System; +using System.Collections.Generic; +using System.Reflection; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Cosmos.ValueGeneration.Internal; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; +using Microsoft.EntityFrameworkCore.Storage.Json; +using Microsoft.EntityFrameworkCore.ValueGeneration; +using Newtonsoft.Json.Linq; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class PrincipalBaseEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalBase", + typeof(CompiledModelTestBase.PrincipalBase), + baseEntityType, + discriminatorProperty: "$type", + discriminatorValue: "PrincipalBase", + derivedTypesCount: 1, + propertyCount: 15, + navigationCount: 1, + skipNavigationCount: 1, + keyCount: 2); + + var id = runtimeEntityType.AddProperty( + "Id", + typeof(long?), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("Id", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + afterSaveBehavior: PropertySaveBehavior.Throw); + + var alternateId = runtimeEntityType.AddProperty( + "AlternateId", + typeof(Guid), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("AlternateId", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.FieldDuringConstruction, + afterSaveBehavior: PropertySaveBehavior.Throw, + jsonValueReaderWriter: JsonGuidReaderWriter.Instance); + alternateId.SetSentinelFromProviderValue("00000000-0000-0000-0000-000000000000"); + + var type = runtimeEntityType.AddProperty( + "$type", + typeof(string), + afterSaveBehavior: PropertySaveBehavior.Throw, + valueGeneratorFactory: new DiscriminatorValueGeneratorFactory().Create); + + var enum1 = runtimeEntityType.AddProperty( + "Enum1", + typeof(CompiledModelTestBase.AnEnum), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("Enum1", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enum1.SetSentinelFromProviderValue(0); + + var enum2 = runtimeEntityType.AddProperty( + "Enum2", + typeof(CompiledModelTestBase.AnEnum?), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("Enum2", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var flagsEnum1 = runtimeEntityType.AddProperty( + "FlagsEnum1", + typeof(CompiledModelTestBase.AFlagsEnum), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("FlagsEnum1", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + flagsEnum1.SetSentinelFromProviderValue(0); + + var flagsEnum2 = runtimeEntityType.AddProperty( + "FlagsEnum2", + typeof(CompiledModelTestBase.AFlagsEnum), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("FlagsEnum2", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Property); + flagsEnum2.SetSentinelFromProviderValue(6); + + var refTypeEnumerable = runtimeEntityType.AddProperty( + "RefTypeEnumerable", + typeof(IEnumerable), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("RefTypeEnumerable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var refTypeIList = runtimeEntityType.AddProperty( + "RefTypeIList", + typeof(IList), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("RefTypeIList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var valueTypeArray = runtimeEntityType.AddProperty( + "ValueTypeArray", + typeof(DateTime[]), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("ValueTypeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var valueTypeEnumerable = runtimeEntityType.AddProperty( + "ValueTypeEnumerable", + typeof(IEnumerable), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("ValueTypeEnumerable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var valueTypeIList = runtimeEntityType.AddProperty( + "ValueTypeIList", + typeof(IList), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("ValueTypeIList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var valueTypeList = runtimeEntityType.AddProperty( + "ValueTypeList", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("ValueTypeList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var __id = runtimeEntityType.AddProperty( + "__id", + typeof(string), + afterSaveBehavior: PropertySaveBehavior.Throw, + valueGeneratorFactory: new IdValueGeneratorFactory().Create); + __id.AddAnnotation("Cosmos:PropertyName", "id"); + + var __jObject = runtimeEntityType.AddProperty( + "__jObject", + typeof(JObject), + nullable: true); + __jObject.AddAnnotation("Cosmos:PropertyName", ""); + + var key = runtimeEntityType.AddKey( + new[] { id }); + + var key0 = runtimeEntityType.AddKey( + new[] { id, alternateId }); + runtimeEntityType.SetPrimaryKey(key0); + + return runtimeEntityType; + } + + public static RuntimeSkipNavigation CreateSkipNavigation1(RuntimeEntityType declaringEntityType, RuntimeEntityType targetEntityType, RuntimeEntityType joinEntityType) + { + var skipNavigation = declaringEntityType.AddSkipNavigation( + "Deriveds", + targetEntityType, + joinEntityType.FindForeignKey( + new[] { joinEntityType.FindProperty("PrincipalsId"), joinEntityType.FindProperty("PrincipalsAlternateId") }, + declaringEntityType.FindKey(new[] { declaringEntityType.FindProperty("Id"), declaringEntityType.FindProperty("AlternateId") }), + declaringEntityType), + true, + false, + typeof(ICollection), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("Deriveds", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var inverse = targetEntityType.FindSkipNavigation("Principals"); + if (inverse != null) + { + skipNavigation.Inverse = inverse; + inverse.Inverse = skipNavigation; + } + + return skipNavigation; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs new file mode 100644 index 00000000000..00293d478e1 --- /dev/null +++ b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs @@ -0,0 +1,127 @@ +// +using System; +using System.Collections.Generic; +using System.Reflection; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Cosmos.ValueGeneration.Internal; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.ValueGeneration; +using Newtonsoft.Json.Linq; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class PrincipalBasePrincipalDerivedDependentBasebyteEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "PrincipalBasePrincipalDerived>", + typeof(Dictionary), + baseEntityType, + sharedClrType: true, + discriminatorProperty: "$type", + indexerPropertyInfo: RuntimeEntityType.FindIndexerProperty(typeof(Dictionary)), + propertyBag: true, + discriminatorValue: "PrincipalBasePrincipalDerived>", + propertyCount: 8, + foreignKeyCount: 2, + keyCount: 1); + + var derivedsId = runtimeEntityType.AddProperty( + "DerivedsId", + typeof(long), + propertyInfo: runtimeEntityType.FindIndexerPropertyInfo(), + afterSaveBehavior: PropertySaveBehavior.Throw); + + var derivedsAlternateId = runtimeEntityType.AddProperty( + "DerivedsAlternateId", + typeof(Guid), + propertyInfo: runtimeEntityType.FindIndexerPropertyInfo(), + afterSaveBehavior: PropertySaveBehavior.Throw); + + var principalsId = runtimeEntityType.AddProperty( + "PrincipalsId", + typeof(long), + propertyInfo: runtimeEntityType.FindIndexerPropertyInfo(), + afterSaveBehavior: PropertySaveBehavior.Throw); + + var principalsAlternateId = runtimeEntityType.AddProperty( + "PrincipalsAlternateId", + typeof(Guid), + propertyInfo: runtimeEntityType.FindIndexerPropertyInfo(), + afterSaveBehavior: PropertySaveBehavior.Throw); + + var type = runtimeEntityType.AddProperty( + "$type", + typeof(string), + propertyInfo: runtimeEntityType.FindIndexerPropertyInfo(), + afterSaveBehavior: PropertySaveBehavior.Throw, + valueGeneratorFactory: new DiscriminatorValueGeneratorFactory().Create); + + var __id = runtimeEntityType.AddProperty( + "__id", + typeof(string), + propertyInfo: runtimeEntityType.FindIndexerPropertyInfo(), + afterSaveBehavior: PropertySaveBehavior.Throw, + valueGeneratorFactory: new IdValueGeneratorFactory().Create); + __id.AddAnnotation("Cosmos:PropertyName", "id"); + + var __jObject = runtimeEntityType.AddProperty( + "__jObject", + typeof(JObject), + propertyInfo: runtimeEntityType.FindIndexerPropertyInfo(), + nullable: true, + valueGenerated: ValueGenerated.OnAddOrUpdate, + beforeSaveBehavior: PropertySaveBehavior.Ignore, + afterSaveBehavior: PropertySaveBehavior.Ignore); + __jObject.AddAnnotation("Cosmos:PropertyName", ""); + + var rowid = runtimeEntityType.AddProperty( + "rowid", + typeof(byte[]), + propertyInfo: runtimeEntityType.FindIndexerPropertyInfo(), + nullable: true); + + var key = runtimeEntityType.AddKey( + new[] { derivedsId, derivedsAlternateId, principalsId, principalsAlternateId }); + runtimeEntityType.SetPrimaryKey(key); + + return runtimeEntityType; + } + + public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("DerivedsId"), declaringEntityType.FindProperty("DerivedsAlternateId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("Id"), principalEntityType.FindProperty("AlternateId") }), + principalEntityType, + deleteBehavior: DeleteBehavior.Cascade, + required: true); + + return runtimeForeignKey; + } + + public static RuntimeForeignKey CreateForeignKey2(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("PrincipalsId"), declaringEntityType.FindProperty("PrincipalsAlternateId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("Id"), principalEntityType.FindProperty("AlternateId") }), + principalEntityType, + deleteBehavior: DeleteBehavior.Cascade, + required: true); + + return runtimeForeignKey; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalDerivedEntityType.cs b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalDerivedEntityType.cs new file mode 100644 index 00000000000..29912134311 --- /dev/null +++ b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalDerivedEntityType.cs @@ -0,0 +1,65 @@ +// +using System; +using System.Collections.Generic; +using System.Reflection; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class PrincipalDerivedEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalDerived>", + typeof(CompiledModelTestBase.PrincipalDerived>), + baseEntityType, + discriminatorProperty: "$type", + discriminatorValue: "PrincipalDerived", + propertyCount: 0, + navigationCount: 2, + skipNavigationCount: 1); + + return runtimeEntityType; + } + + public static RuntimeSkipNavigation CreateSkipNavigation1(RuntimeEntityType declaringEntityType, RuntimeEntityType targetEntityType, RuntimeEntityType joinEntityType) + { + var skipNavigation = declaringEntityType.AddSkipNavigation( + "Principals", + targetEntityType, + joinEntityType.FindForeignKey( + new[] { joinEntityType.FindProperty("DerivedsId"), joinEntityType.FindProperty("DerivedsAlternateId") }, + declaringEntityType.FindKey(new[] { declaringEntityType.FindProperty("Id"), declaringEntityType.FindProperty("AlternateId") }), + declaringEntityType), + true, + false, + typeof(ICollection), + propertyInfo: typeof(CompiledModelTestBase.PrincipalDerived>).GetProperty("Principals", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalDerived>).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var inverse = targetEntityType.FindSkipNavigation("Deriveds"); + if (inverse != null) + { + skipNavigation.Inverse = inverse; + inverse.Inverse = skipNavigation; + } + + return skipNavigation; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/SimpleModel/DependentDerivedEntityType.cs b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/SimpleModel/DependentDerivedEntityType.cs index 0ff9299efb3..799044f4c25 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/SimpleModel/DependentDerivedEntityType.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/Baselines/SimpleModel/DependentDerivedEntityType.cs @@ -233,11 +233,11 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var type = runtimeEntityType.FindProperty("$type")!; - var data = runtimeEntityType.FindProperty("Data")!; - var __id = runtimeEntityType.FindProperty("__id")!; - var __jObject = runtimeEntityType.FindProperty("__jObject")!; + var id = runtimeEntityType.FindProperty("Id"); + var type = runtimeEntityType.FindProperty("$type"); + var data = runtimeEntityType.FindProperty("Data"); + var __id = runtimeEntityType.FindProperty("__id"); + var __jObject = runtimeEntityType.FindProperty("__jObject"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); diff --git a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/CompiledModelCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/CompiledModelCosmosTest.cs index 7b2e808bca4..26eb930ce0c 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/CompiledModelCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/CompiledModelCosmosTest.cs @@ -60,7 +60,7 @@ public virtual Task Basic_cosmos_model() Assert.Equal(ValueGenerated.Never, id.ValueGenerated); Assert.Equal(PropertySaveBehavior.Throw, id.GetAfterSaveBehavior()); Assert.Equal(PropertySaveBehavior.Save, id.GetBeforeSaveBehavior()); - Assert.Equal("Id", CosmosPropertyExtensions.GetJsonPropertyName(id)); + Assert.Equal("Id", id.GetJsonPropertyName()); Assert.Null(id.GetValueGeneratorFactory()); Assert.Null(id.GetValueConverter()); Assert.NotNull(id.GetValueComparer()); @@ -75,7 +75,7 @@ public virtual Task Basic_cosmos_model() Assert.Equal(ValueGenerated.Never, storeId.ValueGenerated); Assert.Equal(PropertySaveBehavior.Throw, storeId.GetAfterSaveBehavior()); Assert.Equal(PropertySaveBehavior.Save, storeId.GetBeforeSaveBehavior()); - Assert.Equal("id", CosmosPropertyExtensions.GetJsonPropertyName(storeId)); + Assert.Equal("id", storeId.GetJsonPropertyName()); Assert.IsType(storeId.GetValueGeneratorFactory()!(storeId, dataEntity)); Assert.Null(storeId.GetValueConverter()); Assert.NotNull(storeId.GetValueComparer()); @@ -90,7 +90,7 @@ public virtual Task Basic_cosmos_model() Assert.Equal(ValueGenerated.Never, partitionId.ValueGenerated); Assert.Equal(PropertySaveBehavior.Throw, partitionId.GetAfterSaveBehavior()); Assert.Equal(PropertySaveBehavior.Save, partitionId.GetBeforeSaveBehavior()); - Assert.Equal("PartitionId", CosmosPropertyExtensions.GetJsonPropertyName(partitionId)); + Assert.Equal("PartitionId", partitionId.GetJsonPropertyName()); Assert.Null(partitionId.GetValueGeneratorFactory()); Assert.Null(partitionId.GetValueConverter()); Assert.Equal("1", partitionId.FindTypeMapping()!.Converter!.ConvertToProvider(1)); @@ -107,7 +107,7 @@ public virtual Task Basic_cosmos_model() Assert.Equal(ValueGenerated.Never, map.ValueGenerated); Assert.Equal(PropertySaveBehavior.Save, map.GetAfterSaveBehavior()); Assert.Equal(PropertySaveBehavior.Save, map.GetBeforeSaveBehavior()); - Assert.Equal("Map", CosmosPropertyExtensions.GetJsonPropertyName(map)); + Assert.Equal("Map", map.GetJsonPropertyName()); Assert.Null(map.GetValueGeneratorFactory()); Assert.Null(map.GetValueConverter()); Assert.NotNull(map.GetValueComparer()); @@ -123,7 +123,7 @@ public virtual Task Basic_cosmos_model() Assert.Equal(ValueGenerated.Never, list.ValueGenerated); Assert.Equal(PropertySaveBehavior.Save, list.GetAfterSaveBehavior()); Assert.Equal(PropertySaveBehavior.Save, list.GetBeforeSaveBehavior()); - Assert.Equal("List", CosmosPropertyExtensions.GetJsonPropertyName(list)); + Assert.Equal("List", list.GetJsonPropertyName()); Assert.Null(list.GetValueGeneratorFactory()); Assert.Null(list.GetValueConverter()); Assert.NotNull(list.GetValueComparer()); @@ -139,7 +139,7 @@ public virtual Task Basic_cosmos_model() Assert.Equal(ValueGenerated.Never, bytes.ValueGenerated); Assert.Equal(PropertySaveBehavior.Save, bytes.GetAfterSaveBehavior()); Assert.Equal(PropertySaveBehavior.Save, bytes.GetBeforeSaveBehavior()); - Assert.Equal("Bytes", CosmosPropertyExtensions.GetJsonPropertyName(bytes)); + Assert.Equal("Bytes", bytes.GetJsonPropertyName()); Assert.Null(bytes.GetValueGeneratorFactory()); Assert.Null(bytes.GetValueConverter()); Assert.NotNull(bytes.GetValueComparer()); @@ -154,7 +154,7 @@ public virtual Task Basic_cosmos_model() Assert.Equal(ValueGenerated.OnAddOrUpdate, eTag.ValueGenerated); Assert.Equal(PropertySaveBehavior.Ignore, eTag.GetAfterSaveBehavior()); Assert.Equal(PropertySaveBehavior.Ignore, eTag.GetBeforeSaveBehavior()); - Assert.Equal("_etag", CosmosPropertyExtensions.GetJsonPropertyName(eTag)); + Assert.Equal("_etag", eTag.GetJsonPropertyName()); Assert.Null(eTag.GetValueGeneratorFactory()); Assert.Null(eTag.GetValueConverter()); Assert.NotNull(eTag.GetValueComparer()); @@ -171,7 +171,7 @@ public virtual Task Basic_cosmos_model() Assert.Equal(ValueGenerated.Never, blob.ValueGenerated); Assert.Equal(PropertySaveBehavior.Save, blob.GetAfterSaveBehavior()); Assert.Equal(PropertySaveBehavior.Save, blob.GetBeforeSaveBehavior()); - Assert.Equal("JsonBlob", CosmosPropertyExtensions.GetJsonPropertyName(blob)); + Assert.Equal("JsonBlob", blob.GetJsonPropertyName()); Assert.Null(blob.GetValueGeneratorFactory()); Assert.Null(blob.GetValueConverter()); Assert.NotNull(blob.GetValueComparer()); @@ -186,7 +186,7 @@ public virtual Task Basic_cosmos_model() Assert.Equal(ValueGenerated.OnAddOrUpdate, jObject.ValueGenerated); Assert.Equal(PropertySaveBehavior.Ignore, jObject.GetAfterSaveBehavior()); Assert.Equal(PropertySaveBehavior.Ignore, jObject.GetBeforeSaveBehavior()); - Assert.Equal("", CosmosPropertyExtensions.GetJsonPropertyName(jObject)); + Assert.Equal("", jObject.GetJsonPropertyName()); Assert.Null(jObject.GetValueGeneratorFactory()); Assert.Null(jObject.GetValueConverter()); Assert.NotNull(jObject.GetValueComparer()); @@ -218,7 +218,6 @@ protected override void BuildBigModel(ModelBuilder modelBuilder, bool jsonColumn b.Ignore(e => e.RefTypeArray); b.Ignore(e => e.RefTypeList); }); - }); modelBuilder.Entity>>( @@ -350,13 +349,13 @@ protected override void BuildComplexTypesModel(ModelBuilder modelBuilder) { b.Ignore(e => e.RefTypeArray); b.Ignore(e => e.RefTypeList); - b.ComplexProperty(c => c.Principal, b => - { - b.Ignore(e => e.RefTypeList); - b.Ignore(e => e.RefTypeArray); - }); + b.ComplexProperty( + c => c.Principal, b => + { + b.Ignore(e => e.RefTypeList); + b.Ignore(e => e.RefTypeArray); + }); }); - }); } @@ -371,8 +370,11 @@ protected override void AssertBigModel(IModel model, bool jsonColumns) protected override int ExpectedComplexTypeProperties => 12; - protected override TestHelpers TestHelpers => CosmosTestHelpers.Instance; - protected override ITestStoreFactory TestStoreFactory => CosmosTestStoreFactory.Instance; + protected override TestHelpers TestHelpers + => CosmosTestHelpers.Instance; + + protected override ITestStoreFactory TestStoreFactory + => CosmosTestStoreFactory.Instance; protected override BuildSource AddReferences(BuildSource build, [CallerFilePath] string filePath = "") { diff --git a/test/EFCore.Cosmos.FunctionalTests/Storage/CosmosDatabaseCreatorTest.cs b/test/EFCore.Cosmos.FunctionalTests/Storage/CosmosDatabaseCreatorTest.cs index 5d879385922..dc683d4121d 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Storage/CosmosDatabaseCreatorTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Storage/CosmosDatabaseCreatorTest.cs @@ -8,7 +8,7 @@ namespace Microsoft.EntityFrameworkCore.Storage; [CosmosCondition(CosmosCondition.DoesNotUseTokenCredential)] public class CosmosDatabaseCreatorTest { - public static IEnumerable IsAsyncData = new object[][] { [false], [true] }; + public static IEnumerable IsAsyncData = [[false], [true]]; [ConditionalFact] public async Task EnsureCreated_returns_true_when_database_does_not_exist() @@ -86,20 +86,38 @@ public Task EnsureDeleted_returns_false_when_database_does_not_exist(bool async) Assert.False(a ? await creator.EnsureDeletedAsync() : creator.EnsureDeleted()); }); - private class BloggingContext(CosmosTestStore testStore) : DbContext + [ConditionalFact] + public async Task EnsureCreated_throws_for_missing_seed() + { + await using var testDatabase = await CosmosTestStore.CreateInitializedAsync("EnsureCreatedSeedTest"); + using var context = new BloggingContext(testDatabase, seed: true); + + Assert.Equal( + CoreStrings.MissingSeeder, + (await Assert.ThrowsAsync(() => context.Database.EnsureCreatedAsync())).Message); + } + + private class BloggingContext(CosmosTestStore testStore, bool seed = false) : DbContext { private readonly string _connectionUri = testStore.ConnectionUri; private readonly string _authToken = testStore.AuthToken; private readonly string _name = testStore.Name; protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - => optionsBuilder + { + optionsBuilder .UseCosmos( _connectionUri, _authToken, _name, b => b.ApplyConfiguration()); + if (seed) + { + optionsBuilder.UseSeeding((_, __) => { }); + } + } + protected override void OnModelCreating(ModelBuilder modelBuilder) { } diff --git a/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosConditionAttribute.cs b/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosConditionAttribute.cs index 44613056a6a..e1448e20ee2 100644 --- a/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosConditionAttribute.cs +++ b/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosConditionAttribute.cs @@ -29,10 +29,10 @@ public ValueTask IsMetAsync() public string SkipReason => string.Format( - "The test Cosmos account does not meet these conditions: '{0}'", - string.Join( - ", ", Enum.GetValues(typeof(CosmosCondition)) - .Cast() - .Where(Conditions.HasFlag) - .Select(f => Enum.GetName(typeof(CosmosCondition), f)))); + "The test Cosmos account does not meet these conditions: '{0}'", + string.Join( + ", ", Enum.GetValues(typeof(CosmosCondition)) + .Cast() + .Where(Conditions.HasFlag) + .Select(f => Enum.GetName(typeof(CosmosCondition), f)))); } diff --git a/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosModelAsserter.cs b/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosModelAsserter.cs index 5c7830ae316..6624496d805 100644 --- a/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosModelAsserter.cs +++ b/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosModelAsserter.cs @@ -11,7 +11,7 @@ protected CosmosModelAsserter() { } - public new static CosmosModelAsserter Instance { get; } = new(); + public static new CosmosModelAsserter Instance { get; } = new(); public override void AssertEqual( IEnumerable expectedProperties, diff --git a/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosTestHelpers.cs b/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosTestHelpers.cs index 4c5f87d3681..74ddb55fdca 100644 --- a/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosTestHelpers.cs +++ b/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosTestHelpers.cs @@ -2,8 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.EntityFrameworkCore.Cosmos.Diagnostics.Internal; -// ReSharper disable once CheckNamespace using Microsoft.EntityFrameworkCore.Cosmos.Internal; +// ReSharper disable once CheckNamespace namespace Microsoft.EntityFrameworkCore.TestUtilities; @@ -23,14 +23,14 @@ public override IServiceCollection AddProviderServices(IServiceCollection servic public override DbContextOptionsBuilder UseProviderOptions(DbContextOptionsBuilder optionsBuilder) => TestEnvironment.UseTokenCredential - ? optionsBuilder.UseCosmos( - TestEnvironment.DefaultConnection, - TestEnvironment.TokenCredential, - "UnitTests") - : optionsBuilder.UseCosmos( - TestEnvironment.DefaultConnection, - TestEnvironment.AuthToken, - "UnitTests"); + ? optionsBuilder.UseCosmos( + TestEnvironment.DefaultConnection, + TestEnvironment.TokenCredential, + "UnitTests") + : optionsBuilder.UseCosmos( + TestEnvironment.DefaultConnection, + TestEnvironment.AuthToken, + "UnitTests"); private static readonly string SyncMessage = CoreStrings.WarningAsErrorTemplate( diff --git a/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosTestStore.cs b/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosTestStore.cs index 1673d662679..c889a991c64 100644 --- a/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosTestStore.cs +++ b/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosTestStore.cs @@ -89,8 +89,8 @@ protected override DbContext CreateDefaultContext() public override DbContextOptionsBuilder AddProviderOptions(DbContextOptionsBuilder builder) => TestEnvironment.UseTokenCredential - ? builder.UseCosmos(ConnectionUri, TokenCredential, Name, _configureCosmos) - : builder.UseCosmos(ConnectionUri, AuthToken, Name, _configureCosmos); + ? builder.UseCosmos(ConnectionUri, TokenCredential, Name, _configureCosmos) + : builder.UseCosmos(ConnectionUri, AuthToken, Name, _configureCosmos); public static async ValueTask IsConnectionAvailableAsync() { @@ -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,16 +261,36 @@ public async Task EnsureCreatedAsync(DbContext context, CancellationToken var databaseAccount = await GetDBAccount(cancellationToken).ConfigureAwait(false); var collection = databaseAccount.Value.GetCosmosDBSqlDatabases(); - var sqlDatabaseCreateUpdateOptions = new CosmosDBSqlDatabaseCreateOrUpdateContent(TestEnvironment.AzureLocation, + var sqlDatabaseCreateUpdateContent = new CosmosDBSqlDatabaseCreateOrUpdateContent( + TestEnvironment.AzureLocation, new CosmosDBSqlDatabaseResourceInfo(Name)); if (await collection.ExistsAsync(Name, 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) @@ -281,7 +309,8 @@ private async Task EnsureDeletedAsync(DbContext context, CancellationToken return false; } - var databaseResponse = (await database.Value!.DeleteAsync(WaitUntil.Completed, cancellationToken).ConfigureAwait(false)).GetRawResponse(); + var databaseResponse = (await database.Value!.DeleteAsync(WaitUntil.Completed, cancellationToken).ConfigureAwait(false)) + .GetRawResponse(); return databaseResponse.Status == (int)HttpStatusCode.OK; } @@ -344,16 +373,14 @@ private async Task CreateContainersAsync(DbContext context) { AnalyticalStorageTtl = container.AnalyticalStoreTimeToLiveInSeconds, DefaultTtl = container.DefaultTimeToLive, - PartitionKey = new CosmosDBContainerPartitionKey - { - Version = 2 - } + PartitionKey = new CosmosDBContainerPartitionKey { Version = 2 } }; if (container.PartitionKeyStoreNames.Count > 1) { resource.PartitionKey.Kind = "MultiHash"; } + foreach (var partitionKey in container.PartitionKeyStoreNames) { resource.PartitionKey.Paths.Add("/" + partitionKey); @@ -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( @@ -407,6 +437,7 @@ await database.Value.GetCosmosDBSqlContainers().CreateOrUpdateAsync( { partitionKeyStoreNames = GetPartitionKeyStoreNames(entityType); } + analyticalTtl ??= entityType.GetAnalyticalStoreTimeToLive(); defaultTtl ??= entityType.GetDefaultTimeToLive(); throughput ??= entityType.GetThroughput(); @@ -422,7 +453,7 @@ await database.Value.GetCosmosDBSqlContainers().CreateOrUpdateAsync( } #pragma warning restore EF9103 - yield return new( + yield return new Cosmos.Storage.Internal.ContainerProperties( containerName, partitionKeyStoreNames, analyticalTtl, @@ -502,13 +533,11 @@ private async Task DeleteContainers(DbContext context) private static async Task SeedAsync(DbContext context) { var creator = (CosmosDatabaseCreator)context.GetService(); - await creator.SeedAsync().ConfigureAwait(false); + await creator.InsertDataAsync().ConfigureAwait(false); + await creator.SeedDataAsync(created: true).ConfigureAwait(false); } - public override void Dispose() - => throw new InvalidOperationException("Calling Dispose can cause deadlocks. Use DisposeAsync instead."); - - public override async Task DisposeAsync() + public override async ValueTask DisposeAsync() { if (_initialized && _dataFilePath == null) @@ -537,7 +566,8 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { if (TestEnvironment.UseTokenCredential) { - optionsBuilder.UseCosmos(_testStore.ConnectionUri, _testStore.TokenCredential, _testStore.Name, _testStore._configureCosmos); + optionsBuilder.UseCosmos( + _testStore.ConnectionUri, _testStore.TokenCredential, _testStore.Name, _testStore._configureCosmos); } else { diff --git a/test/EFCore.Cosmos.FunctionalTests/TestUtilities/TestSqlLoggerFactory.cs b/test/EFCore.Cosmos.FunctionalTests/TestUtilities/TestSqlLoggerFactory.cs index 261ba0b4ae0..81865e869dd 100644 --- a/test/EFCore.Cosmos.FunctionalTests/TestUtilities/TestSqlLoggerFactory.cs +++ b/test/EFCore.Cosmos.FunctionalTests/TestUtilities/TestSqlLoggerFactory.cs @@ -28,9 +28,7 @@ public TestSqlLoggerFactory() public TestSqlLoggerFactory(Func shouldLogCategory) : base(c => shouldLogCategory(c) || c == DbLoggerCategory.Database.Command.Name) - { - Logger = new TestSqlLogger(); - } + => Logger = new TestSqlLogger(); public IReadOnlyList SqlStatements => ((TestSqlLogger)Logger).SqlStatements; diff --git a/test/EFCore.Cosmos.FunctionalTests/ValueConvertersEndToEndCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/ValueConvertersEndToEndCosmosTest.cs index c4c50a518d7..98f9f14bc1b 100644 --- a/test/EFCore.Cosmos.FunctionalTests/ValueConvertersEndToEndCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/ValueConvertersEndToEndCosmosTest.cs @@ -3,8 +3,6 @@ namespace Microsoft.EntityFrameworkCore; -#nullable enable - public class ValueConvertersEndToEndCosmosTest(ValueConvertersEndToEndCosmosTest.ValueConvertersEndToEndCosmosFixture fixture) : ValueConvertersEndToEndTestBase(fixture) { diff --git a/test/EFCore.Cosmos.FunctionalTests/VectorSearchCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/VectorSearchCosmosTest.cs index c67ca8c3cba..04da9fd280c 100644 --- a/test/EFCore.Cosmos.FunctionalTests/VectorSearchCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/VectorSearchCosmosTest.cs @@ -99,16 +99,19 @@ public virtual async Task Query_for_vector_distance_bytes_array() await using var context = CreateContext(); var inputVector = new byte[] { 2, 1, 4, 3, 5, 2, 5, 7, 3, 1 }; - // See Issue #34402 - await Assert.ThrowsAsync( - () => context.Set().Select(e => EF.Functions.VectorDistance(e.BytesArray, inputVector)).ToListAsync()); + var booksFromStore = await context + .Set() + .Select(e => EF.Functions.VectorDistance(e.BytesArray, inputVector)) + .ToListAsync(); - // Assert.Equal(3, booksFromStore.Count); - // Assert.All(booksFromStore, s => Assert.NotEqual(0.0, s)); + Assert.Equal(3, booksFromStore.Count); + Assert.All(booksFromStore, s => Assert.NotEqual(0.0, s)); AssertSql( """ -SELECT VALUE c["BytesArray"] +@__p_1='[2,1,4,3,5,2,5,7,3,1]' + +SELECT VALUE VectorDistance(c["BytesArray"], @__p_1, false, {'distanceFunction':'cosine', 'dataType':'uint8'}) FROM root c """); } @@ -119,17 +122,20 @@ public virtual async Task Query_for_vector_distance_singles_array() await using var context = CreateContext(); var inputVector = new[] { 0.33f, -0.52f, 0.45f, -0.67f, 0.89f, -0.34f, 0.86f, -0.78f, 0.86f, -0.78f }; - // See Issue #34402 - await Assert.ThrowsAsync( - () => context.Set() - .Select(e => EF.Functions.VectorDistance(e.SinglesArray, inputVector, false, DistanceFunction.DotProduct)).ToListAsync()); + var booksFromStore = await context + .Set() + .Select( + e => EF.Functions.VectorDistance(e.SinglesArray, inputVector, false, DistanceFunction.DotProduct)) + .ToListAsync(); - // Assert.Equal(3, booksFromStore.Count); - // Assert.All(booksFromStore, s => Assert.NotEqual(0.0, s)); + Assert.Equal(3, booksFromStore.Count); + Assert.All(booksFromStore, s => Assert.NotEqual(0.0, s)); AssertSql( """ -SELECT VALUE c["SinglesArray"] +@__p_1='[0.33,-0.52,0.45,-0.67,0.89,-0.34,0.86,-0.78,0.86,-0.78]' + +SELECT VALUE VectorDistance(c["SinglesArray"], @__p_1, false, {'distanceFunction':'dotproduct', 'dataType':'float32'}) FROM root c """); } @@ -207,14 +213,20 @@ public virtual async Task Vector_distance_bytes_array_in_OrderBy() await using var context = CreateContext(); var inputVector = new byte[] { 2, 1, 4, 6, 5, 2, 5, 7, 3, 1 }; - // See Issue #34402 - await Assert.ThrowsAsync( - () => context.Set().OrderBy(e => EF.Functions.VectorDistance(e.BytesArray, inputVector)).ToListAsync()); - - // Assert.Equal(3, booksFromStore.Count); + var booksFromStore = await context + .Set() + .OrderBy(e => EF.Functions.VectorDistance(e.BytesArray, inputVector)) + .ToListAsync(); + Assert.Equal(3, booksFromStore.Count); AssertSql( -); + """ +@__p_1='[2,1,4,6,5,2,5,7,3,1]' + +SELECT VALUE c +FROM root c +ORDER BY VectorDistance(c["BytesArray"], @__p_1, false, {'distanceFunction':'cosine', 'dataType':'uint8'}) +"""); } [ConditionalFact] @@ -223,13 +235,20 @@ public virtual async Task Vector_distance_singles_array_in_OrderBy() await using var context = CreateContext(); var inputVector = new[] { 0.33f, -0.52f, 0.45f, -0.67f, 0.89f, -0.34f, 0.86f, -0.78f }; - // See Issue #34402 - await Assert.ThrowsAsync( - () => context.Set().OrderBy(e => EF.Functions.VectorDistance(e.SinglesArray, inputVector)).ToListAsync()); + var booksFromStore = await context + .Set() + .OrderBy(e => EF.Functions.VectorDistance(e.SinglesArray, inputVector)) + .ToListAsync(); - // Assert.Equal(3, booksFromStore.Count); + Assert.Equal(3, booksFromStore.Count); + AssertSql( + """ +@__p_1='[0.33,-0.52,0.45,-0.67,0.89,-0.34,0.86,-0.78]' - AssertSql(); +SELECT VALUE c +FROM root c +ORDER BY VectorDistance(c["SinglesArray"], @__p_1, false, {'distanceFunction':'cosine', 'dataType':'float32'}) +"""); } [ConditionalFact] @@ -384,7 +403,7 @@ protected override Task SeedAsync(PoolableDbContext context) NestedOwned = new Owned2 { Prop = "7" }, NestedOwnedCollection = new List { new() { Prop = "71" }, new() { Prop = "72" } } }, - OwnedCollection = new List { new Owned1 { Prop = 71 }, new Owned1 { Prop = 72 } } + OwnedCollection = new List { new() { Prop = 71 }, new() { Prop = 72 } } }; var book2 = new Book @@ -404,7 +423,7 @@ protected override Task SeedAsync(PoolableDbContext context) NestedOwned = new Owned2 { Prop = "7" }, NestedOwnedCollection = new List { new() { Prop = "71" }, new() { Prop = "72" } } }, - OwnedCollection = new List { new Owned1 { Prop = 71 }, new Owned1 { Prop = 72 } } + OwnedCollection = new List { new() { Prop = 71 }, new() { Prop = 72 } } }; var book3 = new Book @@ -424,7 +443,7 @@ protected override Task SeedAsync(PoolableDbContext context) NestedOwned = new Owned2 { Prop = "7" }, NestedOwnedCollection = new List { new() { Prop = "71" }, new() { Prop = "72" } } }, - OwnedCollection = new List { new Owned1 { Prop = 71 }, new Owned1 { Prop = 72 } } + OwnedCollection = new List { new() { Prop = 71 }, new() { Prop = 72 } } }; context.AddRange(book1, book2, book3); diff --git a/test/EFCore.Cosmos.Tests/Extensions/CosmosMetadataExtensionsTest.cs b/test/EFCore.Cosmos.Tests/Extensions/CosmosMetadataExtensionsTest.cs index e9cb25f25f9..7e6d8ba36bf 100644 --- a/test/EFCore.Cosmos.Tests/Extensions/CosmosMetadataExtensionsTest.cs +++ b/test/EFCore.Cosmos.Tests/Extensions/CosmosMetadataExtensionsTest.cs @@ -110,7 +110,7 @@ public void Can_get_and_set_hierarchical_partition_key_name() Assert.Null(((IConventionEntityType)entityType).GetPartitionKeyPropertyNamesConfigurationSource()); } - [ConditionalFact] + [ConditionalFact] public void Can_get_and_set_etag_name() { var modelBuilder = CreateModelBuilder(); diff --git a/test/EFCore.Cosmos.Tests/Infrastructure/CosmosModelValidatorTest.cs b/test/EFCore.Cosmos.Tests/Infrastructure/CosmosModelValidatorTest.cs index 37526b77314..252061170d1 100644 --- a/test/EFCore.Cosmos.Tests/Infrastructure/CosmosModelValidatorTest.cs +++ b/test/EFCore.Cosmos.Tests/Infrastructure/CosmosModelValidatorTest.cs @@ -194,10 +194,17 @@ public virtual void Detects_missing_partition_keys_one_last_type() public virtual void Detects_missing_partition_key_properties_composite_less_first() { var modelBuilder = CreateConventionModelBuilder(); - modelBuilder.Entity().ToContainer("Orders").HasPartitionKey(c => new { c.PartitionId, c.Id, c.Name }); + modelBuilder.Entity().ToContainer("Orders").HasPartitionKey( + c => new + { + c.PartitionId, + c.Id, + c.Name + }); modelBuilder.Entity().ToContainer("Orders").HasPartitionKey(c => new { c.PartitionId, c.Id }); - VerifyError(CosmosStrings.NoPartitionKey(nameof(Customer), "PartitionId,Id,Name", nameof(Order), "PartitionId,Id", "Orders"), modelBuilder); + VerifyError( + CosmosStrings.NoPartitionKey(nameof(Customer), "PartitionId,Id,Name", nameof(Order), "PartitionId,Id", "Orders"), modelBuilder); } [ConditionalFact] @@ -223,7 +230,8 @@ public virtual void Detects_missing_partition_key_properties_composite_three() b.ToContainer("Orders").HasPartitionKey(c => new { c.OrderId }); }); - VerifyError(CosmosStrings.NoPartitionKey(nameof(Customer), "PartitionId,Id", nameof(OrderProduct), "OrderId", "Orders"), modelBuilder); + VerifyError( + CosmosStrings.NoPartitionKey(nameof(Customer), "PartitionId,Id", nameof(OrderProduct), "OrderId", "Orders"), modelBuilder); } [ConditionalFact] @@ -365,11 +373,12 @@ public virtual void Detects_owned_type_mapped_to_a_container() var modelBuilder = CreateConventionModelBuilder(); modelBuilder.Entity(); modelBuilder.Entity( - ob => ob.OwnsOne(o => o.OrderDetails, b => - { - b.Property(CosmosJsonIdConvention.DefaultIdPropertyName) - .ToJsonProperty(CosmosJsonIdConvention.IdPropertyJsonName); - })); + ob => ob.OwnsOne( + o => o.OrderDetails, b => + { + b.Property(CosmosJsonIdConvention.DefaultIdPropertyName) + .ToJsonProperty(CosmosJsonIdConvention.IdPropertyJsonName); + })); modelBuilder.Model .GetEntityTypes() @@ -497,7 +506,6 @@ public virtual void Detects_vector_index_on_non_vector_property() } #pragma warning restore EF9103 - [ConditionalFact] public virtual void Detects_vector_property_with_unknown_data_type() { @@ -525,10 +533,11 @@ public virtual void Detects_unmappable_property() var modelBuilder = CreateConventionModelBuilder(); modelBuilder.Entity>>().ToContainer("Orders"); - VerifyError(CoreStrings.PropertyNotAdded( - typeof(RememberMyName>).ShortDisplayName(), - nameof(RememberMyName.ForgetMeNot), - typeof(Memory).ShortDisplayName()), modelBuilder); + VerifyError( + CoreStrings.PropertyNotAdded( + typeof(RememberMyName>).ShortDisplayName(), + nameof(RememberMyName.ForgetMeNot), + typeof(Memory).ShortDisplayName()), modelBuilder); } [ConditionalFact] @@ -537,10 +546,11 @@ public virtual void Detects_unmappable_list_property() var modelBuilder = CreateConventionModelBuilder(); modelBuilder.Entity[]>>().ToContainer("Orders"); - VerifyError(CoreStrings.PropertyNotAdded( - typeof(RememberMyName[]>).ShortDisplayName(), - nameof(RememberMyName.ForgetMeNot), - typeof(Memory[]).ShortDisplayName()), modelBuilder); + VerifyError( + CoreStrings.PropertyNotAdded( + typeof(RememberMyName[]>).ShortDisplayName(), + nameof(RememberMyName.ForgetMeNot), + typeof(Memory[]).ShortDisplayName()), modelBuilder); } private class RememberMyName diff --git a/test/EFCore.Cosmos.Tests/Storage/Internal/CosmosTypeMappingSourceTest.cs b/test/EFCore.Cosmos.Tests/Storage/Internal/CosmosTypeMappingSourceTest.cs index 67e2e2196a0..7b850e7e39a 100644 --- a/test/EFCore.Cosmos.Tests/Storage/Internal/CosmosTypeMappingSourceTest.cs +++ b/test/EFCore.Cosmos.Tests/Storage/Internal/CosmosTypeMappingSourceTest.cs @@ -68,15 +68,19 @@ public void Can_map_DateOnly() [ConditionalFact] public void Can_map_TimeOnly() - => Can_map_scalar_by_clr_type(new TimeOnly(20, 19, 12, 254), JTokenType.String, "\"20:19:12.254\""); + => Can_map_scalar_by_clr_type( + new TimeOnly(20, 19, 12, 254), JTokenType.String, "\"20:19:12.254\""); [ConditionalFact] public void Can_map_DateTime() - => Can_map_scalar_by_clr_type(new DateTime(2003, 12, 25, 20, 19, 12, 254), JTokenType.Date, "\"2003-12-25T20:19:12.254\""); + => Can_map_scalar_by_clr_type( + new DateTime(2003, 12, 25, 20, 19, 12, 254), JTokenType.Date, "\"2003-12-25T20:19:12.254\""); [ConditionalFact] public void Can_map_DateTimeOffset() - => Can_map_scalar_by_clr_type(new DateTimeOffset(2003, 12, 25, 20, 19, 12, 254, new TimeSpan(4, 30, 0)), JTokenType.Date, "\"2003-12-25T20:19:12.254+04:30\"", "DefaultDateTimeOffsetValueComparer"); + => Can_map_scalar_by_clr_type( + new DateTimeOffset(2003, 12, 25, 20, 19, 12, 254, new TimeSpan(4, 30, 0)), JTokenType.Date, "\"2003-12-25T20:19:12.254+04:30\"", + "DefaultDateTimeOffsetValueComparer"); [ConditionalFact] public void Can_map_TimeSpan() @@ -144,15 +148,19 @@ public void Can_map_nullable_DateOnly() [ConditionalFact] public void Can_map_nullable_TimeOnly() - => Can_map_scalar_by_clr_type(new TimeOnly(20, 19, 12, 254), JTokenType.String, "\"20:19:12.254\""); + => Can_map_scalar_by_clr_type( + new TimeOnly(20, 19, 12, 254), JTokenType.String, "\"20:19:12.254\""); [ConditionalFact] public void Can_map_nullable_DateTime() - => Can_map_scalar_by_clr_type(new DateTime(2003, 12, 25, 20, 19, 12, 254), JTokenType.Date, "\"2003-12-25T20:19:12.254\""); + => Can_map_scalar_by_clr_type( + new DateTime(2003, 12, 25, 20, 19, 12, 254), JTokenType.Date, "\"2003-12-25T20:19:12.254\""); [ConditionalFact] public void Can_map_nullable_DateTimeOffset() - => Can_map_scalar_by_clr_type(new DateTimeOffset(2003, 12, 25, 20, 19, 12, 254, new TimeSpan(4, 30, 0)), JTokenType.Date, "\"2003-12-25T20:19:12.254+04:30\"", "DefaultDateTimeOffsetValueComparer"); + => Can_map_scalar_by_clr_type( + new DateTimeOffset(2003, 12, 25, 20, 19, 12, 254, new TimeSpan(4, 30, 0)), JTokenType.Date, "\"2003-12-25T20:19:12.254+04:30\"", + "DefaultDateTimeOffsetValueComparer"); [ConditionalFact] public void Can_map_nullable_TimeSpan() @@ -209,78 +217,88 @@ public void Can_map_byte_array() [ConditionalFact] public void Can_map_sbyte_array() => Can_map_collection_by_clr_type>( - [1, -2, 3, -4, 5], "[1,-2,3,-4,5]", "ListOfValueTypesComparer", "ValueComparer", "ValueComparer" ); + [1, -2, 3, -4, 5], "[1,-2,3,-4,5]", "ListOfValueTypesComparer", "ValueComparer", + "ValueComparer"); [ConditionalFact] public void Can_map_short_array() => Can_map_collection_by_clr_type>( - [1, -2, 3, -4, 5], "[1,-2,3,-4,5]", "ListOfValueTypesComparer", "ValueComparer", "ValueComparer" ); + [1, -2, 3, -4, 5], "[1,-2,3,-4,5]", "ListOfValueTypesComparer", "ValueComparer", + "ValueComparer"); [ConditionalFact] public void Can_map_int_array() => Can_map_collection_by_clr_type>( - [1, -2, 3, -4, 5], "[1,-2,3,-4,5]", "ListOfValueTypesComparer", "ValueComparer", "ValueComparer" ); + [1, -2, 3, -4, 5], "[1,-2,3,-4,5]", "ListOfValueTypesComparer", "ValueComparer", "ValueComparer"); [ConditionalFact] public void Can_map_long_array() => Can_map_collection_by_clr_type>( - [1, -2, 3, -4, 5], "[1,-2,3,-4,5]", "ListOfValueTypesComparer", "ValueComparer", "ValueComparer" ); + [1, -2, 3, -4, 5], "[1,-2,3,-4,5]", "ListOfValueTypesComparer", "ValueComparer", "ValueComparer"); [ConditionalFact] public void Can_map_ushort_array() => Can_map_collection_by_clr_type>( - [1, 2, 3, 4, 5], "[1,2,3,4,5]", "ListOfValueTypesComparer", "ValueComparer", "ValueComparer" ); + [1, 2, 3, 4, 5], "[1,2,3,4,5]", "ListOfValueTypesComparer", "ValueComparer", + "ValueComparer"); [ConditionalFact] public void Can_map_uint_array() => Can_map_collection_by_clr_type>( - [1, 2, 3, 4, 5], "[1,2,3,4,5]", "ListOfValueTypesComparer", "ValueComparer", "ValueComparer" ); + [1, 2, 3, 4, 5], "[1,2,3,4,5]", "ListOfValueTypesComparer", "ValueComparer", "ValueComparer"); [ConditionalFact] public void Can_map_ulong_array() => Can_map_collection_by_clr_type>( - [1, 2, 3, 4, 5], "[1,2,3,4,5]", "ListOfValueTypesComparer", "ValueComparer", "ValueComparer" ); - + [1, 2, 3, 4, 5], "[1,2,3,4,5]", "ListOfValueTypesComparer", "ValueComparer", "ValueComparer"); [ConditionalFact] public void Can_map_sbyte_list() => Can_map_collection_by_clr_type, sbyte, JsonCollectionOfStructsReaderWriter, sbyte>>( - [1, -2, 3, -4, 5], "[1,-2,3,-4,5]", "ListOfValueTypesComparer, sbyte>", "ValueComparer>", "ValueComparer>" ); + [1, -2, 3, -4, 5], "[1,-2,3,-4,5]", "ListOfValueTypesComparer, sbyte>", "ValueComparer>", + "ValueComparer>"); [ConditionalFact] public void Can_map_short_list() => Can_map_collection_by_clr_type, short, JsonCollectionOfStructsReaderWriter, short>>( - [1, -2, 3, -4, 5], "[1,-2,3,-4,5]", "ListOfValueTypesComparer, short>", "ValueComparer>", "ValueComparer>" ); + [1, -2, 3, -4, 5], "[1,-2,3,-4,5]", "ListOfValueTypesComparer, short>", "ValueComparer>", + "ValueComparer>"); [ConditionalFact] public void Can_map_int_list() => Can_map_collection_by_clr_type, int, JsonCollectionOfStructsReaderWriter, int>>( - [1, -2, 3, -4, 5], "[1,-2,3,-4,5]", "ListOfValueTypesComparer, int>", "ValueComparer>", "ValueComparer>" ); + [1, -2, 3, -4, 5], "[1,-2,3,-4,5]", "ListOfValueTypesComparer, int>", "ValueComparer>", + "ValueComparer>"); [ConditionalFact] public void Can_map_long_list() => Can_map_collection_by_clr_type, long, JsonCollectionOfStructsReaderWriter, long>>( - [1, -2, 3, -4, 5], "[1,-2,3,-4,5]", "ListOfValueTypesComparer, long>", "ValueComparer>", "ValueComparer>" ); + [1, -2, 3, -4, 5], "[1,-2,3,-4,5]", "ListOfValueTypesComparer, long>", "ValueComparer>", + "ValueComparer>"); [ConditionalFact] public void Can_map_byte_list() => Can_map_collection_by_clr_type, byte, JsonCollectionOfStructsReaderWriter, byte>>( - [1, 2, 3, 4, 5], "[1,2,3,4,5]", "ListOfValueTypesComparer, byte>", "ValueComparer>", "ValueComparer>" ); + [1, 2, 3, 4, 5], "[1,2,3,4,5]", "ListOfValueTypesComparer, byte>", "ValueComparer>", + "ValueComparer>"); [ConditionalFact] public void Can_map_ushort_list() => Can_map_collection_by_clr_type, ushort, JsonCollectionOfStructsReaderWriter, ushort>>( - [1, 2, 3, 4, 5], "[1,2,3,4,5]", "ListOfValueTypesComparer, ushort>", "ValueComparer>", "ValueComparer>" ); + [1, 2, 3, 4, 5], "[1,2,3,4,5]", "ListOfValueTypesComparer, ushort>", "ValueComparer>", + "ValueComparer>"); [ConditionalFact] public void Can_map_uint_list() => Can_map_collection_by_clr_type, uint, JsonCollectionOfStructsReaderWriter, uint>>( - [1, 2, 3, 4, 5], "[1,2,3,4,5]", "ListOfValueTypesComparer, uint>", "ValueComparer>", "ValueComparer>" ); + [1, 2, 3, 4, 5], "[1,2,3,4,5]", "ListOfValueTypesComparer, uint>", "ValueComparer>", + "ValueComparer>"); [ConditionalFact] public void Can_map_ulong_list() => Can_map_collection_by_clr_type, ulong, JsonCollectionOfStructsReaderWriter, ulong>>( - [1, 2, 3, 4, 5], "[1,2,3,4,5]", "ListOfValueTypesComparer, ulong>", "ValueComparer>", "ValueComparer>" ); + [1, 2, 3, 4, 5], "[1,2,3,4,5]", "ListOfValueTypesComparer, ulong>", "ValueComparer>", + "ValueComparer>"); private void Can_map_collection_by_clr_type( TCollection value, @@ -382,19 +400,19 @@ protected IModel CreateModel() protected CoreTypeMapping GetTypeMapping(Type propertyType, bool? nullable = null) { - var modelBuilder = CreateModelBuilder(); - var entityType = modelBuilder.Entity(); - entityType.Property(e => e.Id); - var property = entityType.Property(propertyType, "MyProp").Metadata; + var modelBuilder = CreateModelBuilder(); + var entityType = modelBuilder.Entity(); + entityType.Property(e => e.Id); + var property = entityType.Property(propertyType, "MyProp").Metadata; - if (nullable.HasValue) - { - property.IsNullable = nullable.Value; - } + if (nullable.HasValue) + { + property.IsNullable = nullable.Value; + } - var model = modelBuilder.Model.FinalizeModel(); + var model = modelBuilder.Model.FinalizeModel(); - return CreateTypeMappingSource(model).FindMapping(model.FindEntityType(typeof(MyType))!.FindProperty(property.Name)!)!; + return CreateTypeMappingSource(model).FindMapping(model.FindEntityType(typeof(MyType))!.FindProperty(property.Name)!)!; } private class MyType diff --git a/test/EFCore.Cosmos.Tests/ValueGeneration/IdValueGeneratorTest.cs b/test/EFCore.Cosmos.Tests/ValueGeneration/IdValueGeneratorTest.cs index 45b4ae8371f..e5683496ee8 100644 --- a/test/EFCore.Cosmos.Tests/ValueGeneration/IdValueGeneratorTest.cs +++ b/test/EFCore.Cosmos.Tests/ValueGeneration/IdValueGeneratorTest.cs @@ -107,9 +107,9 @@ public static readonly ValueConverter Converter public bool Equals(BytesStruct other) => Value == null - && other.Value == null + && other.Value == null || other.Value != null - && Value?.SequenceEqual(other.Value) == true; + && Value?.SequenceEqual(other.Value) == true; public override int GetHashCode() { diff --git a/test/EFCore.CrossStore.FunctionalTests/ConfigurationPatternsTest.cs b/test/EFCore.CrossStore.FunctionalTests/ConfigurationPatternsTest.cs index ae181a16c9f..4bb95ee5669 100644 --- a/test/EFCore.CrossStore.FunctionalTests/ConfigurationPatternsTest.cs +++ b/test/EFCore.CrossStore.FunctionalTests/ConfigurationPatternsTest.cs @@ -251,9 +251,7 @@ public BlogContext() } public BlogContext(IServiceProvider serviceProvider) - { - _serviceProvider = serviceProvider; - } + => _serviceProvider = serviceProvider; // ReSharper disable once UnusedAutoPropertyAccessor.Local public DbSet Blogs { get; set; } @@ -279,9 +277,7 @@ public ExternalProviderContext() } public ExternalProviderContext(IServiceProvider serviceProvider) - { - _serviceProvider = serviceProvider; - } + => _serviceProvider = serviceProvider; protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder @@ -290,23 +286,15 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) } public async Task InitializeAsync() - { - ExistingTestStore = await Fixture.CreateTestStoreAsync(SqlServerTestStoreFactory.Instance, StoreName, SeedAsync); - } + => ExistingTestStore = await Fixture.CreateTestStoreAsync(SqlServerTestStoreFactory.Instance, StoreName, SeedAsync); - public Task DisposeAsync() - { - ExistingTestStore.Dispose(); - return Task.CompletedTask; - } + public async Task DisposeAsync() + => await ExistingTestStore.DisposeAsync(); } public async Task InitializeAsync() => ExistingTestStore = await Fixture.CreateTestStoreAsync(SqlServerTestStoreFactory.Instance, StoreName, SeedAsync); - public Task DisposeAsync() - { - ExistingTestStore.Dispose(); - return Task.CompletedTask; - } + public async Task DisposeAsync() + => await ExistingTestStore.DisposeAsync(); } diff --git a/test/EFCore.CrossStore.FunctionalTests/DiscriminatorTest.cs b/test/EFCore.CrossStore.FunctionalTests/DiscriminatorTest.cs index 1965543d645..db106273704 100644 --- a/test/EFCore.CrossStore.FunctionalTests/DiscriminatorTest.cs +++ b/test/EFCore.CrossStore.FunctionalTests/DiscriminatorTest.cs @@ -87,6 +87,7 @@ private class Context4285 : DbContext public DbSet Products { get; set; } public DbSet SubProducts { get; set; } public DbSet SubProducts2 { get; set; } + // ReSharper disable once UnusedAutoPropertyAccessor.Local public DbSet IntProducts { get; set; } public DbSet SubIntProducts { get; set; } diff --git a/test/EFCore.CrossStore.FunctionalTests/EndToEndTest.cs b/test/EFCore.CrossStore.FunctionalTests/EndToEndTest.cs index 083b173aadc..68ac9800ab0 100644 --- a/test/EFCore.CrossStore.FunctionalTests/EndToEndTest.cs +++ b/test/EFCore.CrossStore.FunctionalTests/EndToEndTest.cs @@ -64,11 +64,8 @@ protected CrossStoreContext CreateContext() public async Task InitializeAsync() => TestStore = await Fixture.CreateTestStoreAsync(TestStoreFactory, "CrossStoreTest"); - public Task DisposeAsync() - { - TestStore.Dispose(); - return Task.CompletedTask; - } + public async Task DisposeAsync() + => await TestStore.DisposeAsync(); } public class InMemoryEndToEndTest(CrossStoreFixture fixture) : EndToEndTest(fixture), IClassFixture diff --git a/test/EFCore.Design.Tests/Design/DbContextActivatorTest.cs b/test/EFCore.Design.Tests/Design/DbContextActivatorTest.cs index 93a0611f456..b0486d2b961 100644 --- a/test/EFCore.Design.Tests/Design/DbContextActivatorTest.cs +++ b/test/EFCore.Design.Tests/Design/DbContextActivatorTest.cs @@ -37,9 +37,7 @@ public void CreateInstance_throws_if_constructor_throws() private class ThrowingTestContext : DbContext { public ThrowingTestContext() - { - throw new Exception("Bang!"); - } + => throw new Exception("Bang!"); protected override void OnConfiguring(DbContextOptionsBuilder options) => options diff --git a/test/EFCore.Design.Tests/Design/DesignTimeServicesTest.cs b/test/EFCore.Design.Tests/Design/DesignTimeServicesTest.cs index 94a072271cb..ee13f8d8c34 100644 --- a/test/EFCore.Design.Tests/Design/DesignTimeServicesTest.cs +++ b/test/EFCore.Design.Tests/Design/DesignTimeServicesTest.cs @@ -192,8 +192,14 @@ public bool IsValidId(string value) public class ExtensionHistoryRepository : IHistoryRepository { - public void Create() => throw new NotImplementedException(); - public Task CreateAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException(); + public virtual LockReleaseBehavior LockReleaseBehavior => LockReleaseBehavior.Explicit; + + public void Create() + => throw new NotImplementedException(); + + public Task CreateAsync(CancellationToken cancellationToken = default) + => throw new NotImplementedException(); + public bool Exists() => throw new NotImplementedException(); @@ -218,10 +224,10 @@ public string GetCreateIfNotExistsScript() public string GetCreateScript() => throw new NotImplementedException(); - public IDisposable GetDatabaseLock(TimeSpan timeout) + public IMigrationsDatabaseLock AcquireDatabaseLock() => throw new NotImplementedException(); - public Task GetDatabaseLockAsync(TimeSpan timeout, CancellationToken cancellationToken = default) + public Task AcquireDatabaseLockAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException(); public string GetDeleteScript(string migrationId) @@ -260,6 +266,8 @@ public bool IsValidId(string value) public class ContextHistoryRepository : IHistoryRepository { + public virtual LockReleaseBehavior LockReleaseBehavior => LockReleaseBehavior.Explicit; + public bool Exists() => throw new NotImplementedException(); @@ -290,10 +298,10 @@ public void Create() public Task CreateAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException(); - public IDisposable GetDatabaseLock(TimeSpan timeout) + public IMigrationsDatabaseLock AcquireDatabaseLock() => throw new NotImplementedException(); - public Task GetDatabaseLockAsync(TimeSpan timeout, CancellationToken cancellationToken = default) + public Task AcquireDatabaseLockAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException(); public string GetDeleteScript(string migrationId) diff --git a/test/EFCore.Design.Tests/Design/Internal/CSharpHelperTest.cs b/test/EFCore.Design.Tests/Design/Internal/CSharpHelperTest.cs index 205cb31ec12..d0cc4a4bb74 100644 --- a/test/EFCore.Design.Tests/Design/Internal/CSharpHelperTest.cs +++ b/test/EFCore.Design.Tests/Design/Internal/CSharpHelperTest.cs @@ -894,9 +894,7 @@ public SimpleTestTypeFactory() } public SimpleTestTypeFactory(string factoryArg) - { - FactoryArg = factoryArg; - } + => FactoryArg = factoryArg; public string FactoryArg { get; } = null!; diff --git a/test/EFCore.Design.Tests/Design/Internal/DbContextOperationsTest.cs b/test/EFCore.Design.Tests/Design/Internal/DbContextOperationsTest.cs index 68e7662ccef..0ab95ab7bfd 100644 --- a/test/EFCore.Design.Tests/Design/Internal/DbContextOperationsTest.cs +++ b/test/EFCore.Design.Tests/Design/Internal/DbContextOperationsTest.cs @@ -24,7 +24,8 @@ public void CreateContext_gets_service_when_context_factory_used() public void CreateContext_throws_if_context_type_not_found() => Assert.Equal( DesignStrings.NoContextWithName(typeof(TestContextFromFactory).FullName), - Assert.Throws(() => CreateOperations(typeof(TestProgramRelationalBad)).CreateContext(typeof(TestContextFromFactory).FullName)).Message); + Assert.Throws( + () => CreateOperations(typeof(TestProgramRelationalBad)).CreateContext(typeof(TestContextFromFactory).FullName)).Message); [ConditionalFact] public void CreateContext_throws_if_ambiguous_context_type_by_case() @@ -200,7 +201,8 @@ public void CreateAllContexts_creates_all_contexts() new TestAppServiceProviderFactory(assembly, reporter, throwOnCreate: true)); var contexts = operations.CreateAllContexts().ToList(); - Assert.Collection(contexts, + Assert.Collection( + contexts, c => Assert.Equal(nameof(BaseContext), Assert.IsType(c).FactoryUsed), c => Assert.Equal(nameof(DerivedContext), Assert.IsType(c).FactoryUsed)); @@ -228,8 +230,10 @@ public void Optimize_throws_when_no_contexts() Assert.Equal( DesignStrings.NoContextsToOptimize, - Assert.Throws(() => - operations.Optimize(null, null, contextTypeName: "*", null, scaffoldModel: true, precompileQueries: false)).Message); + Assert.Throws( + () => + operations.Optimize( + null, null, contextTypeName: "*", null, scaffoldModel: true, precompileQueries: false, nativeAot: false)).Message); Assert.DoesNotContain(reporter.Messages, m => m.Level == LogLevel.Critical); Assert.DoesNotContain(reporter.Messages, m => m.Level == LogLevel.Error); @@ -253,7 +257,7 @@ public void Optimize_shows_warning_when_nothing_was_generated() args: [], new TestAppServiceProviderFactory(assembly, reporter, throwOnCreate: true)); - operations.Optimize(null, null, contextTypeName: "*", null, scaffoldModel: true, precompileQueries: false); + operations.Optimize(null, null, contextTypeName: "*", null, scaffoldModel: true, precompileQueries: false, nativeAot: false); Assert.DoesNotContain(reporter.Messages, m => m.Level == LogLevel.Critical); Assert.DoesNotContain(reporter.Messages, m => m.Level == LogLevel.Error); @@ -393,9 +397,7 @@ private static TestWebHost CreateWebHost(Func throw new Exception("This isn't the constructor you're looking for."); public TestContext(DbContextOptions options) : base(options) @@ -406,9 +408,7 @@ public TestContext(DbContextOptions options) private class TestContextFromFactory : DbContext { private TestContextFromFactory() - { - throw new Exception("This isn't the constructor you're looking for."); - } + => throw new Exception("This isn't the constructor you're looking for."); public TestContextFromFactory(DbContextOptions options) : base(options) @@ -419,9 +419,7 @@ public TestContextFromFactory(DbContextOptions options) private class Testcontext : DbContext { public Testcontext() - { - throw new Exception("This isn't the constructor you're looking for."); - } + => throw new Exception("This isn't the constructor you're looking for."); public Testcontext(DbContextOptions options) : base(options) diff --git a/test/EFCore.Design.Tests/Design/Internal/LanguageBasedSelectorTests.cs b/test/EFCore.Design.Tests/Design/Internal/LanguageBasedSelectorTests.cs index 86a361c08d1..f478b78f16b 100644 --- a/test/EFCore.Design.Tests/Design/Internal/LanguageBasedSelectorTests.cs +++ b/test/EFCore.Design.Tests/Design/Internal/LanguageBasedSelectorTests.cs @@ -82,7 +82,8 @@ public void Select_uses_last_when_multiple_services() Assert.Same(lastService, result); } - private class TestLanguageBasedSelector(params TestLanguageBasedService[] services) : LanguageBasedSelector(services); + private class TestLanguageBasedSelector(params TestLanguageBasedService[] services) + : LanguageBasedSelector(services); private class TestLanguageBasedService(string language) : ILanguageBasedService { diff --git a/test/EFCore.Design.Tests/Design/OperationExecutorTest.cs b/test/EFCore.Design.Tests/Design/OperationExecutorTest.cs index d661113a7a2..96ac004bddd 100644 --- a/test/EFCore.Design.Tests/Design/OperationExecutorTest.cs +++ b/test/EFCore.Design.Tests/Design/OperationExecutorTest.cs @@ -1180,21 +1180,15 @@ private class MockOperation : OperationExecutor.OperationBase { public MockOperation(IOperationResultHandler resultHandler, Action action) : base(resultHandler) - { - Execute(action); - } + => Execute(action); public MockOperation(IOperationResultHandler resultHandler, Func action) : base(resultHandler) - { - Execute(action); - } + => Execute(action); public MockOperation(IOperationResultHandler resultHandler, Func> action) : base(resultHandler) - { - Execute(action); - } + => Execute(action); } } diff --git a/test/EFCore.Design.Tests/DesignApiConsistencyTest.cs b/test/EFCore.Design.Tests/DesignApiConsistencyTest.cs index 465fded100e..7a54b4ffc81 100644 --- a/test/EFCore.Design.Tests/DesignApiConsistencyTest.cs +++ b/test/EFCore.Design.Tests/DesignApiConsistencyTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore; -public class DesignApiConsistencyTest(DesignApiConsistencyTest.DesignApiConsistencyFixture fixture) : ApiConsistencyTestBase(fixture) +public class DesignApiConsistencyTest(DesignApiConsistencyTest.DesignApiConsistencyFixture fixture) + : ApiConsistencyTestBase(fixture) { protected override void AddServices(ServiceCollection serviceCollection) { diff --git a/test/EFCore.Design.Tests/DesignTimeFlagTest.cs b/test/EFCore.Design.Tests/DesignTimeFlagTest.cs index 2e94d7330ea..6edeecd0a94 100644 --- a/test/EFCore.Design.Tests/DesignTimeFlagTest.cs +++ b/test/EFCore.Design.Tests/DesignTimeFlagTest.cs @@ -66,9 +66,7 @@ private class MockOperation : OperationExecutor.OperationBase { public MockOperation(IOperationResultHandler resultHandler, Func action) : base(resultHandler) - { - Execute(action); - } + => Execute(action); } } diff --git a/test/EFCore.Design.Tests/EFCore.Design.Tests.csproj b/test/EFCore.Design.Tests/EFCore.Design.Tests.csproj index e7ff39b5371..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.Design.Tests/Migrations/Design/CSharpMigrationOperationGeneratorTest.cs b/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationOperationGeneratorTest.cs index 3539ea13791..ba445da389c 100644 --- a/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationOperationGeneratorTest.cs +++ b/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationOperationGeneratorTest.cs @@ -2327,20 +2327,14 @@ public void SqlOperation_required_args() [new Coordinate(1.1, 2.2), new Coordinate(2.2, 2.2), new Coordinate(2.2, 1.1), new Coordinate(7.1, 7.2)]) { SRID = 4326 }; private static readonly LineString _lineString2 = new( - [new Coordinate(7.1, 7.2), new Coordinate(20.2, 20.2), new Coordinate(20.20, 1.1), new Coordinate(70.1, 70.2)]) - { - SRID = 4326 - }; + [new Coordinate(7.1, 7.2), new Coordinate(20.2, 20.2), new Coordinate(20.20, 1.1), new Coordinate(70.1, 70.2)]) { SRID = 4326 }; private static readonly MultiPoint _multiPoint = new( [new Point(1.1, 2.2), new Point(2.2, 2.2), new Point(2.2, 1.1)]) { SRID = 4326 }; private static readonly Polygon _polygon1 = new( new LinearRing( - [new Coordinate(1.1, 2.2), new Coordinate(2.2, 2.2), new Coordinate(2.2, 1.1), new Coordinate(1.1, 2.2)])) - { - SRID = 4326 - }; + [new Coordinate(1.1, 2.2), new Coordinate(2.2, 2.2), new Coordinate(2.2, 1.1), new Coordinate(1.1, 2.2)])) { SRID = 4326 }; private static readonly Polygon _polygon2 = new( new LinearRing( @@ -2358,10 +2352,7 @@ public void SqlOperation_required_args() [_polygon2, _polygon1]) { SRID = 4326 }; private static readonly GeometryCollection _geometryCollection = new( - [_lineString1, _lineString2, _multiPoint, _polygon1, _polygon2, _point1, _multiLineString, _multiPolygon]) - { - SRID = 4326 - }; + [_lineString1, _lineString2, _multiPoint, _polygon1, _polygon2, _point1, _multiLineString, _multiPolygon]) { SRID = 4326 }; [ConditionalFact] public void InsertDataOperation_all_args() diff --git a/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.ModelSnapshot.cs b/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.ModelSnapshot.cs index 969c3bbf4ac..d9216f9dfe5 100644 --- a/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.ModelSnapshot.cs +++ b/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.ModelSnapshot.cs @@ -23,7 +23,6 @@ namespace Microsoft.EntityFrameworkCore.Migrations.Design; public partial class CSharpMigrationsGeneratorTest { - [ConditionalFact] public void Snapshots_compile() { @@ -870,15 +869,18 @@ public virtual void Entities_are_stored_in_model_snapshot_for_TPT() Assert.Equal(5, model.GetAnnotations().Count()); Assert.Equal(3, model.GetEntityTypes().Count()); - var abstractBase = model.FindEntityType("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+AbstractBase"); + var abstractBase = model.FindEntityType( + "Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+AbstractBase"); Assert.Equal("AbstractBase", abstractBase.GetTableName()); Assert.Equal("TPT", abstractBase.GetMappingStrategy()); - var baseType = model.FindEntityType("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+BaseEntity"); + var baseType = model.FindEntityType( + "Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+BaseEntity"); Assert.Equal("BaseEntity", baseType.GetTableName()); Assert.Equal("DefaultSchema", baseType.GetSchema()); - var derived = model.FindEntityType("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+DerivedEntity"); + var derived = model.FindEntityType( + "Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+DerivedEntity"); Assert.Equal("DerivedEntity", derived.GetTableName()); Assert.Equal("foo", derived.GetSchema()); }); @@ -1050,16 +1052,19 @@ public virtual void Entities_are_stored_in_model_snapshot_for_TPC() Assert.Equal(6, model.GetAnnotations().Count()); Assert.Equal(3, model.GetEntityTypes().Count()); - var abstractBase = model.FindEntityType("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+AbstractBase"); + var abstractBase = model.FindEntityType( + "Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+AbstractBase"); Assert.Null(abstractBase.GetTableName()); Assert.Null(abstractBase.GetViewName()); Assert.Equal("TPC", abstractBase.GetMappingStrategy()); - var baseType = model.FindEntityType("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+BaseEntity"); + var baseType = model.FindEntityType( + "Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+BaseEntity"); Assert.Equal("BaseEntity", baseType.GetTableName()); Assert.Null(baseType.GetViewName()); - var derived = model.FindEntityType("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+DerivedEntity"); + var derived = model.FindEntityType( + "Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+DerivedEntity"); Assert.Equal("DerivedEntity", derived.GetTableName()); Assert.Equal("DerivedView", derived.GetViewName()); }); @@ -1210,7 +1215,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) Assert.Equal(6, model.GetAnnotations().Count()); Assert.Equal(6, model.GetEntityTypes().Count()); - var animalType = model.FindEntityType("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+Animal"); + var animalType = + model.FindEntityType("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+Animal"); Assert.Null(animalType.GetTableName()); Assert.Null(animalType.GetViewName()); Assert.Equal("TPC", animalType.GetMappingStrategy()); @@ -4378,14 +4384,17 @@ public virtual void Owned_types_mapped_to_json_are_stored_in_snapshot() b3.Property("EntityWithStringKeyEntityWithTwoPropertiesEntityWithOnePropertyId") .HasColumnType("int"); - b3.Property("Id") + b3.Property("__synthesizedOrdinal") .ValueGeneratedOnAdd() .HasColumnType("int"); + b3.Property("Id") + .HasColumnType("int"); + b3.Property("Name") .HasColumnType("nvarchar(max)"); - b3.HasKey("EntityWithStringKeyEntityWithTwoPropertiesEntityWithOnePropertyId", "Id"); + b3.HasKey("EntityWithStringKeyEntityWithTwoPropertiesEntityWithOnePropertyId", "__synthesizedOrdinal"); b3.ToTable("EntityWithOneProperty", "DefaultSchema"); @@ -4424,7 +4433,7 @@ public virtual void Owned_types_mapped_to_json_are_stored_in_snapshot() var ownedProperties1 = ownedType1.GetProperties().ToList(); Assert.Equal("EntityWithOnePropertyId", ownedProperties1[0].Name); Assert.Equal("AlternateId", ownedProperties1[1].Name); - Assert.Equal("NotKey", RelationalPropertyExtensions.GetJsonPropertyName(ownedProperties1[1])); + Assert.Equal("NotKey", ownedProperties1[1].GetJsonPropertyName()); Assert.Equal(nameof(EntityWithOneProperty), ownedType1.GetTableName()); Assert.Equal("EntityWithTwoProperties", ownedType1.GetContainerColumnName()); @@ -4453,14 +4462,15 @@ public virtual void Owned_types_mapped_to_json_are_stored_in_snapshot() Assert.Equal(nameof(EntityWithStringProperty), ownedType3.DisplayName()); var pkProperties3 = ownedType3.FindPrimaryKey().Properties; Assert.Equal("EntityWithStringKeyEntityWithTwoPropertiesEntityWithOnePropertyId", pkProperties3[0].Name); - Assert.Equal("Id", pkProperties3[1].Name); + Assert.Equal("__synthesizedOrdinal", pkProperties3[1].Name); var ownedProperties3 = ownedType3.GetProperties().ToList(); - Assert.Equal(3, ownedProperties3.Count); + Assert.Equal(4, ownedProperties3.Count); Assert.Equal("EntityWithStringKeyEntityWithTwoPropertiesEntityWithOnePropertyId", ownedProperties3[0].Name); - Assert.Equal("Id", ownedProperties3[1].Name); - Assert.Equal("Name", ownedProperties3[2].Name); + Assert.Equal("__synthesizedOrdinal", ownedProperties3[1].Name); + Assert.Equal("Id", ownedProperties3[2].Name); + Assert.Equal("Name", ownedProperties3[3].Name); }); private class Order @@ -5008,13 +5018,11 @@ public virtual void Property_column_name_is_stored_in_snapshot_when_DefaultColum model.GetRelationalModel().Tables, t => { - Assert.Equal("BarBase", t.Name); Assert.Equal(["Id", "Discriminator", "FooExtensionId"], t.Columns.Select(t => t.Name)); }, t => { - Assert.Equal("FooExtension", t.Name); Assert.Equal(["Id"], t.Columns.Select(t => t.Name)); }); @@ -5025,7 +5033,7 @@ public virtual void Generic_entity_type_with_owned_entities() => Test( modelBuilder => modelBuilder.Entity>().OwnsOne(e => e.Child), AddBoilerPlate( - """ + """ modelBuilder .HasDefaultSchema("DefaultSchema") .HasAnnotation("Relational:MaxIdentifierLength", 128); @@ -5071,7 +5079,8 @@ public virtual void Generic_entity_type_with_owned_entities() """), model => { - var parentType = model.FindEntityType("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+Parrot"); + var parentType = model.FindEntityType( + "Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+Parrot"); Assert.NotNull(parentType); Assert.NotNull(parentType.FindNavigation("Child")!.TargetEntityType); @@ -5084,7 +5093,7 @@ public virtual void Non_generic_entity_type_with_owned_entities() => Test( modelBuilder => modelBuilder.Entity().OwnsOne(e => e.Child), AddBoilerPlate( - """ + """ modelBuilder .HasDefaultSchema("DefaultSchema") .HasAnnotation("Relational:MaxIdentifierLength", 128); @@ -5130,7 +5139,8 @@ public virtual void Non_generic_entity_type_with_owned_entities() """), model => { - var parentType = model.FindEntityType("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+Parrot"); + var parentType = + model.FindEntityType("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+Parrot"); Assert.NotNull(parentType); Assert.NotNull(parentType.FindNavigation("Child")!.TargetEntityType); @@ -5203,7 +5213,8 @@ public virtual void Property_column_name_on_specific_table_is_stored_in_snapshot Assert.Collection( o.GetEntityTypes(), t => Assert.Equal("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+BaseEntity", t.Name), - t => Assert.Equal("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+DerivedEntity", t.Name), + t => Assert.Equal( + "Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+DerivedEntity", t.Name), t => { Assert.Equal( @@ -5933,6 +5944,72 @@ public virtual void SQLServer_property_legacy_identity_seed_int_annotation() #endregion + #region Primitive collection + + [ConditionalFact] + public virtual void PrimitiveCollection_is_stored_in_snapshot() + => Test( + builder => + { + builder.Entity() + .PrimitiveCollection>("List") + .IsSparse() + .IsFixedLength() + .HasMaxLength(100) + .IsUnicode() + .UseCollation("ListCollation") + .HasSentinel([]) + .HasColumnName("ListColumn") + .HasColumnType("nvarchar") + .HasColumnOrder(1) + .HasComment("ListComment") + .HasComputedColumnSql("ListSql") + .HasJsonPropertyName("ListJson") + .ElementType(b => b.HasConversion()) + .ValueGeneratedOnUpdateSometimes() + .HasAnnotation("AnnotationName", "AnnotationValue"); + + builder.Ignore(); + }, + AddBoilerPlate( + GetHeading() + + """ + modelBuilder.Entity("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+EntityWithOneProperty", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.PrimitiveCollection("List") + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(100) + .IsUnicode(true) + .HasColumnType("nvarchar") + .HasColumnName("ListColumn") + .HasColumnOrder(1) + .HasComputedColumnSql("ListSql") + .IsFixedLength() + .HasComment("ListComment") + .UseCollation("ListCollation") + .HasAnnotation("AnnotationName", "AnnotationValue") + .HasAnnotation("Relational:JsonPropertyName", "ListJson"); + + SqlServerPrimitiveCollectionBuilderExtensions.IsSparse(b.PrimitiveCollection("List")); + + b.HasKey("Id"); + + b.ToTable("EntityWithOneProperty", "DefaultSchema"); + }); +"""), + o => + { + var property = o.GetEntityTypes().First().FindProperty("List"); + Assert.Equal("AnnotationValue", property["AnnotationName"]); + }); + #endregion + #region Complex types [ConditionalFact] @@ -5947,8 +6024,13 @@ public virtual void Complex_properties_are_stored_in_snapshot() eo => eo.EntityWithTwoProperties, eb => { eb.IsRequired(); - eb.Property(e => e.AlternateId).HasColumnOrder(1); - eb.ComplexProperty(e => e.EntityWithStringKey).IsRequired(); + eb.Property(e => e.AlternateId).HasColumnOrder(1).IsSparse(); + eb.PrimitiveCollection>("List") + .HasColumnType("nvarchar(max)") + .IsSparse(); + eb.ComplexProperty(e => e.EntityWithStringKey) + .IsRequired() + .Ignore(e => e.Properties); eb.HasPropertyAnnotation("PropertyAnnotation", 1); eb.HasTypeAnnotation("TypeAnnotation", 2); }); @@ -5973,9 +6055,16 @@ public virtual void Complex_properties_are_stored_in_snapshot() .HasColumnType("int") .HasColumnOrder(1); + SqlServerComplexTypePropertyBuilderExtensions.IsSparse(b1.Property("AlternateId")); + b1.Property("Id") .HasColumnType("int"); + b1.PrimitiveCollection("List") + .HasColumnType("nvarchar(max)"); + + SqlServerComplexTypePrimitiveCollectionBuilderExtensions.IsSparse(b1.PrimitiveCollection("List")); + b1.ComplexProperty>("EntityWithStringKey", "Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+EntityWithOneProperty.EntityWithTwoProperties#EntityWithTwoProperties.EntityWithStringKey#EntityWithStringKey", b2 => { b2.IsRequired(); @@ -5994,7 +6083,7 @@ public virtual void Complex_properties_are_stored_in_snapshot() b.ToTable("EntityWithOneProperty", "DefaultSchema"); }); """, usingCollections: true), - o => + (_, o) => { var entityWithOneProperty = o.FindEntityType(typeof(EntityWithOneProperty)); Assert.Equal(nameof(EntityWithOneProperty), entityWithOneProperty.GetTableName()); @@ -6026,7 +6115,8 @@ public virtual void Complex_properties_are_stored_in_snapshot() Assert.Equal(nameof(EntityWithOneProperty), nestedComplexType.GetTableName()); var nestedIdProperty = nestedComplexType.FindProperty(nameof(EntityWithStringKey.Id)); Assert.True(nestedIdProperty.IsNullable); - }); + }, + validate: true); #endregion @@ -7817,27 +7907,17 @@ static List getAllProperties(IModel model) .ToList(); var lineString1 = new LineString( - [new Coordinate(1.1, 2.2), new Coordinate(2.2, 2.2), new Coordinate(2.2, 1.1), new Coordinate(7.1, 7.2)]) - { - SRID = 4326 - }; + [new Coordinate(1.1, 2.2), new Coordinate(2.2, 2.2), new Coordinate(2.2, 1.1), new Coordinate(7.1, 7.2)]) { SRID = 4326 }; var lineString2 = new LineString( - [new Coordinate(7.1, 7.2), new Coordinate(20.2, 20.2), new Coordinate(20.20, 1.1), new Coordinate(70.1, 70.2)]) - { - SRID = 4326 - }; + [new Coordinate(7.1, 7.2), new Coordinate(20.2, 20.2), new Coordinate(20.20, 1.1), new Coordinate(70.1, 70.2)]) { SRID = 4326 }; var multiPoint = new MultiPoint( - [new Point(1.1, 2.2), new Point(2.2, 2.2), new Point(2.2, 1.1)]) - { SRID = 4326 }; + [new Point(1.1, 2.2), new Point(2.2, 2.2), new Point(2.2, 1.1)]) { SRID = 4326 }; var polygon1 = new Polygon( new LinearRing( - [new Coordinate(1.1, 2.2), new Coordinate(2.2, 2.2), new Coordinate(2.2, 1.1), new Coordinate(1.1, 2.2)])) - { - SRID = 4326 - }; + [new Coordinate(1.1, 2.2), new Coordinate(2.2, 2.2), new Coordinate(2.2, 1.1), new Coordinate(1.1, 2.2)])) { SRID = 4326 }; var polygon2 = new Polygon( new LinearRing( @@ -7853,10 +7933,7 @@ static List getAllProperties(IModel model) var multiPolygon = new MultiPolygon([polygon2, polygon1]) { SRID = 4326 }; var geometryCollection = new GeometryCollection( - [lineString1, lineString2, multiPoint, polygon1, polygon2, point1, multiLineString, multiPolygon]) - { - SRID = 4326 - }; + [lineString1, lineString2, multiPoint, polygon1, polygon2, point1, multiLineString, multiPolygon]) { SRID = 4326 }; Test( builder => @@ -7983,7 +8060,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - b.Property("BoolCollection") + b.PrimitiveCollection("BoolCollection") .HasColumnType("nvarchar(max)"); b.Property("Boolean") @@ -7995,7 +8072,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("Bytes") .HasColumnType("varbinary(max)"); - b.Property("BytesCollection") + b.PrimitiveCollection("BytesCollection") .HasColumnType("nvarchar(max)"); b.Property("Character") @@ -8005,7 +8082,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("DateTime") .HasColumnType("datetime2"); - b.Property("DateTimeCollection") + b.PrimitiveCollection("DateTimeCollection") .HasColumnType("nvarchar(max)"); b.Property("DateTimeOffset") @@ -8017,7 +8094,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("Double") .HasColumnType("float"); - b.Property("DoubleCollection") + b.PrimitiveCollection("DoubleCollection") .HasColumnType("nvarchar(max)"); b.Property("Enum16") @@ -8050,7 +8127,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("Int32") .HasColumnType("int"); - b.Property("Int32Collection") + b.PrimitiveCollection("Int32Collection") .HasColumnType("nvarchar(max)"); b.Property("Int64") @@ -8110,7 +8187,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("String") .HasColumnType("nvarchar(max)"); - b.Property("StringCollection") + b.PrimitiveCollection("StringCollection") .HasColumnType("nvarchar(max)"); b.Property("TimeSpan") @@ -8405,7 +8482,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) protected void Test(Action buildModel, string expectedCode, Action assert) => Test(buildModel, expectedCode, (m, _) => assert(m)); - protected void Test(Action buildModel, string expectedCode, Action assert) + protected void Test(Action buildModel, string expectedCode, Action assert, bool validate = false) { var modelBuilder = CreateConventionalModelBuilder(); modelBuilder.HasDefaultSchema("DefaultSchema"); @@ -8413,7 +8490,7 @@ protected void Test(Action buildModel, string expectedCode, Action modelBuilder.Model.RemoveAnnotation(CoreAnnotationNames.ProductVersion); buildModel(modelBuilder); - var model = modelBuilder.FinalizeModel(designTime: true, skipValidation: true); + var model = modelBuilder.FinalizeModel(designTime: true, skipValidation: !validate); Test(model, expectedCode, assert); } diff --git a/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.cs b/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.cs index 70997837f36..033af3a37ff 100644 --- a/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.cs +++ b/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.cs @@ -95,6 +95,7 @@ public void Test_new_annotations_handled_for_entity_types() RelationalAnnotationNames.JsonPropertyName, // Appears on entity type but requires specific model (i.e. owned types that can map to json, otherwise validation throws) RelationalAnnotationNames.ContainerColumnName, + RelationalAnnotationNames.ContainerColumnType, #pragma warning disable CS0618 RelationalAnnotationNames.ContainerColumnTypeMapping, #pragma warning restore CS0618 @@ -262,6 +263,7 @@ public void Test_new_annotations_handled_for_properties() RelationalAnnotationNames.ModelDependencies, RelationalAnnotationNames.FieldValueGetter, RelationalAnnotationNames.ContainerColumnName, + RelationalAnnotationNames.ContainerColumnType, #pragma warning disable CS0618 RelationalAnnotationNames.ContainerColumnTypeMapping, #pragma warning restore CS0618 @@ -367,8 +369,9 @@ private static void MissingAnnotationCheck( } var relationalAnnotations = typeof(RelationalAnnotationNames).GetFields() - .Where(f => f.FieldType == typeof(string) - && f.Name != "Prefix").ToList(); + .Where( + f => f.FieldType == typeof(string) + && f.Name != "Prefix").ToList(); foreach (var field in relationalAnnotations) { @@ -380,7 +383,11 @@ private static void MissingAnnotationCheck( { Assert.True( RelationalAnnotationNames.AllNames.Contains(annotationName), - nameof(RelationalAnnotationNames) + "." + nameof(RelationalAnnotationNames.AllNames) + " doesn't contain " + annotationName); + nameof(RelationalAnnotationNames) + + "." + + nameof(RelationalAnnotationNames.AllNames) + + " doesn't contain " + + annotationName); } } diff --git a/test/EFCore.Design.Tests/Migrations/Design/MigrationScaffolderTest.cs b/test/EFCore.Design.Tests/Migrations/Design/MigrationScaffolderTest.cs index 7cab26ed8f3..45f138e904b 100644 --- a/test/EFCore.Design.Tests/Migrations/Design/MigrationScaffolderTest.cs +++ b/test/EFCore.Design.Tests/Migrations/Design/MigrationScaffolderTest.cs @@ -91,20 +91,20 @@ var migrationAssembly services.GetRequiredService()), idGenerator, new MigrationsCodeGeneratorSelector( - [ - new CSharpMigrationsGenerator( - new MigrationsCodeGeneratorDependencies( - sqlServerTypeMappingSource, - sqlServerAnnotationCodeGenerator), - new CSharpMigrationsGeneratorDependencies( - code, - new CSharpMigrationOperationGenerator( - new CSharpMigrationOperationGeneratorDependencies( - code)), - new CSharpSnapshotGenerator( - new CSharpSnapshotGeneratorDependencies( - code, sqlServerTypeMappingSource, sqlServerAnnotationCodeGenerator)))) - ]), + [ + new CSharpMigrationsGenerator( + new MigrationsCodeGeneratorDependencies( + sqlServerTypeMappingSource, + sqlServerAnnotationCodeGenerator), + new CSharpMigrationsGeneratorDependencies( + code, + new CSharpMigrationOperationGenerator( + new CSharpMigrationOperationGeneratorDependencies( + code)), + new CSharpSnapshotGenerator( + new CSharpSnapshotGeneratorDependencies( + code, sqlServerTypeMappingSource, sqlServerAnnotationCodeGenerator)))) + ]), historyRepository, reporter, new MockProvider(), @@ -123,9 +123,10 @@ var migrationAssembly services.GetRequiredService>(), services.GetRequiredService(), services.GetRequiredService(), - services.GetServices(), services.GetRequiredService(), - services.GetRequiredService()))); + services.GetRequiredService(), + services.GetRequiredService(), + services.GetRequiredService()))); } // ReSharper disable once UnusedTypeParameter @@ -143,6 +144,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) private class MockHistoryRepository : IHistoryRepository { + public virtual LockReleaseBehavior LockReleaseBehavior => LockReleaseBehavior.Explicit; + public string GetBeginIfExistsScript(string migrationId) => null; @@ -182,10 +185,10 @@ public void Create() public Task CreateAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException(); - public IDisposable GetDatabaseLock(TimeSpan timeout) + public IMigrationsDatabaseLock AcquireDatabaseLock() => throw new NotImplementedException(); - public Task GetDatabaseLockAsync(TimeSpan timeout, CancellationToken cancellationToken = default) + public Task AcquireDatabaseLockAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException(); } diff --git a/test/EFCore.Design.Tests/Migrations/Design/SnapshotModelProcessorTest.cs b/test/EFCore.Design.Tests/Migrations/Design/SnapshotModelProcessorTest.cs index 5265acf89f0..6cbc70fc2d8 100644 --- a/test/EFCore.Design.Tests/Migrations/Design/SnapshotModelProcessorTest.cs +++ b/test/EFCore.Design.Tests/Migrations/Design/SnapshotModelProcessorTest.cs @@ -271,7 +271,7 @@ private static IModel PreprocessModel(ModelSnapshot snapshot) } } else if (property.GetValueGenerationStrategy() is SqlServerValueGenerationStrategy strategy - && strategy != SqlServerValueGenerationStrategy.None) + && strategy != SqlServerValueGenerationStrategy.None) { property.SetValueGenerationStrategy(strategy); } diff --git a/test/EFCore.Design.Tests/Query/CSharpToLinqTranslatorTest.cs b/test/EFCore.Design.Tests/Query/CSharpToLinqTranslatorTest.cs index 3fa2f2c2f6f..8a374a9bf2a 100644 --- a/test/EFCore.Design.Tests/Query/CSharpToLinqTranslatorTest.cs +++ b/test/EFCore.Design.Tests/Query/CSharpToLinqTranslatorTest.cs @@ -12,7 +12,6 @@ namespace Microsoft.EntityFrameworkCore.Query; // ReSharper disable InconsistentNaming // ReSharper disable RedundantCast - #nullable enable public class CSharpToLinqTranslatorTest @@ -104,7 +103,12 @@ public void ElementAccess_over_array() [Fact] public void ElementAccess_over_list() => AssertExpression( - () => new List { 1, 2, 3 }[1], + () => new List + { + 1, + 2, + 3 + }[1], "new List { 1, 2, 3 }[1]"); [Fact] @@ -128,7 +132,7 @@ public void Interpolated_string() [Fact] public void Interpolated_string_formattable() => AssertExpression( - () => FormattableStringMethod(FormattableStringFactory.Create("Foo: {0}, {1}", (object)8, (object) 9)), + () => FormattableStringMethod(FormattableStringFactory.Create("Foo: {0}, {1}", (object)8, (object)9)), """CSharpToLinqTranslatorTest.FormattableStringMethod($"Foo: {8}, {9}")"""); [Fact] @@ -260,7 +264,8 @@ public void Invocation_generic_method_on_generic_type() """CSharpToLinqTranslatorTest.SomeGenericType.SomeGenericFunction(1, "foo")"""); [Theory] - [InlineData(""" + [InlineData( + """ "hello" """, "hello")] [InlineData("1", 1)] diff --git a/test/EFCore.Design.Tests/Query/LinqToCSharpSyntaxTranslatorTest.cs b/test/EFCore.Design.Tests/Query/LinqToCSharpSyntaxTranslatorTest.cs index f40df69279a..33b3d83e5bd 100644 --- a/test/EFCore.Design.Tests/Query/LinqToCSharpSyntaxTranslatorTest.cs +++ b/test/EFCore.Design.Tests/Query/LinqToCSharpSyntaxTranslatorTest.cs @@ -56,7 +56,9 @@ public void Enum() [Fact] public void Enum_with_multiple_values() - => AssertExpression(Constant(SomeEnum.One | SomeEnum.Two), "LinqToCSharpSyntaxTranslatorTest.SomeEnum.One | LinqToCSharpSyntaxTranslatorTest.SomeEnum.Two"); + => AssertExpression( + Constant(SomeEnum.One | SomeEnum.Two), + "LinqToCSharpSyntaxTranslatorTest.SomeEnum.One | LinqToCSharpSyntaxTranslatorTest.SomeEnum.Two"); [Fact] public void Enum_with_unknown_value() @@ -145,9 +147,8 @@ public void Private_instance_field_AssignOperators_with_replacements(ExpressionT expressionType, Field(Parameter(typeof(Blog), "blog"), "_privateField"), Constant(3)), - $"""AccessPrivateField(blog) {op} Three""", new Dictionary() { { 3, "Three" } }, new Dictionary() { - { BlogPrivateField, new QualifiedName("AccessPrivateField", "") } - }); + $"""AccessPrivateField(blog) {op} Three""", new Dictionary { { 3, "Three" } }, + new Dictionary { { BlogPrivateField, new QualifiedName("AccessPrivateField", "") } }); [Theory] [InlineData(ExpressionType.Negate, "-(i)")] @@ -297,13 +298,14 @@ public void Internal_instance_field_read() Field( Parameter(typeof(Blog), "blog"), "InternalField"), - "UnsafeAccessor_Microsoft_EntityFrameworkCore_Query_Blog_InternalField_Get(blog)", unsafeAccessorsAsserter: unsafeAccessors => Assert.Equal( - """ + "UnsafeAccessor_Microsoft_EntityFrameworkCore_Query_Blog_InternalField_Get(blog)", unsafeAccessorsAsserter: unsafeAccessors + => Assert.Equal( + """ [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "InternalField")] private static extern int UnsafeAccessor_Microsoft_EntityFrameworkCore_Query_Blog_InternalField_Get(LinqToCSharpSyntaxTranslatorTest.Blog instance); """, - Assert.Single(unsafeAccessors), - ignoreLineEndingDifferences: true)); + Assert.Single(unsafeAccessors), + ignoreLineEndingDifferences: true)); [Fact] public void Not() @@ -435,7 +437,7 @@ public void Method_call_extension_with_null_this() Call( LinqExpressionToRoslynTranslatorExtensions.SomeExtensionMethod, Constant(null, typeof(LinqExpressionToRoslynTranslatorExtensionType))), - "LinqExpressionToRoslynTranslatorExtensions.SomeExtension(null)"); + "LinqExpressionToRoslynTranslatorExtensions.SomeExtension((LinqExpressionToRoslynTranslatorExtensionType)(null))"); [Fact] public void Method_call_generic() @@ -1142,7 +1144,8 @@ public void Same_parameter_instance_is_used_twice_in_nested_lambdas() [Fact] public void Block_with_non_standalone_expression_as_statement() - => AssertStatement(Block(Add(Constant(1), Constant(2))), + => AssertStatement( + Block(Add(Constant(1), Constant(2))), """ { _ = (1 + 2); @@ -1413,8 +1416,7 @@ public void Lift_block_in_lambda_body_expression() ReturnsIntWithParamMethod, Block( Call(FooMethod), - Call(BarMethod))), - []), + Call(BarMethod)))), """ int () => { @@ -1427,8 +1429,7 @@ public void Lift_block_in_lambda_body_expression() public void Do_not_lift_block_in_lambda_body() => AssertExpression( Lambda>( - Block(Block(Constant(8))), - []), + Block(Block(Constant(8)))), """ int () => { @@ -2073,7 +2074,8 @@ public static int Baz() public static int MethodWithSixParams(int a, int b, int c, int d, int e, int f) => a + b + c + d + e + f; - public static Expression> LambdaExpressionProperty => f => f > 5; + public static Expression> LambdaExpressionProperty + => f => f > 5; private static readonly FieldInfo BlogPrivateField = typeof(Blog).GetField("_privateField", BindingFlags.NonPublic | BindingFlags.Instance)!; @@ -2126,9 +2128,7 @@ private class BlogWithRequiredProperties public BlogWithRequiredProperties() { } public BlogWithRequiredProperties(string name) - { - Name = name; - } + => Name = name; [SetsRequiredMembers] public BlogWithRequiredProperties(string name, int rating) diff --git a/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpDbContextGeneratorTest.cs b/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpDbContextGeneratorTest.cs index fff78ef1e68..6a46be64eb1 100644 --- a/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpDbContextGeneratorTest.cs +++ b/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpDbContextGeneratorTest.cs @@ -11,7 +11,8 @@ namespace Microsoft.EntityFrameworkCore.Scaffolding.Internal { - public class CSharpDbContextGeneratorTest(ModelCodeGeneratorTestFixture fixture, ITestOutputHelper output) : ModelCodeGeneratorTestBase(fixture, output) + public class CSharpDbContextGeneratorTest(ModelCodeGeneratorTestFixture fixture, ITestOutputHelper output) + : ModelCodeGeneratorTestBase(fixture, output) { [ConditionalFact] public Task Empty_model() @@ -1360,7 +1361,8 @@ protected override IServiceCollection AddModelServices(IServiceCollection servic protected override IServiceCollection AddScaffoldingServices(IServiceCollection services) => services.Replace(ServiceDescriptor.Singleton()); - private class TestModelAnnotationProvider(RelationalAnnotationProviderDependencies dependencies) : SqlServerAnnotationProvider(dependencies) + private class TestModelAnnotationProvider(RelationalAnnotationProviderDependencies dependencies) + : SqlServerAnnotationProvider(dependencies) { public override IEnumerable For(IRelationalModel database, bool designTime) { @@ -1376,7 +1378,8 @@ public override IEnumerable For(IRelationalModel database, bool des } } - private class TestModelAnnotationCodeGenerator(AnnotationCodeGeneratorDependencies dependencies) : SqlServerAnnotationCodeGenerator(dependencies) + private class TestModelAnnotationCodeGenerator(AnnotationCodeGeneratorDependencies dependencies) + : SqlServerAnnotationCodeGenerator(dependencies) { private static readonly MethodInfo _testFluentApiCallMethodInfo = typeof(TestModelBuilderExtensions).GetRuntimeMethod( diff --git a/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpEntityTypeGeneratorTest.cs b/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpEntityTypeGeneratorTest.cs index f684700a894..740f3a35a4e 100644 --- a/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpEntityTypeGeneratorTest.cs +++ b/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpEntityTypeGeneratorTest.cs @@ -9,7 +9,8 @@ namespace Microsoft.EntityFrameworkCore.Scaffolding.Internal; -public class CSharpEntityTypeGeneratorTest(ModelCodeGeneratorTestFixture fixture, ITestOutputHelper output) : ModelCodeGeneratorTestBase(fixture, output) +public class CSharpEntityTypeGeneratorTest(ModelCodeGeneratorTestFixture fixture, ITestOutputHelper output) + : ModelCodeGeneratorTestBase(fixture, output) { [ConditionalFact] public Task KeylessAttribute_is_generated_for_key_less_entity() @@ -2934,7 +2935,8 @@ protected override IServiceCollection AddModelServices(IServiceCollection servic protected override IServiceCollection AddScaffoldingServices(IServiceCollection services) => services.Replace(ServiceDescriptor.Singleton()); - private class TestModelAnnotationProvider(RelationalAnnotationProviderDependencies dependencies) : SqlServerAnnotationProvider(dependencies) + private class TestModelAnnotationProvider(RelationalAnnotationProviderDependencies dependencies) + : SqlServerAnnotationProvider(dependencies) { public override IEnumerable For(ITable table, bool designTime) { @@ -2968,7 +2970,8 @@ public override IEnumerable For(IColumn column, bool designTime) } } - private class TestModelAnnotationCodeGenerator(AnnotationCodeGeneratorDependencies dependencies) : SqlServerAnnotationCodeGenerator(dependencies) + private class TestModelAnnotationCodeGenerator(AnnotationCodeGeneratorDependencies dependencies) + : SqlServerAnnotationCodeGenerator(dependencies) { protected override AttributeCodeFragment GenerateDataAnnotation(IEntityType entityType, IAnnotation annotation) => annotation.Name switch diff --git a/test/EFCore.Design.Tests/Scaffolding/Internal/RelationalScaffoldingModelFactoryTest.cs b/test/EFCore.Design.Tests/Scaffolding/Internal/RelationalScaffoldingModelFactoryTest.cs index 77eee706a71..66d5a78c003 100644 --- a/test/EFCore.Design.Tests/Scaffolding/Internal/RelationalScaffoldingModelFactoryTest.cs +++ b/test/EFCore.Design.Tests/Scaffolding/Internal/RelationalScaffoldingModelFactoryTest.cs @@ -3200,12 +3200,27 @@ public void Navigation_name_from_composite_FK() // Issue #32685 { Table = someTable, Name = "FK_SomeTable_DetailItem", - Columns = { someTable.Columns.Single(c => c.Name == "DetailItemName"), someTable.Columns.Single(c => c.Name == "DetailItemCategoryName") }, + Columns = + { + someTable.Columns.Single(c => c.Name == "DetailItemName"), + someTable.Columns.Single(c => c.Name == "DetailItemCategoryName") + }, PrincipalTable = itemTable, - PrincipalColumns = { itemTable.Columns.Single(c => c.Name == "Name"), itemTable.Columns.Single(c => c.Name == "CategoryName") }, + PrincipalColumns = + { + itemTable.Columns.Single(c => c.Name == "Name"), itemTable.Columns.Single(c => c.Name == "CategoryName") + }, }); - var info = new DatabaseModel { Tables = { itemTable, someTable, itemCategoryTable } }; + var info = new DatabaseModel + { + Tables = + { + itemTable, + someTable, + itemCategoryTable + } + }; var model = _factory.Create(info, new ModelReverseEngineerOptions()); diff --git a/test/EFCore.Design.Tests/Scaffolding/Internal/ScaffoldingTypeMapperSqlServerTest.cs b/test/EFCore.Design.Tests/Scaffolding/Internal/ScaffoldingTypeMapperSqlServerTest.cs index d8f2fdce4b4..235799e1f4d 100644 --- a/test/EFCore.Design.Tests/Scaffolding/Internal/ScaffoldingTypeMapperSqlServerTest.cs +++ b/test/EFCore.Design.Tests/Scaffolding/Internal/ScaffoldingTypeMapperSqlServerTest.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.EntityFrameworkCore.Scaffolding.Internal; using Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal; // ReSharper disable CheckNamespace diff --git a/test/EFCore.Design.Tests/TestUtilities/DatabaseColumnRef.cs b/test/EFCore.Design.Tests/TestUtilities/DatabaseColumnRef.cs index 7b049a52fa8..a04c85a1d67 100644 --- a/test/EFCore.Design.Tests/TestUtilities/DatabaseColumnRef.cs +++ b/test/EFCore.Design.Tests/TestUtilities/DatabaseColumnRef.cs @@ -8,9 +8,7 @@ namespace Microsoft.EntityFrameworkCore.TestUtilities; internal class DatabaseColumnRef : DatabaseColumn { public DatabaseColumnRef(string name) - { - Name = name; - } + => Name = name; public override DatabaseTable Table { diff --git a/test/EFCore.Design.Tests/TestUtilities/FakeScaffoldingModelFactory.cs b/test/EFCore.Design.Tests/TestUtilities/FakeScaffoldingModelFactory.cs index c6b252a3525..c25e9f00a0f 100644 --- a/test/EFCore.Design.Tests/TestUtilities/FakeScaffoldingModelFactory.cs +++ b/test/EFCore.Design.Tests/TestUtilities/FakeScaffoldingModelFactory.cs @@ -14,8 +14,8 @@ public class FakeScaffoldingModelFactory( ICSharpUtilities cSharpUtilities, IScaffoldingTypeMapper scaffoldingTypeMapper, IModelRuntimeInitializer modelRuntimeInitializer) : RelationalScaffoldingModelFactory( - reporter, candidateNamingService, pluralizer, cSharpUtilities, scaffoldingTypeMapper, - modelRuntimeInitializer) + reporter, candidateNamingService, pluralizer, cSharpUtilities, scaffoldingTypeMapper, + modelRuntimeInitializer) { public override IModel Create(DatabaseModel databaseModel, ModelReverseEngineerOptions options) { diff --git a/test/EFCore.Design.Tests/TestUtilities/TestDbContextOperations.cs b/test/EFCore.Design.Tests/TestUtilities/TestDbContextOperations.cs index 6c089e0e627..ac5ef9c2971 100644 --- a/test/EFCore.Design.Tests/TestUtilities/TestDbContextOperations.cs +++ b/test/EFCore.Design.Tests/TestUtilities/TestDbContextOperations.cs @@ -15,4 +15,5 @@ public class TestDbContextOperations( string language, bool nullable, string[] args, - AppServiceProviderFactory appServicesFactory) : DbContextOperations(reporter, assembly, startupAssembly, project, projectDir, rootNamespace, language, nullable, args, appServicesFactory); + AppServiceProviderFactory appServicesFactory) : DbContextOperations( + reporter, assembly, startupAssembly, project, projectDir, rootNamespace, language, nullable, args, appServicesFactory); diff --git a/test/EFCore.FSharp.FunctionalTests/EFCore.FSharp.FunctionalTests.fsproj b/test/EFCore.FSharp.FunctionalTests/EFCore.FSharp.FunctionalTests.fsproj new file mode 100644 index 00000000000..edc4e73d6a3 --- /dev/null +++ b/test/EFCore.FSharp.FunctionalTests/EFCore.FSharp.FunctionalTests.fsproj @@ -0,0 +1,21 @@ + + + + Microsoft.EntityFrameworkCore + $(DefaultNetCoreTargetFramework) + Microsoft.EntityFrameworkCore.FSharp.FunctionalTests + True + latest + + + + + + + + + + + + + diff --git a/test/EFCore.FSharp.FunctionalTests/NorthwindFSharpQuerySqlServerFixture.fs b/test/EFCore.FSharp.FunctionalTests/NorthwindFSharpQuerySqlServerFixture.fs new file mode 100644 index 00000000000..43cb9ccb5e3 --- /dev/null +++ b/test/EFCore.FSharp.FunctionalTests/NorthwindFSharpQuerySqlServerFixture.fs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.FSharp.FunctionalTests + +open Microsoft.EntityFrameworkCore.Infrastructure +open Microsoft.EntityFrameworkCore.Query + +type NorthwindFSharpQuerySqlServerFixture<'TModelCustomizer + when 'TModelCustomizer : (new: unit -> 'TModelCustomizer) + and 'TModelCustomizer :> ITestModelCustomizer>() = + inherit NorthwindQuerySqlServerFixture<'TModelCustomizer>() + + override self.StoreName = "NorthwindFSharp" diff --git a/test/EFCore.FSharp.FunctionalTests/NorthwindQueryFSharpTest.fs b/test/EFCore.FSharp.FunctionalTests/NorthwindQueryFSharpTest.fs new file mode 100644 index 00000000000..323ad23369b --- /dev/null +++ b/test/EFCore.FSharp.FunctionalTests/NorthwindQueryFSharpTest.fs @@ -0,0 +1,38 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.FSharp.FunctionalTests + +open System.Linq +open Microsoft.EntityFrameworkCore.Query +open Microsoft.EntityFrameworkCore.TestModels.Northwind +open Microsoft.EntityFrameworkCore.TestUtilities +open global.Xunit + +type NorthwindQueryFSharpTest(fixture) as self = + inherit QueryTestBase>(fixture) + + do fixture.TestSqlLoggerFactory.Clear() + + let assertSql (sql: string) = + fixture.TestSqlLoggerFactory.AssertBaseline([|sql|]) + + [] + [] + let ListLiteral_Contains (isAsync: bool) = + task { + do! self.AssertQuery(isAsync, (fun ss -> ss.Set().Where(fun c -> ["ALFKI"; "ALFKI2"].Contains(c.CustomerID)))) + assertSql( + "SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] +FROM [Customers] AS [c] +WHERE [c].[CustomerID] IN (N'ALFKI', N'ALFKI2')") + } + + member private self.RewriteExpectedQueryExpressionRedirect expression = base.RewriteExpectedQueryExpression expression + member private self.RewriteServerQueryExpressionRedirect expression = base.RewriteServerQueryExpression expression + + override self.CreateQueryAsserter fixture = + new RelationalQueryAsserter( + fixture, + (fun e -> self.RewriteExpectedQueryExpressionRedirect(e)), + (fun e -> self.RewriteServerQueryExpressionRedirect(e))) diff --git a/test/EFCore.InMemory.FunctionalTests/CompositeKeyEndToEndTest.cs b/test/EFCore.InMemory.FunctionalTests/CompositeKeyEndToEndTest.cs index 47ab8f7b69b..39467eedecd 100644 --- a/test/EFCore.InMemory.FunctionalTests/CompositeKeyEndToEndTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/CompositeKeyEndToEndTest.cs @@ -175,8 +175,10 @@ private class BronieContext(IServiceProvider serviceProvider) : PoolableDbContex // ReSharper disable once UnusedAutoPropertyAccessor.Local public DbSet Pegasuses { get; set; } + // ReSharper disable once UnusedAutoPropertyAccessor.Local public DbSet Unicorns { get; set; } + // ReSharper disable once UnusedAutoPropertyAccessor.Local public DbSet EarthPonies { get; set; } diff --git a/test/EFCore.InMemory.FunctionalTests/ConcurrencyDetectorDisabledInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/ConcurrencyDetectorDisabledInMemoryTest.cs index e67d53173f1..11960e294a7 100644 --- a/test/EFCore.InMemory.FunctionalTests/ConcurrencyDetectorDisabledInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/ConcurrencyDetectorDisabledInMemoryTest.cs @@ -3,8 +3,9 @@ namespace Microsoft.EntityFrameworkCore; -public class ConcurrencyDetectorDisabledInMemoryTest(ConcurrencyDetectorDisabledInMemoryTest.ConcurrencyDetectorInMemoryFixture fixture) : ConcurrencyDetectorDisabledTestBase< - ConcurrencyDetectorDisabledInMemoryTest.ConcurrencyDetectorInMemoryFixture>(fixture) +public class ConcurrencyDetectorDisabledInMemoryTest(ConcurrencyDetectorDisabledInMemoryTest.ConcurrencyDetectorInMemoryFixture fixture) + : ConcurrencyDetectorDisabledTestBase< + ConcurrencyDetectorDisabledInMemoryTest.ConcurrencyDetectorInMemoryFixture>(fixture) { public class ConcurrencyDetectorInMemoryFixture : ConcurrencyDetectorFixtureBase { diff --git a/test/EFCore.InMemory.FunctionalTests/ConcurrencyDetectorEnabledInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/ConcurrencyDetectorEnabledInMemoryTest.cs index 31f9913b31c..cfdc7faa051 100644 --- a/test/EFCore.InMemory.FunctionalTests/ConcurrencyDetectorEnabledInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/ConcurrencyDetectorEnabledInMemoryTest.cs @@ -3,8 +3,9 @@ namespace Microsoft.EntityFrameworkCore; -public class ConcurrencyDetectorEnabledInMemoryTest(ConcurrencyDetectorEnabledInMemoryTest.ConcurrencyDetectorInMemoryFixture fixture) : ConcurrencyDetectorEnabledTestBase< - ConcurrencyDetectorEnabledInMemoryTest.ConcurrencyDetectorInMemoryFixture>(fixture) +public class ConcurrencyDetectorEnabledInMemoryTest(ConcurrencyDetectorEnabledInMemoryTest.ConcurrencyDetectorInMemoryFixture fixture) + : ConcurrencyDetectorEnabledTestBase< + ConcurrencyDetectorEnabledInMemoryTest.ConcurrencyDetectorInMemoryFixture>(fixture) { public class ConcurrencyDetectorInMemoryFixture : ConcurrencyDetectorFixtureBase { diff --git a/test/EFCore.InMemory.FunctionalTests/ConfigPatternsInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/ConfigPatternsInMemoryTest.cs index b5281c52a1a..00ee85ff887 100644 --- a/test/EFCore.InMemory.FunctionalTests/ConfigPatternsInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/ConfigPatternsInMemoryTest.cs @@ -145,7 +145,6 @@ public void Can_save_and_query_with_explicit_services_and_explicit_config() private class ExplicitServicesAndConfigBlogContext(DbContextOptions options) : DbContext(options) { - // ReSharper disable once UnusedAutoPropertyAccessor.Local public DbSet Blogs { get; set; } } @@ -304,9 +303,7 @@ private class InjectContextAndConfigurationBlogContext : DbContext { public InjectContextAndConfigurationBlogContext(DbContextOptions options) : base(options) - { - Assert.NotNull(options); - } + => Assert.NotNull(options); // ReSharper disable once UnusedAutoPropertyAccessor.Local public DbSet Blogs { get; set; } @@ -362,9 +359,7 @@ private class InjectConfigurationBlogContext : DbContext { public InjectConfigurationBlogContext(DbContextOptions options) : base(options) - { - Assert.NotNull(options); - } + => Assert.NotNull(options); // ReSharper disable once UnusedAutoPropertyAccessor.Local public DbSet Blogs { get; set; } @@ -451,9 +446,7 @@ private class InjectDifferentConfigurationsBlogContext : DbContext { public InjectDifferentConfigurationsBlogContext(DbContextOptions options) : base(options) - { - Assert.NotNull(options); - } + => Assert.NotNull(options); // ReSharper disable once UnusedAutoPropertyAccessor.Local public DbSet Blogs { get; set; } @@ -463,9 +456,7 @@ private class InjectDifferentConfigurationsAccountContext : DbContext { public InjectDifferentConfigurationsAccountContext(DbContextOptions options) : base(options) - { - Assert.NotNull(options); - } + => Assert.NotNull(options); // ReSharper disable once UnusedAutoPropertyAccessor.Local public DbSet Accounts { get; set; } diff --git a/test/EFCore.InMemory.FunctionalTests/FieldsOnlyLoadInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/FieldsOnlyLoadInMemoryTest.cs index a1454f47b83..77ba4d97a1c 100644 --- a/test/EFCore.InMemory.FunctionalTests/FieldsOnlyLoadInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/FieldsOnlyLoadInMemoryTest.cs @@ -3,7 +3,8 @@ namespace Microsoft.EntityFrameworkCore; -public class FieldsOnlyLoadInMemoryTest(FieldsOnlyLoadInMemoryTest.FieldsOnlyLoadInMemoryFixture fixture) : FieldsOnlyLoadTestBase(fixture) +public class FieldsOnlyLoadInMemoryTest(FieldsOnlyLoadInMemoryTest.FieldsOnlyLoadInMemoryFixture fixture) + : FieldsOnlyLoadTestBase(fixture) { public class FieldsOnlyLoadInMemoryFixture : FieldsOnlyLoadFixtureBase { diff --git a/test/EFCore.InMemory.FunctionalTests/InMemoryApiConsistencyTest.cs b/test/EFCore.InMemory.FunctionalTests/InMemoryApiConsistencyTest.cs index 86cca60516d..8eecd9ed50a 100644 --- a/test/EFCore.InMemory.FunctionalTests/InMemoryApiConsistencyTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/InMemoryApiConsistencyTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore; -public class InMemoryApiConsistencyTest(InMemoryApiConsistencyTest.InMemoryApiConsistencyFixture fixture) : ApiConsistencyTestBase(fixture) +public class InMemoryApiConsistencyTest(InMemoryApiConsistencyTest.InMemoryApiConsistencyFixture fixture) + : ApiConsistencyTestBase(fixture) { protected override void AddServices(ServiceCollection serviceCollection) => serviceCollection.AddEntityFrameworkInMemoryDatabase(); diff --git a/test/EFCore.InMemory.FunctionalTests/IntegerValueGeneratorTest.cs b/test/EFCore.InMemory.FunctionalTests/IntegerValueGeneratorTest.cs index 49a507f51ee..1244fa01e58 100644 --- a/test/EFCore.InMemory.FunctionalTests/IntegerValueGeneratorTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/IntegerValueGeneratorTest.cs @@ -384,6 +384,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) // ReSharper disable once UnusedAutoPropertyAccessor.Local public DbSet CookedBreads { get; set; } public DbSet Olives { get; set; } + // ReSharper disable once UnusedAutoPropertyAccessor.Local public DbSet Macs { get; set; } public DbSet Smokeys { get; set; } diff --git a/test/EFCore.InMemory.FunctionalTests/LazyLoadProxyInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/LazyLoadProxyInMemoryTest.cs index 791c03b2b29..5e46f4e83fe 100644 --- a/test/EFCore.InMemory.FunctionalTests/LazyLoadProxyInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/LazyLoadProxyInMemoryTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore; -public class LazyLoadProxyInMemoryTest(LazyLoadProxyInMemoryTest.LoadInMemoryFixture fixture) : LazyLoadProxyTestBase(fixture) +public class LazyLoadProxyInMemoryTest(LazyLoadProxyInMemoryTest.LoadInMemoryFixture fixture) + : LazyLoadProxyTestBase(fixture) { protected override string SerializedBlogs2 => """ diff --git a/test/EFCore.InMemory.FunctionalTests/ManyToManyFieldsLoadInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/ManyToManyFieldsLoadInMemoryTest.cs index 7b64655543e..7aea5113c59 100644 --- a/test/EFCore.InMemory.FunctionalTests/ManyToManyFieldsLoadInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/ManyToManyFieldsLoadInMemoryTest.cs @@ -3,8 +3,9 @@ namespace Microsoft.EntityFrameworkCore; -public class ManyToManyFieldsLoadInMemoryTest(ManyToManyFieldsLoadInMemoryTest.ManyToManyFieldsLoadInMemoryFixture fixture) : ManyToManyFieldsLoadTestBase< - ManyToManyFieldsLoadInMemoryTest.ManyToManyFieldsLoadInMemoryFixture>(fixture) +public class ManyToManyFieldsLoadInMemoryTest(ManyToManyFieldsLoadInMemoryTest.ManyToManyFieldsLoadInMemoryFixture fixture) + : ManyToManyFieldsLoadTestBase< + ManyToManyFieldsLoadInMemoryTest.ManyToManyFieldsLoadInMemoryFixture>(fixture) { public class ManyToManyFieldsLoadInMemoryFixture : ManyToManyFieldsLoadFixtureBase { diff --git a/test/EFCore.InMemory.FunctionalTests/ManyToManyLoadInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/ManyToManyLoadInMemoryTest.cs index 4d7acaa69a0..a55e41d1106 100644 --- a/test/EFCore.InMemory.FunctionalTests/ManyToManyLoadInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/ManyToManyLoadInMemoryTest.cs @@ -3,7 +3,8 @@ namespace Microsoft.EntityFrameworkCore; -public class ManyToManyLoadInMemoryTest(ManyToManyLoadInMemoryTest.ManyToManyLoadInMemoryFixture fixture) : ManyToManyLoadTestBase(fixture) +public class ManyToManyLoadInMemoryTest(ManyToManyLoadInMemoryTest.ManyToManyLoadInMemoryFixture fixture) + : ManyToManyLoadTestBase(fixture) { public class ManyToManyLoadInMemoryFixture : ManyToManyLoadFixtureBase { diff --git a/test/EFCore.InMemory.FunctionalTests/ModelBuilding/InMemoryModelBuilderAssemblyScanTest.cs b/test/EFCore.InMemory.FunctionalTests/ModelBuilding/InMemoryModelBuilderAssemblyScanTest.cs index 275389c4642..f3809d7f4cb 100644 --- a/test/EFCore.InMemory.FunctionalTests/ModelBuilding/InMemoryModelBuilderAssemblyScanTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/ModelBuilding/InMemoryModelBuilderAssemblyScanTest.cs @@ -44,7 +44,7 @@ public void Scan_reports_load_errors() }; var assembly = MockAssembly.Create( - types, null, new ReflectionTypeLoadException([types[1], types[2]], [new(), new()])); + types, null, new ReflectionTypeLoadException([types[1], types[2]], [new Exception(), new Exception()])); var loggerFactory = new ListLoggerFactory(); var logger = CreateModelLogger(loggerFactory); diff --git a/test/EFCore.InMemory.FunctionalTests/ModelBuilding/InMemoryModelBuilderGenericRelationshipStringTest.cs b/test/EFCore.InMemory.FunctionalTests/ModelBuilding/InMemoryModelBuilderGenericRelationshipStringTest.cs index 18dd24f8331..e80a12256de 100644 --- a/test/EFCore.InMemory.FunctionalTests/ModelBuilding/InMemoryModelBuilderGenericRelationshipStringTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/ModelBuilding/InMemoryModelBuilderGenericRelationshipStringTest.cs @@ -37,7 +37,8 @@ protected override TestModelBuilder CreateModelBuilder(Action new GenericStringTestModelBuilder(Fixture, configure); } - public class GenericStringTestModelBuilder(ModelBuilderFixtureBase fixture, Action? configure) : TestModelBuilder(fixture, configure) + public class GenericStringTestModelBuilder(ModelBuilderFixtureBase fixture, Action? configure) + : TestModelBuilder(fixture, configure) { public override TestEntityTypeBuilder Entity() => new GenericStringTestEntityTypeBuilder(ModelBuilder.Entity()); @@ -75,7 +76,8 @@ public override string GetDisplayName(Type entityType) => entityType.FullName!; } - protected class GenericStringTestEntityTypeBuilder(EntityTypeBuilder entityTypeBuilder) : GenericTestEntityTypeBuilder(entityTypeBuilder) + protected class GenericStringTestEntityTypeBuilder(EntityTypeBuilder entityTypeBuilder) + : GenericTestEntityTypeBuilder(entityTypeBuilder) where TEntity : class { protected override TestEntityTypeBuilder Wrap(EntityTypeBuilder entityTypeBuilder) @@ -187,7 +189,8 @@ public override TestReferenceCollectionBuilder HasPrinc keyExpression.GetMemberAccessList().Select(p => p.GetSimpleMemberName()).ToArray())); } - protected class GenericStringTestReferenceReferenceBuilder(ReferenceReferenceBuilder referenceReferenceBuilder) + protected class GenericStringTestReferenceReferenceBuilder( + ReferenceReferenceBuilder referenceReferenceBuilder) : GenericTestReferenceReferenceBuilder(referenceReferenceBuilder) where TEntity : class where TRelatedEntity : class @@ -229,7 +232,8 @@ protected class GenericStringTestCollectionCollectionBuilder(OwnedNavigationBuilder ownedNavigationBuilder) + protected class GenericStringTestOwnedNavigationBuilder( + OwnedNavigationBuilder ownedNavigationBuilder) : GenericTestOwnedNavigationBuilder(ownedNavigationBuilder) where TEntity : class where TDependentEntity : class diff --git a/test/EFCore.InMemory.FunctionalTests/ModelBuilding/InMemoryModelBuilderGenericRelationshipTypeTest.cs b/test/EFCore.InMemory.FunctionalTests/ModelBuilding/InMemoryModelBuilderGenericRelationshipTypeTest.cs index fda3367c22e..e42b82f6c3b 100644 --- a/test/EFCore.InMemory.FunctionalTests/ModelBuilding/InMemoryModelBuilderGenericRelationshipTypeTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/ModelBuilding/InMemoryModelBuilderGenericRelationshipTypeTest.cs @@ -19,7 +19,8 @@ protected override TestModelBuilder CreateModelBuilder(Action new GenericTypeTestModelBuilder(Fixture, configure); } - public class GenericTypeTestModelBuilder(ModelBuilderFixtureBase fixture, Action? configure) : TestModelBuilder(fixture, configure) + public class GenericTypeTestModelBuilder(ModelBuilderFixtureBase fixture, Action? configure) + : TestModelBuilder(fixture, configure) { public override TestEntityTypeBuilder Entity() => new GenericTypeTestEntityTypeBuilder(ModelBuilder.Entity()); @@ -54,7 +55,8 @@ public override TestModelBuilder Ignore() } } - protected class GenericTypeTestEntityTypeBuilder(EntityTypeBuilder entityTypeBuilder) : GenericTestEntityTypeBuilder(entityTypeBuilder) + protected class GenericTypeTestEntityTypeBuilder(EntityTypeBuilder entityTypeBuilder) + : GenericTestEntityTypeBuilder(entityTypeBuilder) where TEntity : class { protected override TestEntityTypeBuilder Wrap(EntityTypeBuilder entityTypeBuilder) @@ -89,7 +91,8 @@ public override TestCollectionNavigationBuilder HasMany => new GenericTypeTestCollectionNavigationBuilder(EntityTypeBuilder.HasMany(navigationExpression)); } - protected class GenericTypeTestPropertyBuilder(PropertyBuilder propertyBuilder) : GenericTestPropertyBuilder(propertyBuilder) + protected class GenericTypeTestPropertyBuilder(PropertyBuilder propertyBuilder) + : GenericTestPropertyBuilder(propertyBuilder) { protected override TestPropertyBuilder Wrap(PropertyBuilder propertyBuilder) => new GenericTypeTestPropertyBuilder(propertyBuilder); @@ -112,7 +115,8 @@ public override TestPropertyBuilder HasConversion Wrap(PropertyBuilder.HasConversion(typeof(TConverter), typeof(TComparer), typeof(TProviderComparer))); } - protected class GenericTypeTestReferenceNavigationBuilder(ReferenceNavigationBuilder referenceNavigationBuilder) : GenericTestReferenceNavigationBuilder( + ReferenceNavigationBuilder referenceNavigationBuilder) : GenericTestReferenceNavigationBuilder(referenceNavigationBuilder) where TEntity : class where TRelatedEntity : class @@ -135,7 +139,8 @@ public override TestCollectionCollectionBuilder WithMan CollectionNavigationBuilder.WithMany(navigationExpression)); } - protected class GenericTypeTestReferenceReferenceBuilder(ReferenceReferenceBuilder referenceReferenceBuilder) + protected class GenericTypeTestReferenceReferenceBuilder( + ReferenceReferenceBuilder referenceReferenceBuilder) : GenericTestReferenceReferenceBuilder(referenceReferenceBuilder) where TEntity : class where TRelatedEntity : class @@ -278,7 +283,8 @@ public override TestEntityTypeBuilder UsingEntity( new GenericTypeTestEntityTypeBuilder(new EntityTypeBuilder(e.Metadata))))); } - protected class GenericTypeTestOwnedNavigationBuilder(OwnedNavigationBuilder ownedNavigationBuilder) + protected class GenericTypeTestOwnedNavigationBuilder( + OwnedNavigationBuilder ownedNavigationBuilder) : GenericTestOwnedNavigationBuilder(ownedNavigationBuilder) where TEntity : class where TRelatedEntity : class diff --git a/test/EFCore.InMemory.FunctionalTests/ModelBuilding/InMemoryModelBuilderGenericTest.cs b/test/EFCore.InMemory.FunctionalTests/ModelBuilding/InMemoryModelBuilderGenericTest.cs index 9b4b0c97154..0f91ab44316 100644 --- a/test/EFCore.InMemory.FunctionalTests/ModelBuilding/InMemoryModelBuilderGenericTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/ModelBuilding/InMemoryModelBuilderGenericTest.cs @@ -1,12 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.ComponentModel.DataAnnotations.Schema; +#nullable enable + using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; using Microsoft.EntityFrameworkCore.Metadata.Internal; -#nullable enable - // ReSharper disable InconsistentNaming namespace Microsoft.EntityFrameworkCore.ModelBuilding; diff --git a/test/EFCore.InMemory.FunctionalTests/ModelBuilding/InMemoryModelBuilderNonGenericStringTest.cs b/test/EFCore.InMemory.FunctionalTests/ModelBuilding/InMemoryModelBuilderNonGenericStringTest.cs index 691ddf4645c..c8c4bb58bec 100644 --- a/test/EFCore.InMemory.FunctionalTests/ModelBuilding/InMemoryModelBuilderNonGenericStringTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/ModelBuilding/InMemoryModelBuilderNonGenericStringTest.cs @@ -33,7 +33,7 @@ protected override TestModelBuilder CreateModelBuilder(Action Assert.Throws( - base.WithMany_pointing_to_keyless_entity_throws); + base.WithMany_pointing_to_keyless_entity_throws); } public class NonGenericStringManyToOneType(InMemoryModelBuilderFixture fixture) : InMemoryManyToOne(fixture) @@ -48,7 +48,8 @@ protected override TestModelBuilder CreateModelBuilder(Action new NonGenericStringTestModelBuilder(Fixture, configure); } - private class NonGenericStringTestModelBuilder(ModelBuilderFixtureBase fixture, Action? configure) : TestModelBuilder(fixture, configure) + private class NonGenericStringTestModelBuilder(ModelBuilderFixtureBase fixture, Action? configure) + : TestModelBuilder(fixture, configure) { public override TestEntityTypeBuilder Entity() => new NonGenericStringTestEntityTypeBuilder(ModelBuilder.Entity(typeof(TEntity))); @@ -86,7 +87,8 @@ public override string GetDisplayName(Type entityType) => entityType.FullName!; } - private class NonGenericStringTestEntityTypeBuilder(EntityTypeBuilder entityTypeBuilder) : NonGenericTestEntityTypeBuilder(entityTypeBuilder) + private class NonGenericStringTestEntityTypeBuilder(EntityTypeBuilder entityTypeBuilder) + : NonGenericTestEntityTypeBuilder(entityTypeBuilder) where TEntity : class { protected override NonGenericTestEntityTypeBuilder Wrap(EntityTypeBuilder entityTypeBuilder) @@ -144,7 +146,8 @@ public override TestCollectionNavigationBuilder HasMany navigationExpression?.GetMemberAccess().GetSimpleMemberName())); } - private class NonGenericStringTestReferenceNavigationBuilder(ReferenceNavigationBuilder referenceNavigationBuilder) + private class NonGenericStringTestReferenceNavigationBuilder( + ReferenceNavigationBuilder referenceNavigationBuilder) : NonGenericTestReferenceNavigationBuilder(referenceNavigationBuilder) where TEntity : class where TRelatedEntity : class @@ -156,7 +159,8 @@ public override TestReferenceReferenceBuilder WithOne( navigationExpression?.GetMemberAccess().GetSimpleMemberName())); } - private class NonGenericStringTestReferenceReferenceBuilder(ReferenceReferenceBuilder referenceReferenceBuilder) + private class NonGenericStringTestReferenceReferenceBuilder( + ReferenceReferenceBuilder referenceReferenceBuilder) : NonGenericTestReferenceReferenceBuilder(referenceReferenceBuilder) where TEntity : class where TRelatedEntity : class diff --git a/test/EFCore.InMemory.FunctionalTests/ModelBuilding/InMemoryModelBuilderNonGenericUnqualifiedStringTest.cs b/test/EFCore.InMemory.FunctionalTests/ModelBuilding/InMemoryModelBuilderNonGenericUnqualifiedStringTest.cs index dac0a0a56d9..0f5fd8e1237 100644 --- a/test/EFCore.InMemory.FunctionalTests/ModelBuilding/InMemoryModelBuilderNonGenericUnqualifiedStringTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/ModelBuilding/InMemoryModelBuilderNonGenericUnqualifiedStringTest.cs @@ -13,7 +13,8 @@ protected override TestModelBuilder CreateModelBuilder(Action new NonGenericStringTestModelBuilder(Fixture, configure); } - private class NonGenericStringTestModelBuilder(ModelBuilderFixtureBase fixture, Action? configure) : TestModelBuilder(fixture, configure) + private class NonGenericStringTestModelBuilder(ModelBuilderFixtureBase fixture, Action? configure) + : TestModelBuilder(fixture, configure) { public override TestEntityTypeBuilder Entity() => new NonGenericStringTestEntityTypeBuilder(ModelBuilder.Entity(typeof(TEntity))); @@ -48,7 +49,8 @@ public override TestModelBuilder Ignore() } } - private class NonGenericStringTestEntityTypeBuilder(EntityTypeBuilder entityTypeBuilder) : NonGenericTestEntityTypeBuilder(entityTypeBuilder) + private class NonGenericStringTestEntityTypeBuilder(EntityTypeBuilder entityTypeBuilder) + : NonGenericTestEntityTypeBuilder(entityTypeBuilder) where TEntity : class { protected override NonGenericTestEntityTypeBuilder Wrap(EntityTypeBuilder entityTypeBuilder) @@ -112,7 +114,8 @@ public override TestCollectionNavigationBuilder HasMany } } - private class NonGenericStringTestReferenceNavigationBuilder(ReferenceNavigationBuilder referenceNavigationBuilder) : NonGenericTestReferenceNavigationBuilder< + private class NonGenericStringTestReferenceNavigationBuilder( + ReferenceNavigationBuilder referenceNavigationBuilder) : NonGenericTestReferenceNavigationBuilder< TEntity, TRelatedEntity>(referenceNavigationBuilder) where TEntity : class where TRelatedEntity : class @@ -124,7 +127,8 @@ public override TestReferenceReferenceBuilder WithOne( navigationExpression?.GetMemberAccess().GetSimpleMemberName())); } - private class NonGenericStringTestReferenceReferenceBuilder(ReferenceReferenceBuilder referenceReferenceBuilder) : NonGenericTestReferenceReferenceBuilder< + private class NonGenericStringTestReferenceReferenceBuilder( + ReferenceReferenceBuilder referenceReferenceBuilder) : NonGenericTestReferenceReferenceBuilder< TEntity, TRelatedEntity>(referenceReferenceBuilder) where TEntity : class where TRelatedEntity : class diff --git a/test/EFCore.InMemory.FunctionalTests/ModelBuilding/InMemoryModelBuilderTest.cs b/test/EFCore.InMemory.FunctionalTests/ModelBuilding/InMemoryModelBuilderTest.cs index b3708b71b12..2050f207959 100644 --- a/test/EFCore.InMemory.FunctionalTests/ModelBuilding/InMemoryModelBuilderTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/ModelBuilding/InMemoryModelBuilderTest.cs @@ -8,25 +8,34 @@ namespace Microsoft.EntityFrameworkCore.ModelBuilding; public class InMemoryModelBuilderTest : ModelBuilderTest { - public abstract class InMemoryNonRelationship(InMemoryModelBuilderFixture fixture) : NonRelationshipTestBase(fixture), IClassFixture; + public abstract class InMemoryNonRelationship(InMemoryModelBuilderFixture fixture) + : NonRelationshipTestBase(fixture), IClassFixture; - public abstract class InMemoryComplexType(InMemoryModelBuilderFixture fixture) : ComplexTypeTestBase(fixture), IClassFixture; + public abstract class InMemoryComplexType(InMemoryModelBuilderFixture fixture) + : ComplexTypeTestBase(fixture), IClassFixture; - public abstract class InMemoryInheritance(InMemoryModelBuilderFixture fixture) : InheritanceTestBase(fixture), IClassFixture; + public abstract class InMemoryInheritance(InMemoryModelBuilderFixture fixture) + : InheritanceTestBase(fixture), IClassFixture; - public abstract class InMemoryOneToMany(InMemoryModelBuilderFixture fixture) : OneToManyTestBase(fixture), IClassFixture; + public abstract class InMemoryOneToMany(InMemoryModelBuilderFixture fixture) + : OneToManyTestBase(fixture), IClassFixture; - public abstract class InMemoryManyToMany(InMemoryModelBuilderFixture fixture) : ManyToManyTestBase(fixture), IClassFixture; + public abstract class InMemoryManyToMany(InMemoryModelBuilderFixture fixture) + : ManyToManyTestBase(fixture), IClassFixture; - public abstract class InMemoryManyToOne(InMemoryModelBuilderFixture fixture) : ManyToOneTestBase(fixture), IClassFixture; + public abstract class InMemoryManyToOne(InMemoryModelBuilderFixture fixture) + : ManyToOneTestBase(fixture), IClassFixture; - public abstract class InMemoryOneToOne(InMemoryModelBuilderFixture fixture) : OneToOneTestBase(fixture), IClassFixture; + public abstract class InMemoryOneToOne(InMemoryModelBuilderFixture fixture) + : OneToOneTestBase(fixture), IClassFixture; - public abstract class InMemoryOwnedTypes(InMemoryModelBuilderFixture fixture) : OwnedTypesTestBase(fixture), IClassFixture; + public abstract class InMemoryOwnedTypes(InMemoryModelBuilderFixture fixture) + : OwnedTypesTestBase(fixture), IClassFixture; public class InMemoryModelBuilderFixture : ModelBuilderFixtureBase { - public override TestHelpers TestHelpers => InMemoryTestHelpers.Instance; + public override TestHelpers TestHelpers + => InMemoryTestHelpers.Instance; public override bool ForeignKeysHaveIndexes => false; diff --git a/test/EFCore.InMemory.FunctionalTests/MonsterFixupSnapshotInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/MonsterFixupSnapshotInMemoryTest.cs index 9161871b951..32ea6cde199 100644 --- a/test/EFCore.InMemory.FunctionalTests/MonsterFixupSnapshotInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/MonsterFixupSnapshotInMemoryTest.cs @@ -3,8 +3,9 @@ namespace Microsoft.EntityFrameworkCore; -public class MonsterFixupSnapshotInMemoryTest(MonsterFixupSnapshotInMemoryTest.MonsterFixupSnapshotInMemoryFixture fixture) : MonsterFixupTestBase< - MonsterFixupSnapshotInMemoryTest.MonsterFixupSnapshotInMemoryFixture>(fixture) +public class MonsterFixupSnapshotInMemoryTest(MonsterFixupSnapshotInMemoryTest.MonsterFixupSnapshotInMemoryFixture fixture) + : MonsterFixupTestBase< + MonsterFixupSnapshotInMemoryTest.MonsterFixupSnapshotInMemoryFixture>(fixture) { public class MonsterFixupSnapshotInMemoryFixture : MonsterFixupSnapshotFixtureBase { diff --git a/test/EFCore.InMemory.FunctionalTests/MusicStoreInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/MusicStoreInMemoryTest.cs index df23e8fe011..49ffa9d389c 100644 --- a/test/EFCore.InMemory.FunctionalTests/MusicStoreInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/MusicStoreInMemoryTest.cs @@ -3,7 +3,8 @@ namespace Microsoft.EntityFrameworkCore; -public class MusicStoreInMemoryTest(MusicStoreInMemoryTest.MusicStoreInMemoryFixture fixture) : MusicStoreTestBase(fixture) +public class MusicStoreInMemoryTest(MusicStoreInMemoryTest.MusicStoreInMemoryFixture fixture) + : MusicStoreTestBase(fixture) { public class MusicStoreInMemoryFixture : MusicStoreFixtureBase { diff --git a/test/EFCore.InMemory.FunctionalTests/NonLoadingNavigationsInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/NonLoadingNavigationsInMemoryTest.cs index 9199cc0e5a0..880047d49a1 100644 --- a/test/EFCore.InMemory.FunctionalTests/NonLoadingNavigationsInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/NonLoadingNavigationsInMemoryTest.cs @@ -3,7 +3,8 @@ namespace Microsoft.EntityFrameworkCore; -public class NonLoadingNavigationsInMemoryTest(NonLoadingNavigationsInMemoryTest.NonLoadingNavigationsInMemoryFixture fixture) : LoadTestBase(fixture) +public class NonLoadingNavigationsInMemoryTest(NonLoadingNavigationsInMemoryTest.NonLoadingNavigationsInMemoryFixture fixture) + : LoadTestBase(fixture) { protected override bool LazyLoadingEnabled => false; diff --git a/test/EFCore.InMemory.FunctionalTests/NotificationEntitiesInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/NotificationEntitiesInMemoryTest.cs index 8426e1a25a3..27c0f651ec4 100644 --- a/test/EFCore.InMemory.FunctionalTests/NotificationEntitiesInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/NotificationEntitiesInMemoryTest.cs @@ -3,8 +3,9 @@ namespace Microsoft.EntityFrameworkCore; -public class NotificationEntitiesInMemoryTest(NotificationEntitiesInMemoryTest.NotificationEntitiesInMemoryFixture fixture) : NotificationEntitiesTestBase< - NotificationEntitiesInMemoryTest.NotificationEntitiesInMemoryFixture>(fixture) +public class NotificationEntitiesInMemoryTest(NotificationEntitiesInMemoryTest.NotificationEntitiesInMemoryFixture fixture) + : NotificationEntitiesTestBase< + NotificationEntitiesInMemoryTest.NotificationEntitiesInMemoryFixture>(fixture) { public class NotificationEntitiesInMemoryFixture : NotificationEntitiesFixtureBase { diff --git a/test/EFCore.InMemory.FunctionalTests/OptimisticConcurrencyInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/OptimisticConcurrencyInMemoryTest.cs index 61abad52f34..84d753a8f76 100644 --- a/test/EFCore.InMemory.FunctionalTests/OptimisticConcurrencyInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/OptimisticConcurrencyInMemoryTest.cs @@ -3,9 +3,11 @@ namespace Microsoft.EntityFrameworkCore; -public class OptimisticConcurrencyULongInMemoryTest(F1ULongInMemoryFixture fixture) : OptimisticConcurrencyInMemoryTestBase(fixture); +public class OptimisticConcurrencyULongInMemoryTest(F1ULongInMemoryFixture fixture) + : OptimisticConcurrencyInMemoryTestBase(fixture); -public class OptimisticConcurrencyInMemoryTest(F1InMemoryFixture fixture) : OptimisticConcurrencyInMemoryTestBase(fixture); +public class OptimisticConcurrencyInMemoryTest(F1InMemoryFixture fixture) + : OptimisticConcurrencyInMemoryTestBase(fixture); public abstract class OptimisticConcurrencyInMemoryTestBase(TFixture fixture) : OptimisticConcurrencyTestBase(fixture) diff --git a/test/EFCore.InMemory.FunctionalTests/PropertyValuesInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/PropertyValuesInMemoryTest.cs index e53710149e9..95edb17f942 100644 --- a/test/EFCore.InMemory.FunctionalTests/PropertyValuesInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/PropertyValuesInMemoryTest.cs @@ -3,7 +3,8 @@ namespace Microsoft.EntityFrameworkCore; -public class PropertyValuesInMemoryTest(PropertyValuesInMemoryTest.PropertyValuesInMemoryFixture fixture) : PropertyValuesTestBase(fixture) +public class PropertyValuesInMemoryTest(PropertyValuesInMemoryTest.PropertyValuesInMemoryFixture fixture) + : PropertyValuesTestBase(fixture) { public override Task Complex_current_values_can_be_accessed_as_a_property_dictionary_using_IProperty() => Assert.ThrowsAsync( // In-memory database cannot query complex types @@ -46,7 +47,6 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con b.Ignore(e => e.Culture); b.Ignore(e => e.Milk); }); - } } } diff --git a/test/EFCore.InMemory.FunctionalTests/Query/FiltersInheritanceQueryInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/Query/FiltersInheritanceQueryInMemoryTest.cs index 83e7a031463..3427fcc712a 100644 --- a/test/EFCore.InMemory.FunctionalTests/Query/FiltersInheritanceQueryInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/Query/FiltersInheritanceQueryInMemoryTest.cs @@ -3,4 +3,5 @@ namespace Microsoft.EntityFrameworkCore.Query; -public class FiltersInheritanceQueryInMemoryTest(FiltersInheritanceQueryInMemoryFixture fixture) : FiltersInheritanceQueryTestBase(fixture); +public class FiltersInheritanceQueryInMemoryTest(FiltersInheritanceQueryInMemoryFixture fixture) + : FiltersInheritanceQueryTestBase(fixture); diff --git a/test/EFCore.InMemory.FunctionalTests/Query/GearsOfWarQueryInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/Query/GearsOfWarQueryInMemoryTest.cs index 4d6b2f4b184..fdd78cef5a4 100644 --- a/test/EFCore.InMemory.FunctionalTests/Query/GearsOfWarQueryInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/Query/GearsOfWarQueryInMemoryTest.cs @@ -3,7 +3,6 @@ using Microsoft.EntityFrameworkCore.InMemory.Internal; using Microsoft.EntityFrameworkCore.TestModels.GearsOfWarModel; -using Xunit.Sdk; namespace Microsoft.EntityFrameworkCore.Query; diff --git a/test/EFCore.InMemory.FunctionalTests/Query/IncludeOneToOneInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/Query/IncludeOneToOneInMemoryTest.cs index 7db214c779f..96a992fe374 100644 --- a/test/EFCore.InMemory.FunctionalTests/Query/IncludeOneToOneInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/Query/IncludeOneToOneInMemoryTest.cs @@ -3,7 +3,8 @@ namespace Microsoft.EntityFrameworkCore.Query; -public class IncludeOneToOneInMemoryTest(IncludeOneToOneInMemoryTest.OneToOneQueryInMemoryFixture fixture) : IncludeOneToOneTestBase(fixture) +public class IncludeOneToOneInMemoryTest(IncludeOneToOneInMemoryTest.OneToOneQueryInMemoryFixture fixture) + : IncludeOneToOneTestBase(fixture) { public class OneToOneQueryInMemoryFixture : OneToOneQueryFixtureBase { diff --git a/test/EFCore.InMemory.FunctionalTests/Query/IncompleteMappingInheritanceQueryInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/Query/IncompleteMappingInheritanceQueryInMemoryTest.cs index 03edfb5389b..5bc8c697d26 100644 --- a/test/EFCore.InMemory.FunctionalTests/Query/IncompleteMappingInheritanceQueryInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/Query/IncompleteMappingInheritanceQueryInMemoryTest.cs @@ -3,7 +3,8 @@ namespace Microsoft.EntityFrameworkCore.Query; -public class IncompleteMappingInheritanceQueryInMemoryTest(IncompleteMappingInheritanceQueryInMemoryFixture fixture) : InheritanceQueryTestBase(fixture) +public class IncompleteMappingInheritanceQueryInMemoryTest(IncompleteMappingInheritanceQueryInMemoryFixture fixture) + : InheritanceQueryTestBase(fixture) { public override async Task Can_query_all_animal_views(bool async) { diff --git a/test/EFCore.InMemory.FunctionalTests/Query/InheritanceRelationshipsQueryInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/Query/InheritanceRelationshipsQueryInMemoryTest.cs index 70682997865..64efa13f59b 100644 --- a/test/EFCore.InMemory.FunctionalTests/Query/InheritanceRelationshipsQueryInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/Query/InheritanceRelationshipsQueryInMemoryTest.cs @@ -3,5 +3,6 @@ namespace Microsoft.EntityFrameworkCore.Query; -public class InheritanceRelationshipsQueryInMemoryTest(InheritanceRelationshipsQueryInMemoryFixture fixture) : InheritanceRelationshipsQueryTestBase< - InheritanceRelationshipsQueryInMemoryFixture>(fixture); +public class InheritanceRelationshipsQueryInMemoryTest(InheritanceRelationshipsQueryInMemoryFixture fixture) + : InheritanceRelationshipsQueryTestBase< + InheritanceRelationshipsQueryInMemoryFixture>(fixture); diff --git a/test/EFCore.InMemory.FunctionalTests/Query/NorthwindAggregateOperatorsQueryInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/Query/NorthwindAggregateOperatorsQueryInMemoryTest.cs index 2b91264909c..4fbd11e77d6 100644 --- a/test/EFCore.InMemory.FunctionalTests/Query/NorthwindAggregateOperatorsQueryInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/Query/NorthwindAggregateOperatorsQueryInMemoryTest.cs @@ -6,7 +6,6 @@ namespace Microsoft.EntityFrameworkCore.Query; public class NorthwindAggregateOperatorsQueryInMemoryTest(NorthwindQueryInMemoryFixture fixture) : NorthwindAggregateOperatorsQueryTestBase>(fixture) { - // InMemory can throw server side exception public override async Task Average_no_data_subquery(bool async) => Assert.Equal( diff --git a/test/EFCore.InMemory.FunctionalTests/Query/NorthwindAsNoTrackingQueryInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/Query/NorthwindAsNoTrackingQueryInMemoryTest.cs index f3eedf76916..9750c5ffbb2 100644 --- a/test/EFCore.InMemory.FunctionalTests/Query/NorthwindAsNoTrackingQueryInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/Query/NorthwindAsNoTrackingQueryInMemoryTest.cs @@ -3,5 +3,6 @@ namespace Microsoft.EntityFrameworkCore.Query; -public class NorthwindAsNoTrackingQueryInMemoryTest(NorthwindQueryInMemoryFixture fixture) : NorthwindAsNoTrackingQueryTestBase< - NorthwindQueryInMemoryFixture>(fixture); +public class NorthwindAsNoTrackingQueryInMemoryTest(NorthwindQueryInMemoryFixture fixture) + : NorthwindAsNoTrackingQueryTestBase< + NorthwindQueryInMemoryFixture>(fixture); diff --git a/test/EFCore.InMemory.FunctionalTests/Query/NorthwindAsTrackingQueryInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/Query/NorthwindAsTrackingQueryInMemoryTest.cs index 0612b33b427..cfe6d2593c5 100644 --- a/test/EFCore.InMemory.FunctionalTests/Query/NorthwindAsTrackingQueryInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/Query/NorthwindAsTrackingQueryInMemoryTest.cs @@ -3,4 +3,5 @@ namespace Microsoft.EntityFrameworkCore.Query; -public class NorthwindAsTrackingQueryInMemoryTest(NorthwindQueryInMemoryFixture fixture) : NorthwindAsTrackingQueryTestBase>(fixture); +public class NorthwindAsTrackingQueryInMemoryTest(NorthwindQueryInMemoryFixture fixture) + : NorthwindAsTrackingQueryTestBase>(fixture); diff --git a/test/EFCore.InMemory.FunctionalTests/Query/NorthwindCompiledQueryInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/Query/NorthwindCompiledQueryInMemoryTest.cs index 3ddd7408e95..abb05e2df8d 100644 --- a/test/EFCore.InMemory.FunctionalTests/Query/NorthwindCompiledQueryInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/Query/NorthwindCompiledQueryInMemoryTest.cs @@ -3,4 +3,5 @@ namespace Microsoft.EntityFrameworkCore.Query; -public class NorthwindCompiledQueryInMemoryTest(NorthwindQueryInMemoryFixture fixture) : NorthwindCompiledQueryTestBase>(fixture); +public class NorthwindCompiledQueryInMemoryTest(NorthwindQueryInMemoryFixture fixture) + : NorthwindCompiledQueryTestBase>(fixture); diff --git a/test/EFCore.InMemory.FunctionalTests/Query/NorthwindGroupByQueryInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/Query/NorthwindGroupByQueryInMemoryTest.cs index 0cbdbec62c6..1e7af050b34 100644 --- a/test/EFCore.InMemory.FunctionalTests/Query/NorthwindGroupByQueryInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/Query/NorthwindGroupByQueryInMemoryTest.cs @@ -67,4 +67,9 @@ public override Task Final_GroupBy_property_entity_projecting_collection_and_sin => AssertTranslationFailedWithDetails( () => base.Final_GroupBy_property_entity_projecting_collection_and_single_result(async), InMemoryStrings.NonComposedGroupByNotSupported); + + public override Task Final_GroupBy_TagWith(bool async) + => AssertTranslationFailedWithDetails( + () => base.Final_GroupBy_TagWith(async), + InMemoryStrings.NonComposedGroupByNotSupported); } diff --git a/test/EFCore.InMemory.FunctionalTests/Query/NorthwindKeylessEntitiesQueryInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/Query/NorthwindKeylessEntitiesQueryInMemoryTest.cs index 266a51c0a63..eba6a41d5b7 100644 --- a/test/EFCore.InMemory.FunctionalTests/Query/NorthwindKeylessEntitiesQueryInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/Query/NorthwindKeylessEntitiesQueryInMemoryTest.cs @@ -6,7 +6,6 @@ namespace Microsoft.EntityFrameworkCore.Query; public class NorthwindKeylessEntitiesQueryInMemoryTest(NorthwindQueryInMemoryFixture fixture) : NorthwindKeylessEntitiesQueryTestBase>(fixture) { - // mapping to view not supported on InMemory public override Task KeylessEntity_by_database_view(bool async) => Task.CompletedTask; diff --git a/test/EFCore.InMemory.FunctionalTests/Query/NorthwindMiscellaneousQueryInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/Query/NorthwindMiscellaneousQueryInMemoryTest.cs index ef7b6c60356..8575750edbb 100644 --- a/test/EFCore.InMemory.FunctionalTests/Query/NorthwindMiscellaneousQueryInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/Query/NorthwindMiscellaneousQueryInMemoryTest.cs @@ -55,4 +55,9 @@ public override Task Collection_navigation_equal_to_null_for_subquery_using_Elem public override Task Collection_navigation_equal_to_null_for_subquery_using_ElementAtOrDefault_parameter(bool async) => Task.CompletedTask; + + public override Task Where_Order_First(bool async) + // Sequence contains no elements. + => Assert.ThrowsAsync( + () => base.Where_Order_First(async)); } diff --git a/test/EFCore.InMemory.FunctionalTests/Query/NorthwindWhereQueryInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/Query/NorthwindWhereQueryInMemoryTest.cs index d7e36df9e11..4c7da207ccb 100644 --- a/test/EFCore.InMemory.FunctionalTests/Query/NorthwindWhereQueryInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/Query/NorthwindWhereQueryInMemoryTest.cs @@ -50,6 +50,4 @@ public override Task Where_compare_tuple_constructed_multi_value_not_equal(bool public override Task Where_compare_tuple_create_constructed_multi_value_not_equal(bool async) => Task.CompletedTask; - - } diff --git a/test/EFCore.InMemory.FunctionalTests/Query/NullKeysInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/Query/NullKeysInMemoryTest.cs index 6478fe0a052..a98ca3683c4 100644 --- a/test/EFCore.InMemory.FunctionalTests/Query/NullKeysInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/Query/NullKeysInMemoryTest.cs @@ -3,7 +3,8 @@ namespace Microsoft.EntityFrameworkCore.Query; -public class NullKeysInMemoryTest(NullKeysInMemoryTest.NullKeysInMemoryFixture fixture) : NullKeysTestBase(fixture) +public class NullKeysInMemoryTest(NullKeysInMemoryTest.NullKeysInMemoryFixture fixture) + : NullKeysTestBase(fixture) { public class NullKeysInMemoryFixture : NullKeysFixtureBase { diff --git a/test/EFCore.InMemory.FunctionalTests/Query/QueryBugsInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/Query/QueryBugsInMemoryTest.cs index b03a2f9b49c..82fbe1c909a 100644 --- a/test/EFCore.InMemory.FunctionalTests/Query/QueryBugsInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/Query/QueryBugsInMemoryTest.cs @@ -16,7 +16,7 @@ public class QueryBugsInMemoryTest : IClassFixture [ConditionalFact] public virtual async Task Include_throw_when_empty_9849() { - using (await CreateScratchAsync(_ => Task.CompletedTask, "9849")) + await using (await CreateScratchAsync(_ => Task.CompletedTask, "9849")) { using var context = new DatabaseContext(); var results = context.VehicleInspections.Include(_ => _.Motors).ToList(); @@ -28,7 +28,7 @@ public virtual async Task Include_throw_when_empty_9849() [ConditionalFact] public virtual async Task Include_throw_when_empty_9849_2() { - using (await CreateScratchAsync(_ => Task.CompletedTask, "9849")) + await using (await CreateScratchAsync(_ => Task.CompletedTask, "9849")) { using var context = new DatabaseContext(); #pragma warning disable IDE1006 // Naming Styles @@ -42,7 +42,7 @@ public virtual async Task Include_throw_when_empty_9849_2() [ConditionalFact] public virtual async Task Include_throw_when_empty_9849_3() { - using (await CreateScratchAsync(_ => Task.CompletedTask, "9849")) + await using (await CreateScratchAsync(_ => Task.CompletedTask, "9849")) { using var context = new DatabaseContext(); #pragma warning disable IDE1006 // Naming Styles @@ -56,7 +56,7 @@ public virtual async Task Include_throw_when_empty_9849_3() [ConditionalFact] public virtual async Task Include_throw_when_empty_9849_4() { - using (await CreateScratchAsync(_ => Task.CompletedTask, "9849")) + await using (await CreateScratchAsync(_ => Task.CompletedTask, "9849")) { using var context = new DatabaseContext(); #pragma warning disable IDE1006 // Naming Styles @@ -70,7 +70,7 @@ public virtual async Task Include_throw_when_empty_9849_4() [ConditionalFact] public virtual async Task Include_throw_when_empty_9849_5() { - using (await CreateScratchAsync(_ => Task.CompletedTask, "9849")) + await using (await CreateScratchAsync(_ => Task.CompletedTask, "9849")) { using var context = new DatabaseContext(); var results @@ -86,7 +86,7 @@ join __ in context.VehicleInspections on _f.Id equals __.Id [ConditionalFact] public virtual async Task Include_throw_when_empty_9849_6() { - using (await CreateScratchAsync(_ => Task.CompletedTask, "9849")) + await using (await CreateScratchAsync(_ => Task.CompletedTask, "9849")) { using var context = new DatabaseContext(); #pragma warning disable IDE1006 // Naming Styles @@ -146,7 +146,7 @@ private class Motor [ConditionalFact] public virtual async Task GroupBy_with_uninitialized_datetime_projection_3595() { - using (await CreateScratchAsync(Seed3595, "3595")) + await using (await CreateScratchAsync(Seed3595, "3595")) { using var context = new Context3595(); var q0 = from instance in context.Exams @@ -224,7 +224,7 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) [ConditionalFact] public virtual async Task Repro3101_simple_coalesce1() { - using (await CreateScratchAsync(Seed3101, "3101")) + await using (await CreateScratchAsync(Seed3101, "3101")) { using var ctx = new MyContext3101(); var query = from eVersion in ctx.Entities @@ -241,7 +241,7 @@ from eRootJoined in RootEntities.DefaultIfEmpty() [ConditionalFact] public virtual async Task Repro3101_simple_coalesce2() { - using (await CreateScratchAsync(Seed3101, "3101")) + await using (await CreateScratchAsync(Seed3101, "3101")) { using var ctx = new MyContext3101(); var query = from eVersion in ctx.Entities @@ -259,7 +259,7 @@ from eRootJoined in RootEntities.DefaultIfEmpty() [ConditionalFact] public virtual async Task Repro3101_simple_coalesce3() { - using (await CreateScratchAsync(Seed3101, "3101")) + await using (await CreateScratchAsync(Seed3101, "3101")) { using var ctx = new MyContext3101(); var query = from eVersion in ctx.Entities.Include(e => e.Children) @@ -278,7 +278,7 @@ from eRootJoined in RootEntities.DefaultIfEmpty() [ConditionalFact] public virtual async Task Repro3101_complex_coalesce1() { - using (await CreateScratchAsync(Seed3101, "3101")) + await using (await CreateScratchAsync(Seed3101, "3101")) { using var ctx = new MyContext3101(); var query = from eVersion in ctx.Entities.Include(e => e.Children) @@ -296,7 +296,7 @@ from eRootJoined in RootEntities.DefaultIfEmpty() [ConditionalFact] public virtual async Task Repro3101_complex_coalesce2() { - using (await CreateScratchAsync(Seed3101, "3101")) + await using (await CreateScratchAsync(Seed3101, "3101")) { using var ctx = new MyContext3101(); var query = from eVersion in ctx.Entities @@ -314,7 +314,7 @@ from eRootJoined in RootEntities.DefaultIfEmpty() [ConditionalFact] public virtual async Task Repro3101_nested_coalesce1() { - using (await CreateScratchAsync(Seed3101, "3101")) + await using (await CreateScratchAsync(Seed3101, "3101")) { using var ctx = new MyContext3101(); var query = from eVersion in ctx.Entities @@ -332,7 +332,7 @@ from eRootJoined in RootEntities.DefaultIfEmpty() [ConditionalFact] public virtual async Task Repro3101_nested_coalesce2() { - using (await CreateScratchAsync(Seed3101, "3101")) + await using (await CreateScratchAsync(Seed3101, "3101")) { using var ctx = new MyContext3101(); var query = from eVersion in ctx.Entities.Include(e => e.Children) @@ -355,7 +355,7 @@ from eRootJoined in RootEntities.DefaultIfEmpty() [ConditionalFact] public virtual async Task Repro3101_conditional() { - using (await CreateScratchAsync(Seed3101, "3101")) + await using (await CreateScratchAsync(Seed3101, "3101")) { using var ctx = new MyContext3101(); var query = from eVersion in ctx.Entities.Include(e => e.Children) @@ -375,7 +375,7 @@ from eRootJoined in RootEntities.DefaultIfEmpty() [ConditionalFact] public virtual async Task Repro3101_coalesce_tracking() { - using (await CreateScratchAsync(Seed3101, "3101")) + await using (await CreateScratchAsync(Seed3101, "3101")) { using var ctx = new MyContext3101(); var query = from eVersion in ctx.Entities @@ -459,7 +459,7 @@ private class Child3101 [ConditionalFact] public virtual async Task Repro5456_include_group_join_is_per_query_context() { - using (await CreateScratchAsync(Seed5456, "5456")) + await using (await CreateScratchAsync(Seed5456, "5456")) { Parallel.For( 0, 10, i => @@ -475,7 +475,7 @@ public virtual async Task Repro5456_include_group_join_is_per_query_context() [ConditionalFact] public virtual async Task Repro5456_include_group_join_is_per_query_context_async() { - using (await CreateScratchAsync(Seed5456, "5456")) + await using (await CreateScratchAsync(Seed5456, "5456")) { var tasks = new List(); for (var i = 0; i < 10; i++) @@ -498,7 +498,7 @@ async Task Action() [ConditionalFact] public virtual async Task Repro5456_multiple_include_group_join_is_per_query_context() { - using (await CreateScratchAsync(Seed5456, "5456")) + await using (await CreateScratchAsync(Seed5456, "5456")) { Parallel.For( 0, 10, i => @@ -514,7 +514,7 @@ public virtual async Task Repro5456_multiple_include_group_join_is_per_query_con [ConditionalFact] public virtual async Task Repro5456_multiple_include_group_join_is_per_query_context_async() { - using (await CreateScratchAsync(Seed5456, "5456")) + await using (await CreateScratchAsync(Seed5456, "5456")) { var tasks = new List(); for (var i = 0; i < 10; i++) @@ -538,7 +538,7 @@ async Task Action() [ConditionalFact] public virtual async Task Repro5456_multi_level_include_group_join_is_per_query_context() { - using (await CreateScratchAsync(Seed5456, "5456")) + await using (await CreateScratchAsync(Seed5456, "5456")) { Parallel.For( 0, 10, i => @@ -554,7 +554,7 @@ public virtual async Task Repro5456_multi_level_include_group_join_is_per_query_ [ConditionalFact] public virtual async Task Repro5456_multi_level_include_group_join_is_per_query_context_async() { - using (await CreateScratchAsync(Seed5456, "5456")) + await using (await CreateScratchAsync(Seed5456, "5456")) { var tasks = new List(); for (var i = 0; i < 10; i++) @@ -583,7 +583,7 @@ private Task Seed5456(MyContext5456 context) new Blog5456 { Id = i + 1, - Posts = [new() { Comments = [new(), new()] }, new()], + Posts = [new Post5456 { Comments = [new Comment5456(), new Comment5456()] }, new Post5456()], Author = new Author5456() }); } @@ -642,7 +642,7 @@ private class Comment5456 [ConditionalFact] public virtual async Task Entity_passed_to_DTO_constructor_works() { - using (await CreateScratchAsync(_ => Task.CompletedTask, "8282")) + await using (await CreateScratchAsync(_ => Task.CompletedTask, "8282")) { using var context = new MyContext8282(); var query = context.Entity.Select(e => new EntityDto8282(e)).ToList(); @@ -679,7 +679,7 @@ private class EntityDto8282(Entity8282 entity) [ConditionalFact] public virtual async Task Select_enumerable_navigation_backed_by_collection() { - using (await CreateScratchAsync(Seed21803, "21803")) + await using (await CreateScratchAsync(Seed21803, "21803")) { using var context = new MyContext21803(); @@ -734,7 +734,7 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) [ConditionalFact] public virtual async Task Multiple_owned_references_at_same_level_maintains_valueBuffer_positions() { - using (await CreateScratchAsync(Seed20729, "20729")) + await using (await CreateScratchAsync(Seed20729, "20729")) { using var context = new MyContext20729(); @@ -812,7 +812,7 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) [ConditionalFact] public virtual async Task Owned_reference_on_base_with_hierarchy() { - using (await CreateScratchAsync(Seed23285, "23285")) + await using (await CreateScratchAsync(Seed23285, "23285")) { using var context = new MyContext23285(); @@ -877,7 +877,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalFact] public virtual async Task Owned_reference_with_composite_key() { - using (await CreateScratchAsync(Seed23687, "23687")) + await using (await CreateScratchAsync(Seed23687, "23687")) { using var context = new MyContext23687(); @@ -938,7 +938,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalFact] public virtual async Task Join_with_enum_as_key_selector() { - using (await CreateScratchAsync(Seed23593, "23593")) + await using (await CreateScratchAsync(Seed23593, "23593")) { using var context = new MyContext23593(); @@ -954,7 +954,7 @@ join sme in context.StatusMapEvents on sm.Id equals sme.Id [ConditionalFact] public virtual async Task Join_with_enum_inside_anonymous_type_as_key_selector() { - using (await CreateScratchAsync(Seed23593, "23593")) + await using (await CreateScratchAsync(Seed23593, "23593")) { using var context = new MyContext23593(); @@ -970,7 +970,7 @@ public virtual async Task Join_with_enum_inside_anonymous_type_as_key_selector() [ConditionalFact] public virtual async Task Join_with_enum_inside_anonymous_type_with_other_property_as_key_selector() { - using (await CreateScratchAsync(Seed23593, "23593")) + await using (await CreateScratchAsync(Seed23593, "23593")) { using var context = new MyContext23593(); @@ -1031,7 +1031,7 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) [ConditionalFact] public virtual async Task Left_join_with_entity_with_enum_discriminator() { - using (await CreateScratchAsync(Seed23926, "23926")) + await using (await CreateScratchAsync(Seed23926, "23926")) { using var context = new MyContext23926(); @@ -1098,7 +1098,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalFact] public virtual async Task Shared_owned_property_on_multiple_level_in_Select() { - using (await CreateScratchAsync(Seed18435, "18435")) + await using (await CreateScratchAsync(Seed18435, "18435")) { using var context = new MyContext18435(); @@ -1188,7 +1188,7 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) [ConditionalFact(Skip = "Issue#19425")] public virtual async Task Non_nullable_cast_in_null_check() { - using (await CreateScratchAsync(Seed19425, "19425")) + await using (await CreateScratchAsync(Seed19425, "19425")) { using var context = new MyContext19425(); @@ -1236,7 +1236,7 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) [ConditionalFact] public virtual async Task Property_access_on_nullable_converted_scalar_type() { - using (await CreateScratchAsync(Seed19667, "19667")) + await using (await CreateScratchAsync(Seed19667, "19667")) { using var context = new MyContext19667(); @@ -1285,7 +1285,7 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) [ConditionalFact] public virtual async Task Changing_order_of_projection_in_anonymous_type_works() { - using (await CreateScratchAsync(Seed20359, "20359")) + await using (await CreateScratchAsync(Seed20359, "20359")) { using var context = new MyContext20359(); @@ -1372,7 +1372,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalFact] public virtual async Task Union_with_different_property_name_using_same_anonymous_type() { - using (await CreateScratchAsync(Seed23360, "23360")) + await using (await CreateScratchAsync(Seed23360, "23360")) { using var context = new MyContext23360(); @@ -1460,7 +1460,7 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) [ConditionalFact] public virtual async Task Ordering_of_collection_result_is_correct() { - using (await CreateScratchAsync(Seed18394, "18394")) + await using (await CreateScratchAsync(Seed18394, "18394")) { using var context = new MyContext18394(); @@ -1487,7 +1487,7 @@ public virtual async Task Ordering_of_collection_result_is_correct() private static Task Seed18394(MyContext18394 context) { - var a = new A18394 { PropertyB = new B18394 { PropertyCList = [new() { SomeText = "TestText" }] } }; + var a = new A18394 { PropertyB = new B18394 { PropertyCList = [new C18394 { SomeText = "TestText" }] } }; context.As.Add(a); return context.SaveChangesAsync(); @@ -1565,7 +1565,7 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) [ConditionalFact] public virtual async Task Owned_entity_indexes_are_maintained_properly() { - using (await CreateScratchAsync(Seed23934, "23934")) + await using (await CreateScratchAsync(Seed23934, "23934")) { using var context = new MyContext23934(); diff --git a/test/EFCore.InMemory.FunctionalTests/Query/WarningsTest.cs b/test/EFCore.InMemory.FunctionalTests/Query/WarningsTest.cs index bc9020d4244..6f337e0891b 100644 --- a/test/EFCore.InMemory.FunctionalTests/Query/WarningsTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/Query/WarningsTest.cs @@ -286,9 +286,7 @@ public WarningAsErrorEntity() } private WarningAsErrorEntity(Action lazyLoader) - { - _loader = lazyLoader; - } + => _loader = lazyLoader; public IncludedEntity Nav { diff --git a/test/EFCore.InMemory.FunctionalTests/SaveChangesInterceptionInMemoryTestBase.cs b/test/EFCore.InMemory.FunctionalTests/SaveChangesInterceptionInMemoryTestBase.cs index 8612adaf330..cdb52d890f1 100644 --- a/test/EFCore.InMemory.FunctionalTests/SaveChangesInterceptionInMemoryTestBase.cs +++ b/test/EFCore.InMemory.FunctionalTests/SaveChangesInterceptionInMemoryTestBase.cs @@ -37,7 +37,8 @@ protected override bool ShouldSubscribeToDiagnosticListener } } - public class SaveChangesInterceptionWithDiagnosticsInMemoryTest(SaveChangesInterceptionWithDiagnosticsInMemoryTest.InterceptionInMemoryFixture fixture) + public class SaveChangesInterceptionWithDiagnosticsInMemoryTest( + SaveChangesInterceptionWithDiagnosticsInMemoryTest.InterceptionInMemoryFixture fixture) : SaveChangesInterceptionInMemoryTestBase(fixture), IClassFixture { diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/DbContextAssemblyAttributes.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/DbContextAssemblyAttributes.cs new file mode 100644 index 00000000000..c224873f6fa --- /dev/null +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/DbContextAssemblyAttributes.cs @@ -0,0 +1,9 @@ +// +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using TestNamespace; + +#pragma warning disable 219, 612, 618 +#nullable disable + +[assembly: DbContextModel(typeof(DbContext), typeof(DbContextModel))] diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/DbContextModel.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/DbContextModel.cs new file mode 100644 index 00000000000..583ee4d90cc --- /dev/null +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/DbContextModel.cs @@ -0,0 +1,48 @@ +// +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [DbContext(typeof(DbContext))] + public partial class DbContextModel : RuntimeModel + { + private static readonly bool _useOldBehavior31751 = + System.AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue31751", out var enabled31751) && enabled31751; + + static DbContextModel() + { + var model = new DbContextModel(); + + if (_useOldBehavior31751) + { + model.Initialize(); + } + else + { + var thread = new System.Threading.Thread(RunInitialization, 10 * 1024 * 1024); + thread.Start(); + thread.Join(); + + void RunInitialization() + { + model.Initialize(); + } + } + + model.Customize(); + _instance = (DbContextModel)model.FinalizeModel(); + } + + private static DbContextModel _instance; + public static IModel Instance => _instance; + + partial void Initialize(); + + partial void Customize(); + } +} diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/DbContextModelBuilder.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/DbContextModelBuilder.cs new file mode 100644 index 00000000000..b59436c7735 --- /dev/null +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/DbContextModelBuilder.cs @@ -0,0 +1,50 @@ +// +using System; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + public partial class DbContextModel + { + private DbContextModel() + : base(skipDetectChanges: false, modelId: new Guid("00000000-0000-0000-0000-000000000000"), entityTypeCount: 8) + { + } + + partial void Initialize() + { + var dependentBase = DependentBaseEntityType.Create(this); + var manyTypes = ManyTypesEntityType.Create(this); + var principalBase = PrincipalBaseEntityType.Create(this); + var ownedType = OwnedTypeEntityType.Create(this); + var ownedType0 = OwnedType0EntityType.Create(this); + var principalBasePrincipalDerivedDependentBasebyte = PrincipalBasePrincipalDerivedDependentBasebyteEntityType.Create(this); + var dependentDerived = DependentDerivedEntityType.Create(this, dependentBase); + var principalDerived = PrincipalDerivedEntityType.Create(this, principalBase); + + DependentBaseEntityType.CreateForeignKey1(dependentBase, principalBase); + DependentBaseEntityType.CreateForeignKey2(dependentBase, principalDerived); + OwnedTypeEntityType.CreateForeignKey1(ownedType, principalBase); + OwnedType0EntityType.CreateForeignKey1(ownedType0, principalDerived); + PrincipalBasePrincipalDerivedDependentBasebyteEntityType.CreateForeignKey1(principalBasePrincipalDerivedDependentBasebyte, principalDerived); + PrincipalBasePrincipalDerivedDependentBasebyteEntityType.CreateForeignKey2(principalBasePrincipalDerivedDependentBasebyte, principalBase); + + PrincipalBaseEntityType.CreateSkipNavigation1(principalBase, principalDerived, principalBasePrincipalDerivedDependentBasebyte); + PrincipalDerivedEntityType.CreateSkipNavigation1(principalDerived, principalBase, principalBasePrincipalDerivedDependentBasebyte); + + DependentBaseEntityType.CreateAnnotations(dependentBase); + ManyTypesEntityType.CreateAnnotations(manyTypes); + PrincipalBaseEntityType.CreateAnnotations(principalBase); + OwnedTypeEntityType.CreateAnnotations(ownedType); + OwnedType0EntityType.CreateAnnotations(ownedType0); + PrincipalBasePrincipalDerivedDependentBasebyteEntityType.CreateAnnotations(principalBasePrincipalDerivedDependentBasebyte); + DependentDerivedEntityType.CreateAnnotations(dependentDerived); + PrincipalDerivedEntityType.CreateAnnotations(principalDerived); + + } + } +} diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/DependentBaseEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/DependentBaseEntityType.cs new file mode 100644 index 00000000000..dc8d863b403 --- /dev/null +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/DependentBaseEntityType.cs @@ -0,0 +1,114 @@ +// +using System; +using System.Reflection; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; +using Microsoft.EntityFrameworkCore.ValueGeneration; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class DependentBaseEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+DependentBase", + typeof(CompiledModelTestBase.DependentBase), + baseEntityType, + discriminatorProperty: "EnumDiscriminator", + discriminatorValue: CompiledModelTestBase.Enum1.One, + derivedTypesCount: 1, + propertyCount: 4, + navigationCount: 1, + foreignKeyCount: 2, + keyCount: 1); + + var principalId = runtimeEntityType.AddProperty( + "PrincipalId", + typeof(long), + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: 0L); + + var principalAlternateId = runtimeEntityType.AddProperty( + "PrincipalAlternateId", + typeof(Guid), + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: new Guid("00000000-0000-0000-0000-000000000000")); + + var enumDiscriminator = runtimeEntityType.AddProperty( + "EnumDiscriminator", + typeof(CompiledModelTestBase.Enum1), + afterSaveBehavior: PropertySaveBehavior.Throw, + valueGeneratorFactory: new DiscriminatorValueGeneratorFactory().Create, + sentinel: CompiledModelTestBase.Enum1.Default); + + var id = runtimeEntityType.AddProperty( + "Id", + typeof(byte?), + propertyInfo: typeof(CompiledModelTestBase.DependentBase).GetProperty("Id", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.DependentBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var key = runtimeEntityType.AddKey( + new[] { principalId, principalAlternateId }); + runtimeEntityType.SetPrimaryKey(key); + + return runtimeEntityType; + } + + public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("PrincipalId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("Id") }), + principalEntityType, + deleteBehavior: DeleteBehavior.Cascade, + unique: true, + required: true); + + return runtimeForeignKey; + } + + public static RuntimeForeignKey CreateForeignKey2(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("PrincipalId"), declaringEntityType.FindProperty("PrincipalAlternateId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("Id"), principalEntityType.FindProperty("AlternateId") }), + principalEntityType, + deleteBehavior: DeleteBehavior.ClientNoAction, + unique: true, + required: true); + + var principal = declaringEntityType.AddNavigation("Principal", + runtimeForeignKey, + onDependent: true, + typeof(CompiledModelTestBase.PrincipalDerived>), + propertyInfo: typeof(CompiledModelTestBase.DependentBase).GetProperty("Principal", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.DependentBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var dependent = principalEntityType.AddNavigation("Dependent", + runtimeForeignKey, + onDependent: false, + typeof(CompiledModelTestBase.DependentBase), + propertyInfo: typeof(CompiledModelTestBase.PrincipalDerived>).GetProperty("Dependent", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalDerived>).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + eagerLoaded: true, + lazyLoadingEnabled: false); + + return runtimeForeignKey; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + runtimeEntityType.AddAnnotation("DiscriminatorMappingComplete", false); + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/DependentDerivedEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/DependentDerivedEntityType.cs new file mode 100644 index 00000000000..74ff4f82ea1 --- /dev/null +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/DependentDerivedEntityType.cs @@ -0,0 +1,53 @@ +// +using System; +using System.Reflection; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class DependentDerivedEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+DependentDerived", + typeof(CompiledModelTestBase.DependentDerived), + baseEntityType, + discriminatorProperty: "EnumDiscriminator", + discriminatorValue: CompiledModelTestBase.Enum1.Two, + propertyCount: 2); + + var data = runtimeEntityType.AddProperty( + "Data", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.DependentDerived).GetProperty("Data", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.DependentDerived).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true, + maxLength: 20, + unicode: false); + + var money = runtimeEntityType.AddProperty( + "Money", + typeof(decimal), + precision: 9, + scale: 3, + sentinel: 0m); + + return runtimeEntityType; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/ManyTypesEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/ManyTypesEntityType.cs new file mode 100644 index 00000000000..1af80a9af87 --- /dev/null +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/ManyTypesEntityType.cs @@ -0,0 +1,1779 @@ +// +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.NetworkInformation; +using System.Reflection; +using System.Text; +using Microsoft.EntityFrameworkCore.ChangeTracking; +using Microsoft.EntityFrameworkCore.InMemory.Storage.Internal; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; +using Microsoft.EntityFrameworkCore.Storage.Json; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class ManyTypesEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+ManyTypes", + typeof(CompiledModelTestBase.ManyTypes), + baseEntityType, + propertyCount: 258, + keyCount: 1); + + var id = runtimeEntityType.AddProperty( + "Id", + typeof(CompiledModelTestBase.ManyTypesId), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Id", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueGenerated: ValueGenerated.OnAdd, + afterSaveBehavior: PropertySaveBehavior.Throw, + valueConverter: new CompiledModelTestBase.ManyTypesIdConverter()); + id.SetSentinelFromProviderValue(0); + + var @bool = runtimeEntityType.AddProperty( + "Bool", + typeof(bool), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Bool", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: false); + + var boolArray = runtimeEntityType.AddProperty( + "BoolArray", + typeof(bool[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BoolArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var boolNestedCollection = runtimeEntityType.AddProperty( + "BoolNestedCollection", + typeof(bool[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BoolNestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var boolToStringConverterProperty = runtimeEntityType.AddProperty( + "BoolToStringConverterProperty", + typeof(bool), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BoolToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + boolToStringConverterProperty.TypeMapping = InMemoryTypeMapping.Default.Clone( + comparer: new ValueComparer( + bool (bool v1, bool v2) => v1 == v2, + int (bool v) => ((object)v).GetHashCode(), + bool (bool v) => v), + keyComparer: new ValueComparer( + bool (bool v1, bool v2) => v1 == v2, + int (bool v) => ((object)v).GetHashCode(), + bool (bool v) => v), + providerValueComparer: new ValueComparer( + bool (string v1, string v2) => v1 == v2, + int (string v) => ((object)v).GetHashCode(), + string (string v) => v), + converter: new ValueConverter( + string (bool v) => ((string)((v ? "B" : "A"))), + bool (string v) => !(string.IsNullOrEmpty(v)) && ((int)(v.ToUpperInvariant()[0])) == ((int)("B".ToUpperInvariant()[0]))), + jsonValueReaderWriter: new JsonConvertedValueReaderWriter( + JsonStringReaderWriter.Instance, + new ValueConverter( + string (bool v) => ((string)((v ? "B" : "A"))), + bool (string v) => !(string.IsNullOrEmpty(v)) && ((int)(v.ToUpperInvariant()[0])) == ((int)("B".ToUpperInvariant()[0]))))); + boolToStringConverterProperty.SetSentinelFromProviderValue("A"); + + var boolToTwoValuesConverterProperty = runtimeEntityType.AddProperty( + "BoolToTwoValuesConverterProperty", + typeof(bool), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BoolToTwoValuesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + boolToTwoValuesConverterProperty.SetValueConverter(new ValueConverter( + byte (bool v) => ((byte)((v ? 1 : 0))), + bool (byte v) => v == 1)); + boolToTwoValuesConverterProperty.SetSentinelFromProviderValue((byte)0); + + var boolToZeroOneConverterProperty = runtimeEntityType.AddProperty( + "BoolToZeroOneConverterProperty", + typeof(bool), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BoolToZeroOneConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new BoolToZeroOneConverter()); + boolToZeroOneConverterProperty.SetSentinelFromProviderValue((short)0); + + var bytes = runtimeEntityType.AddProperty( + "Bytes", + typeof(byte[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Bytes", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var bytesArray = runtimeEntityType.AddProperty( + "BytesArray", + typeof(byte[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BytesArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var bytesNestedCollection = runtimeEntityType.AddProperty( + "BytesNestedCollection", + typeof(byte[][][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BytesNestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var bytesToStringConverterProperty = runtimeEntityType.AddProperty( + "BytesToStringConverterProperty", + typeof(byte[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BytesToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new BytesToStringConverter(), + valueComparer: new ArrayStructuralComparer()); + + var castingConverterProperty = runtimeEntityType.AddProperty( + "CastingConverterProperty", + typeof(int), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("CastingConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new CastingConverter()); + castingConverterProperty.SetSentinelFromProviderValue(0m); + + var @char = runtimeEntityType.AddProperty( + "Char", + typeof(char), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Char", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: '\0'); + + var charArray = runtimeEntityType.AddProperty( + "CharArray", + typeof(char[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("CharArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var charNestedCollection = runtimeEntityType.AddProperty( + "CharNestedCollection", + typeof(char[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("CharNestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var charToStringConverterProperty = runtimeEntityType.AddProperty( + "CharToStringConverterProperty", + typeof(char), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("CharToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new CharToStringConverter()); + charToStringConverterProperty.SetSentinelFromProviderValue("\0"); + + var dateOnly = runtimeEntityType.AddProperty( + "DateOnly", + typeof(DateOnly), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateOnly", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: new DateOnly(1, 1, 1)); + + var dateOnlyArray = runtimeEntityType.AddProperty( + "DateOnlyArray", + typeof(DateOnly[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateOnlyArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var dateOnlyToStringConverterProperty = runtimeEntityType.AddProperty( + "DateOnlyToStringConverterProperty", + typeof(DateOnly), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateOnlyToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new DateOnlyToStringConverter()); + dateOnlyToStringConverterProperty.SetSentinelFromProviderValue("0001-01-01"); + + var dateTime = runtimeEntityType.AddProperty( + "DateTime", + typeof(DateTime), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTime", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + var dateTimeArray = runtimeEntityType.AddProperty( + "DateTimeArray", + typeof(DateTime[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var dateTimeOffsetToBinaryConverterProperty = runtimeEntityType.AddProperty( + "DateTimeOffsetToBinaryConverterProperty", + typeof(DateTimeOffset), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeOffsetToBinaryConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new DateTimeOffsetToBinaryConverter()); + dateTimeOffsetToBinaryConverterProperty.SetSentinelFromProviderValue(0L); + + var dateTimeOffsetToBytesConverterProperty = runtimeEntityType.AddProperty( + "DateTimeOffsetToBytesConverterProperty", + typeof(DateTimeOffset), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeOffsetToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new DateTimeOffsetToBytesConverter()); + dateTimeOffsetToBytesConverterProperty.SetSentinelFromProviderValue(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }); + + var dateTimeOffsetToStringConverterProperty = runtimeEntityType.AddProperty( + "DateTimeOffsetToStringConverterProperty", + typeof(DateTimeOffset), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeOffsetToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new DateTimeOffsetToStringConverter()); + dateTimeOffsetToStringConverterProperty.SetSentinelFromProviderValue("0001-01-01 00:00:00+00:00"); + + var dateTimeToBinaryConverterProperty = runtimeEntityType.AddProperty( + "DateTimeToBinaryConverterProperty", + typeof(DateTime), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeToBinaryConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new DateTimeToBinaryConverter()); + dateTimeToBinaryConverterProperty.SetSentinelFromProviderValue(0L); + + var dateTimeToStringConverterProperty = runtimeEntityType.AddProperty( + "DateTimeToStringConverterProperty", + typeof(DateTime), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new DateTimeToStringConverter()); + dateTimeToStringConverterProperty.SetSentinelFromProviderValue("0001-01-01 00:00:00"); + + var dateTimeToTicksConverterProperty = runtimeEntityType.AddProperty( + "DateTimeToTicksConverterProperty", + typeof(DateTime), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeToTicksConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + var @decimal = runtimeEntityType.AddProperty( + "Decimal", + typeof(decimal), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Decimal", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0m); + + var decimalArray = runtimeEntityType.AddProperty( + "DecimalArray", + typeof(decimal[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DecimalArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var decimalNumberToBytesConverterProperty = runtimeEntityType.AddProperty( + "DecimalNumberToBytesConverterProperty", + typeof(decimal), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DecimalNumberToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new NumberToBytesConverter()); + decimalNumberToBytesConverterProperty.SetSentinelFromProviderValue(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }); + + var decimalNumberToStringConverterProperty = runtimeEntityType.AddProperty( + "DecimalNumberToStringConverterProperty", + typeof(decimal), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DecimalNumberToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new NumberToStringConverter()); + decimalNumberToStringConverterProperty.SetSentinelFromProviderValue("0"); + + var @double = runtimeEntityType.AddProperty( + "Double", + typeof(double), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Double", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0.0); + + var doubleArray = runtimeEntityType.AddProperty( + "DoubleArray", + typeof(double[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DoubleArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var doubleNumberToBytesConverterProperty = runtimeEntityType.AddProperty( + "DoubleNumberToBytesConverterProperty", + typeof(double), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DoubleNumberToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new NumberToBytesConverter()); + doubleNumberToBytesConverterProperty.SetSentinelFromProviderValue(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }); + + var doubleNumberToStringConverterProperty = runtimeEntityType.AddProperty( + "DoubleNumberToStringConverterProperty", + typeof(double), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DoubleNumberToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new NumberToStringConverter()); + doubleNumberToStringConverterProperty.SetSentinelFromProviderValue("0"); + + var enum16 = runtimeEntityType.AddProperty( + "Enum16", + typeof(CompiledModelTestBase.Enum16), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: CompiledModelTestBase.Enum16.Default); + + var enum16Array = runtimeEntityType.AddProperty( + "Enum16Array", + typeof(CompiledModelTestBase.Enum16[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum16AsString = runtimeEntityType.AddProperty( + "Enum16AsString", + typeof(CompiledModelTestBase.Enum16), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum16AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enum16AsString.SetSentinelFromProviderValue("Default"); + + var enum16AsStringArray = runtimeEntityType.AddProperty( + "Enum16AsStringArray", + typeof(CompiledModelTestBase.Enum16[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum16AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum16AsStringCollection = runtimeEntityType.AddProperty( + "Enum16AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum16AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum16Collection = runtimeEntityType.AddProperty( + "Enum16Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum16Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum32 = runtimeEntityType.AddProperty( + "Enum32", + typeof(CompiledModelTestBase.Enum32), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: CompiledModelTestBase.Enum32.Default); + + var enum32Array = runtimeEntityType.AddProperty( + "Enum32Array", + typeof(CompiledModelTestBase.Enum32[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum32AsString = runtimeEntityType.AddProperty( + "Enum32AsString", + typeof(CompiledModelTestBase.Enum32), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum32AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enum32AsString.SetSentinelFromProviderValue("Default"); + + var enum32AsStringArray = runtimeEntityType.AddProperty( + "Enum32AsStringArray", + typeof(CompiledModelTestBase.Enum32[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum32AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum32AsStringCollection = runtimeEntityType.AddProperty( + "Enum32AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum32AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum32Collection = runtimeEntityType.AddProperty( + "Enum32Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum32Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum32NestedCollection = runtimeEntityType.AddProperty( + "Enum32NestedCollection", + typeof(List[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum32NestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum64 = runtimeEntityType.AddProperty( + "Enum64", + typeof(CompiledModelTestBase.Enum64), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: CompiledModelTestBase.Enum64.Default); + + var enum64Array = runtimeEntityType.AddProperty( + "Enum64Array", + typeof(CompiledModelTestBase.Enum64[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum64AsString = runtimeEntityType.AddProperty( + "Enum64AsString", + typeof(CompiledModelTestBase.Enum64), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum64AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enum64AsString.SetSentinelFromProviderValue("Default"); + + var enum64AsStringArray = runtimeEntityType.AddProperty( + "Enum64AsStringArray", + typeof(CompiledModelTestBase.Enum64[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum64AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum64AsStringCollection = runtimeEntityType.AddProperty( + "Enum64AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum64AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum64Collection = runtimeEntityType.AddProperty( + "Enum64Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum64Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum8 = runtimeEntityType.AddProperty( + "Enum8", + typeof(CompiledModelTestBase.Enum8), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: CompiledModelTestBase.Enum8.Default); + + var enum8Array = runtimeEntityType.AddProperty( + "Enum8Array", + typeof(CompiledModelTestBase.Enum8[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum8AsString = runtimeEntityType.AddProperty( + "Enum8AsString", + typeof(CompiledModelTestBase.Enum8), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum8AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enum8AsString.SetSentinelFromProviderValue("Default"); + + var enum8AsStringArray = runtimeEntityType.AddProperty( + "Enum8AsStringArray", + typeof(CompiledModelTestBase.Enum8[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum8AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum8AsStringCollection = runtimeEntityType.AddProperty( + "Enum8AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum8AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum8Collection = runtimeEntityType.AddProperty( + "Enum8Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum8Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum8NestedCollection = runtimeEntityType.AddProperty( + "Enum8NestedCollection", + typeof(CompiledModelTestBase.Enum8[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum8NestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumToNumberConverterProperty = runtimeEntityType.AddProperty( + "EnumToNumberConverterProperty", + typeof(CompiledModelTestBase.Enum32), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumToNumberConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new EnumToNumberConverter()); + enumToNumberConverterProperty.SetSentinelFromProviderValue(0); + + var enumToStringConverterProperty = runtimeEntityType.AddProperty( + "EnumToStringConverterProperty", + typeof(CompiledModelTestBase.Enum32), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new EnumToStringConverter()); + enumToStringConverterProperty.SetSentinelFromProviderValue("Default"); + + var enumU16 = runtimeEntityType.AddProperty( + "EnumU16", + typeof(CompiledModelTestBase.EnumU16), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: CompiledModelTestBase.EnumU16.Min); + + var enumU16Array = runtimeEntityType.AddProperty( + "EnumU16Array", + typeof(CompiledModelTestBase.EnumU16[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU16AsString = runtimeEntityType.AddProperty( + "EnumU16AsString", + typeof(CompiledModelTestBase.EnumU16), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU16AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enumU16AsString.SetSentinelFromProviderValue("Min"); + + var enumU16AsStringArray = runtimeEntityType.AddProperty( + "EnumU16AsStringArray", + typeof(CompiledModelTestBase.EnumU16[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU16AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU16AsStringCollection = runtimeEntityType.AddProperty( + "EnumU16AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU16AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU16Collection = runtimeEntityType.AddProperty( + "EnumU16Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU16Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU32 = runtimeEntityType.AddProperty( + "EnumU32", + typeof(CompiledModelTestBase.EnumU32), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: CompiledModelTestBase.EnumU32.Min); + + var enumU32Array = runtimeEntityType.AddProperty( + "EnumU32Array", + typeof(CompiledModelTestBase.EnumU32[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU32AsString = runtimeEntityType.AddProperty( + "EnumU32AsString", + typeof(CompiledModelTestBase.EnumU32), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU32AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enumU32AsString.SetSentinelFromProviderValue("Min"); + + var enumU32AsStringArray = runtimeEntityType.AddProperty( + "EnumU32AsStringArray", + typeof(CompiledModelTestBase.EnumU32[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU32AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU32AsStringCollection = runtimeEntityType.AddProperty( + "EnumU32AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU32AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU32Collection = runtimeEntityType.AddProperty( + "EnumU32Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU32Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU64 = runtimeEntityType.AddProperty( + "EnumU64", + typeof(CompiledModelTestBase.EnumU64), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: CompiledModelTestBase.EnumU64.Min); + + var enumU64Array = runtimeEntityType.AddProperty( + "EnumU64Array", + typeof(CompiledModelTestBase.EnumU64[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU64AsString = runtimeEntityType.AddProperty( + "EnumU64AsString", + typeof(CompiledModelTestBase.EnumU64), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU64AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enumU64AsString.SetSentinelFromProviderValue("Min"); + + var enumU64AsStringArray = runtimeEntityType.AddProperty( + "EnumU64AsStringArray", + typeof(CompiledModelTestBase.EnumU64[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU64AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU64AsStringCollection = runtimeEntityType.AddProperty( + "EnumU64AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU64AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU64Collection = runtimeEntityType.AddProperty( + "EnumU64Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU64Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU64NestedCollection = runtimeEntityType.AddProperty( + "EnumU64NestedCollection", + typeof(CompiledModelTestBase.EnumU64[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU64NestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU8 = runtimeEntityType.AddProperty( + "EnumU8", + typeof(CompiledModelTestBase.EnumU8), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: CompiledModelTestBase.EnumU8.Min); + + var enumU8Array = runtimeEntityType.AddProperty( + "EnumU8Array", + typeof(CompiledModelTestBase.EnumU8[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU8AsString = runtimeEntityType.AddProperty( + "EnumU8AsString", + typeof(CompiledModelTestBase.EnumU8), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU8AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enumU8AsString.SetSentinelFromProviderValue("Min"); + + var enumU8AsStringArray = runtimeEntityType.AddProperty( + "EnumU8AsStringArray", + typeof(CompiledModelTestBase.EnumU8[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU8AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU8AsStringCollection = runtimeEntityType.AddProperty( + "EnumU8AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU8AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU8Collection = runtimeEntityType.AddProperty( + "EnumU8Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU8Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var @float = runtimeEntityType.AddProperty( + "Float", + typeof(float), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Float", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0f); + + var floatArray = runtimeEntityType.AddProperty( + "FloatArray", + typeof(float[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("FloatArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var guid = runtimeEntityType.AddProperty( + "Guid", + typeof(Guid), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Guid", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: new Guid("00000000-0000-0000-0000-000000000000")); + + var guidArray = runtimeEntityType.AddProperty( + "GuidArray", + typeof(Guid[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("GuidArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var guidNestedCollection = runtimeEntityType.AddProperty( + "GuidNestedCollection", + typeof(ICollection), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("GuidNestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var guidToBytesConverterProperty = runtimeEntityType.AddProperty( + "GuidToBytesConverterProperty", + typeof(Guid), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("GuidToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new GuidToBytesConverter()); + guidToBytesConverterProperty.SetSentinelFromProviderValue(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }); + + var guidToStringConverterProperty = runtimeEntityType.AddProperty( + "GuidToStringConverterProperty", + typeof(Guid), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("GuidToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new GuidToStringConverter()); + guidToStringConverterProperty.SetSentinelFromProviderValue("00000000-0000-0000-0000-000000000000"); + + var iPAddress = runtimeEntityType.AddProperty( + "IPAddress", + typeof(IPAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("IPAddress", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var iPAddressArray = runtimeEntityType.AddProperty( + "IPAddressArray", + typeof(IPAddress[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("IPAddressArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var iPAddressToBytesConverterProperty = runtimeEntityType.AddProperty( + "IPAddressToBytesConverterProperty", + typeof(IPAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("IPAddressToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new IPAddressToBytesConverter()); + + var iPAddressToStringConverterProperty = runtimeEntityType.AddProperty( + "IPAddressToStringConverterProperty", + typeof(IPAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("IPAddressToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new IPAddressToStringConverter()); + + var int16 = runtimeEntityType.AddProperty( + "Int16", + typeof(short), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: (short)0); + + var int16Array = runtimeEntityType.AddProperty( + "Int16Array", + typeof(short[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var int32 = runtimeEntityType.AddProperty( + "Int32", + typeof(int), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0); + + var int32Array = runtimeEntityType.AddProperty( + "Int32Array", + typeof(int[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var int32NestedCollection = runtimeEntityType.AddProperty( + "Int32NestedCollection", + typeof(int[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int32NestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var int64 = runtimeEntityType.AddProperty( + "Int64", + typeof(long), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0L); + + var int64Array = runtimeEntityType.AddProperty( + "Int64Array", + typeof(long[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var int64NestedCollection = runtimeEntityType.AddProperty( + "Int64NestedCollection", + typeof(IList[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int64NestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var int8 = runtimeEntityType.AddProperty( + "Int8", + typeof(sbyte), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: (sbyte)0); + + var int8Array = runtimeEntityType.AddProperty( + "Int8Array", + typeof(sbyte[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var int8NestedCollection = runtimeEntityType.AddProperty( + "Int8NestedCollection", + typeof(sbyte[][][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int8NestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var intNumberToBytesConverterProperty = runtimeEntityType.AddProperty( + "IntNumberToBytesConverterProperty", + typeof(int), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("IntNumberToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new NumberToBytesConverter()); + intNumberToBytesConverterProperty.SetSentinelFromProviderValue(new byte[] { 0, 0, 0, 0 }); + + var intNumberToStringConverterProperty = runtimeEntityType.AddProperty( + "IntNumberToStringConverterProperty", + typeof(int), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("IntNumberToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new NumberToStringConverter()); + intNumberToStringConverterProperty.SetSentinelFromProviderValue("0"); + + var nullIntToNullStringConverterProperty = runtimeEntityType.AddProperty( + "NullIntToNullStringConverterProperty", + typeof(int?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullIntToNullStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true, + valueConverter: new CompiledModelTestBase.NullIntToNullStringConverter()); + + var nullableBool = runtimeEntityType.AddProperty( + "NullableBool", + typeof(bool?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableBool", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableBoolArray = runtimeEntityType.AddProperty( + "NullableBoolArray", + typeof(bool?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableBoolArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableBytes = runtimeEntityType.AddProperty( + "NullableBytes", + typeof(byte[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableBytes", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableBytesArray = runtimeEntityType.AddProperty( + "NullableBytesArray", + typeof(byte[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableBytesArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableBytesNestedCollection = runtimeEntityType.AddProperty( + "NullableBytesNestedCollection", + typeof(byte[][][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableBytesNestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableChar = runtimeEntityType.AddProperty( + "NullableChar", + typeof(char?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableChar", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableCharArray = runtimeEntityType.AddProperty( + "NullableCharArray", + typeof(char?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableCharArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableDateOnly = runtimeEntityType.AddProperty( + "NullableDateOnly", + typeof(DateOnly?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDateOnly", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableDateOnlyArray = runtimeEntityType.AddProperty( + "NullableDateOnlyArray", + typeof(DateOnly?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDateOnlyArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableDateTime = runtimeEntityType.AddProperty( + "NullableDateTime", + typeof(DateTime?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDateTime", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableDateTimeArray = runtimeEntityType.AddProperty( + "NullableDateTimeArray", + typeof(DateTime?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDateTimeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableDecimal = runtimeEntityType.AddProperty( + "NullableDecimal", + typeof(decimal?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDecimal", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableDecimalArray = runtimeEntityType.AddProperty( + "NullableDecimalArray", + typeof(decimal?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDecimalArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableDouble = runtimeEntityType.AddProperty( + "NullableDouble", + typeof(double?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDouble", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableDoubleArray = runtimeEntityType.AddProperty( + "NullableDoubleArray", + typeof(double?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDoubleArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum16 = runtimeEntityType.AddProperty( + "NullableEnum16", + typeof(CompiledModelTestBase.Enum16?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnum16Array = runtimeEntityType.AddProperty( + "NullableEnum16Array", + typeof(CompiledModelTestBase.Enum16?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum16AsString = runtimeEntityType.AddProperty( + "NullableEnum16AsString", + typeof(CompiledModelTestBase.Enum16?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum16AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnum16AsStringArray = runtimeEntityType.AddProperty( + "NullableEnum16AsStringArray", + typeof(CompiledModelTestBase.Enum16?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum16AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum16AsStringCollection = runtimeEntityType.AddProperty( + "NullableEnum16AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum16AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum16Collection = runtimeEntityType.AddProperty( + "NullableEnum16Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum16Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum32 = runtimeEntityType.AddProperty( + "NullableEnum32", + typeof(CompiledModelTestBase.Enum32?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnum32Array = runtimeEntityType.AddProperty( + "NullableEnum32Array", + typeof(CompiledModelTestBase.Enum32?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum32AsString = runtimeEntityType.AddProperty( + "NullableEnum32AsString", + typeof(CompiledModelTestBase.Enum32?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum32AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnum32AsStringArray = runtimeEntityType.AddProperty( + "NullableEnum32AsStringArray", + typeof(CompiledModelTestBase.Enum32?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum32AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum32AsStringCollection = runtimeEntityType.AddProperty( + "NullableEnum32AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum32AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum32Collection = runtimeEntityType.AddProperty( + "NullableEnum32Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum32Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum32NestedCollection = runtimeEntityType.AddProperty( + "NullableEnum32NestedCollection", + typeof(CompiledModelTestBase.Enum32?[][][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum32NestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum64 = runtimeEntityType.AddProperty( + "NullableEnum64", + typeof(CompiledModelTestBase.Enum64?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnum64Array = runtimeEntityType.AddProperty( + "NullableEnum64Array", + typeof(CompiledModelTestBase.Enum64?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum64AsString = runtimeEntityType.AddProperty( + "NullableEnum64AsString", + typeof(CompiledModelTestBase.Enum64?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum64AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnum64AsStringArray = runtimeEntityType.AddProperty( + "NullableEnum64AsStringArray", + typeof(CompiledModelTestBase.Enum64?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum64AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum64AsStringCollection = runtimeEntityType.AddProperty( + "NullableEnum64AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum64AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum64Collection = runtimeEntityType.AddProperty( + "NullableEnum64Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum64Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum8 = runtimeEntityType.AddProperty( + "NullableEnum8", + typeof(CompiledModelTestBase.Enum8?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnum8Array = runtimeEntityType.AddProperty( + "NullableEnum8Array", + typeof(CompiledModelTestBase.Enum8?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum8AsString = runtimeEntityType.AddProperty( + "NullableEnum8AsString", + typeof(CompiledModelTestBase.Enum8?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum8AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnum8AsStringArray = runtimeEntityType.AddProperty( + "NullableEnum8AsStringArray", + typeof(CompiledModelTestBase.Enum8?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum8AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum8AsStringCollection = runtimeEntityType.AddProperty( + "NullableEnum8AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum8AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum8Collection = runtimeEntityType.AddProperty( + "NullableEnum8Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum8Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum8NestedCollection = runtimeEntityType.AddProperty( + "NullableEnum8NestedCollection", + typeof(CompiledModelTestBase.Enum8?[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum8NestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU16 = runtimeEntityType.AddProperty( + "NullableEnumU16", + typeof(CompiledModelTestBase.EnumU16?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnumU16Array = runtimeEntityType.AddProperty( + "NullableEnumU16Array", + typeof(CompiledModelTestBase.EnumU16?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU16AsString = runtimeEntityType.AddProperty( + "NullableEnumU16AsString", + typeof(CompiledModelTestBase.EnumU16?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU16AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnumU16AsStringArray = runtimeEntityType.AddProperty( + "NullableEnumU16AsStringArray", + typeof(CompiledModelTestBase.EnumU16?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU16AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU16AsStringCollection = runtimeEntityType.AddProperty( + "NullableEnumU16AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU16AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU16Collection = runtimeEntityType.AddProperty( + "NullableEnumU16Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU16Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU32 = runtimeEntityType.AddProperty( + "NullableEnumU32", + typeof(CompiledModelTestBase.EnumU32?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnumU32Array = runtimeEntityType.AddProperty( + "NullableEnumU32Array", + typeof(CompiledModelTestBase.EnumU32?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU32AsString = runtimeEntityType.AddProperty( + "NullableEnumU32AsString", + typeof(CompiledModelTestBase.EnumU32?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU32AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnumU32AsStringArray = runtimeEntityType.AddProperty( + "NullableEnumU32AsStringArray", + typeof(CompiledModelTestBase.EnumU32?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU32AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU32AsStringCollection = runtimeEntityType.AddProperty( + "NullableEnumU32AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU32AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU32Collection = runtimeEntityType.AddProperty( + "NullableEnumU32Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU32Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU64 = runtimeEntityType.AddProperty( + "NullableEnumU64", + typeof(CompiledModelTestBase.EnumU64?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnumU64Array = runtimeEntityType.AddProperty( + "NullableEnumU64Array", + typeof(CompiledModelTestBase.EnumU64?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU64AsString = runtimeEntityType.AddProperty( + "NullableEnumU64AsString", + typeof(CompiledModelTestBase.EnumU64?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU64AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnumU64AsStringArray = runtimeEntityType.AddProperty( + "NullableEnumU64AsStringArray", + typeof(CompiledModelTestBase.EnumU64?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU64AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU64AsStringCollection = runtimeEntityType.AddProperty( + "NullableEnumU64AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU64AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU64Collection = runtimeEntityType.AddProperty( + "NullableEnumU64Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU64Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU64NestedCollection = runtimeEntityType.AddProperty( + "NullableEnumU64NestedCollection", + typeof(CompiledModelTestBase.EnumU64?[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU64NestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU8 = runtimeEntityType.AddProperty( + "NullableEnumU8", + typeof(CompiledModelTestBase.EnumU8?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnumU8Array = runtimeEntityType.AddProperty( + "NullableEnumU8Array", + typeof(CompiledModelTestBase.EnumU8?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU8AsString = runtimeEntityType.AddProperty( + "NullableEnumU8AsString", + typeof(CompiledModelTestBase.EnumU8?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU8AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnumU8AsStringArray = runtimeEntityType.AddProperty( + "NullableEnumU8AsStringArray", + typeof(CompiledModelTestBase.EnumU8?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU8AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU8AsStringCollection = runtimeEntityType.AddProperty( + "NullableEnumU8AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU8AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU8Collection = runtimeEntityType.AddProperty( + "NullableEnumU8Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU8Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableFloat = runtimeEntityType.AddProperty( + "NullableFloat", + typeof(float?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableFloat", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableFloatArray = runtimeEntityType.AddProperty( + "NullableFloatArray", + typeof(float?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableFloatArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableGuid = runtimeEntityType.AddProperty( + "NullableGuid", + typeof(Guid?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableGuid", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableGuidArray = runtimeEntityType.AddProperty( + "NullableGuidArray", + typeof(Guid?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableGuidArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableGuidNestedCollection = runtimeEntityType.AddProperty( + "NullableGuidNestedCollection", + typeof(Guid?[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableGuidNestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableIPAddress = runtimeEntityType.AddProperty( + "NullableIPAddress", + typeof(IPAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableIPAddress", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableIPAddressArray = runtimeEntityType.AddProperty( + "NullableIPAddressArray", + typeof(IPAddress[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableIPAddressArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableInt16 = runtimeEntityType.AddProperty( + "NullableInt16", + typeof(short?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableInt16Array = runtimeEntityType.AddProperty( + "NullableInt16Array", + typeof(short?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableInt32 = runtimeEntityType.AddProperty( + "NullableInt32", + typeof(int?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableInt32Array = runtimeEntityType.AddProperty( + "NullableInt32Array", + typeof(int?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableInt32NestedCollection = runtimeEntityType.AddProperty( + "NullableInt32NestedCollection", + typeof(int?[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt32NestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableInt64 = runtimeEntityType.AddProperty( + "NullableInt64", + typeof(long?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableInt64Array = runtimeEntityType.AddProperty( + "NullableInt64Array", + typeof(long?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableInt64NestedCollection = runtimeEntityType.AddProperty( + "NullableInt64NestedCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt64NestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableInt8 = runtimeEntityType.AddProperty( + "NullableInt8", + typeof(sbyte?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableInt8Array = runtimeEntityType.AddProperty( + "NullableInt8Array", + typeof(sbyte?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullablePhysicalAddress = runtimeEntityType.AddProperty( + "NullablePhysicalAddress", + typeof(PhysicalAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullablePhysicalAddress", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullablePhysicalAddressArray = runtimeEntityType.AddProperty( + "NullablePhysicalAddressArray", + typeof(PhysicalAddress[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullablePhysicalAddressArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullablePhysicalAddressNestedCollection = runtimeEntityType.AddProperty( + "NullablePhysicalAddressNestedCollection", + typeof(IEnumerable), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullablePhysicalAddressNestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableString = runtimeEntityType.AddProperty( + "NullableString", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableStringArray = runtimeEntityType.AddProperty( + "NullableStringArray", + typeof(string[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableStringNestedCollection = runtimeEntityType.AddProperty( + "NullableStringNestedCollection", + typeof(string[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableStringNestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableTimeOnly = runtimeEntityType.AddProperty( + "NullableTimeOnly", + typeof(TimeOnly?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableTimeOnly", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableTimeOnlyArray = runtimeEntityType.AddProperty( + "NullableTimeOnlyArray", + typeof(TimeOnly?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableTimeOnlyArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableTimeSpan = runtimeEntityType.AddProperty( + "NullableTimeSpan", + typeof(TimeSpan?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableTimeSpan", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableTimeSpanArray = runtimeEntityType.AddProperty( + "NullableTimeSpanArray", + typeof(TimeSpan?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableTimeSpanArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableUInt16 = runtimeEntityType.AddProperty( + "NullableUInt16", + typeof(ushort?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableUInt16Array = runtimeEntityType.AddProperty( + "NullableUInt16Array", + typeof(ushort?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableUInt32 = runtimeEntityType.AddProperty( + "NullableUInt32", + typeof(uint?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableUInt32Array = runtimeEntityType.AddProperty( + "NullableUInt32Array", + typeof(uint?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableUInt64 = runtimeEntityType.AddProperty( + "NullableUInt64", + typeof(ulong?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableUInt64Array = runtimeEntityType.AddProperty( + "NullableUInt64Array", + typeof(ulong?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableUInt8 = runtimeEntityType.AddProperty( + "NullableUInt8", + typeof(byte?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableUInt8Array = runtimeEntityType.AddProperty( + "NullableUInt8Array", + typeof(byte?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableUInt8NestedCollection = runtimeEntityType.AddProperty( + "NullableUInt8NestedCollection", + typeof(byte?[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt8NestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableUri = runtimeEntityType.AddProperty( + "NullableUri", + typeof(Uri), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUri", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableUriArray = runtimeEntityType.AddProperty( + "NullableUriArray", + typeof(Uri[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUriArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var physicalAddress = runtimeEntityType.AddProperty( + "PhysicalAddress", + typeof(PhysicalAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("PhysicalAddress", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var physicalAddressArray = runtimeEntityType.AddProperty( + "PhysicalAddressArray", + typeof(PhysicalAddress[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("PhysicalAddressArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var physicalAddressToBytesConverterProperty = runtimeEntityType.AddProperty( + "PhysicalAddressToBytesConverterProperty", + typeof(PhysicalAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("PhysicalAddressToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new PhysicalAddressToBytesConverter()); + + var physicalAddressToStringConverterProperty = runtimeEntityType.AddProperty( + "PhysicalAddressToStringConverterProperty", + typeof(PhysicalAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("PhysicalAddressToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new PhysicalAddressToStringConverter()); + + var @string = runtimeEntityType.AddProperty( + "String", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("String", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var stringArray = runtimeEntityType.AddProperty( + "StringArray", + typeof(string[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var stringNestedCollection = runtimeEntityType.AddProperty( + "StringNestedCollection", + typeof(string[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringNestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var stringToBoolConverterProperty = runtimeEntityType.AddProperty( + "StringToBoolConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToBoolConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToBoolConverter()); + + var stringToBytesConverterProperty = runtimeEntityType.AddProperty( + "StringToBytesConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + stringToBytesConverterProperty.SetValueConverter(new ValueConverter( + byte[] (string v) => Encoding.GetEncoding(12000).GetBytes(v), + string (byte[] v) => Encoding.GetEncoding(12000).GetString(v))); + + var stringToCharConverterProperty = runtimeEntityType.AddProperty( + "StringToCharConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToCharConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToCharConverter()); + + var stringToDateOnlyConverterProperty = runtimeEntityType.AddProperty( + "StringToDateOnlyConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToDateOnlyConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToDateOnlyConverter()); + + var stringToDateTimeConverterProperty = runtimeEntityType.AddProperty( + "StringToDateTimeConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToDateTimeConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToDateTimeConverter()); + + var stringToDateTimeOffsetConverterProperty = runtimeEntityType.AddProperty( + "StringToDateTimeOffsetConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToDateTimeOffsetConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToDateTimeOffsetConverter()); + + var stringToDecimalNumberConverterProperty = runtimeEntityType.AddProperty( + "StringToDecimalNumberConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToDecimalNumberConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToNumberConverter()); + + var stringToDoubleNumberConverterProperty = runtimeEntityType.AddProperty( + "StringToDoubleNumberConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToDoubleNumberConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToNumberConverter()); + + var stringToEnumConverterProperty = runtimeEntityType.AddProperty( + "StringToEnumConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToEnumConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToEnumConverter()); + + var stringToGuidConverterProperty = runtimeEntityType.AddProperty( + "StringToGuidConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToGuidConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var stringToIntNumberConverterProperty = runtimeEntityType.AddProperty( + "StringToIntNumberConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToIntNumberConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToNumberConverter()); + + var stringToTimeOnlyConverterProperty = runtimeEntityType.AddProperty( + "StringToTimeOnlyConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToTimeOnlyConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToTimeOnlyConverter()); + + var stringToTimeSpanConverterProperty = runtimeEntityType.AddProperty( + "StringToTimeSpanConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToTimeSpanConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToTimeSpanConverter()); + + var stringToUriConverterProperty = runtimeEntityType.AddProperty( + "StringToUriConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToUriConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToUriConverter()); + + var timeOnly = runtimeEntityType.AddProperty( + "TimeOnly", + typeof(TimeOnly), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeOnly", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: new TimeOnly(0, 0, 0)); + + var timeOnlyArray = runtimeEntityType.AddProperty( + "TimeOnlyArray", + typeof(TimeOnly[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeOnlyArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var timeOnlyToStringConverterProperty = runtimeEntityType.AddProperty( + "TimeOnlyToStringConverterProperty", + typeof(TimeOnly), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeOnlyToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new TimeOnlyToStringConverter()); + timeOnlyToStringConverterProperty.SetSentinelFromProviderValue("00:00:00"); + + var timeOnlyToTicksConverterProperty = runtimeEntityType.AddProperty( + "TimeOnlyToTicksConverterProperty", + typeof(TimeOnly), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeOnlyToTicksConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new TimeOnlyToTicksConverter()); + timeOnlyToTicksConverterProperty.SetSentinelFromProviderValue(0L); + + var timeSpan = runtimeEntityType.AddProperty( + "TimeSpan", + typeof(TimeSpan), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeSpan", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: new TimeSpan(0, 0, 0, 0, 0)); + + var timeSpanArray = runtimeEntityType.AddProperty( + "TimeSpanArray", + typeof(TimeSpan[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeSpanArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var timeSpanToStringConverterProperty = runtimeEntityType.AddProperty( + "TimeSpanToStringConverterProperty", + typeof(TimeSpan), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeSpanToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new TimeSpanToStringConverter()); + timeSpanToStringConverterProperty.SetSentinelFromProviderValue("00:00:00"); + + var timeSpanToTicksConverterProperty = runtimeEntityType.AddProperty( + "TimeSpanToTicksConverterProperty", + typeof(TimeSpan), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeSpanToTicksConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new TimeSpanToTicksConverter()); + timeSpanToTicksConverterProperty.SetSentinelFromProviderValue(0L); + + var uInt16 = runtimeEntityType.AddProperty( + "UInt16", + typeof(ushort), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: (ushort)0); + + var uInt16Array = runtimeEntityType.AddProperty( + "UInt16Array", + typeof(ushort[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var uInt32 = runtimeEntityType.AddProperty( + "UInt32", + typeof(uint), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0u); + + var uInt32Array = runtimeEntityType.AddProperty( + "UInt32Array", + typeof(uint[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var uInt64 = runtimeEntityType.AddProperty( + "UInt64", + typeof(ulong), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0ul); + + var uInt64Array = runtimeEntityType.AddProperty( + "UInt64Array", + typeof(ulong[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var uInt8 = runtimeEntityType.AddProperty( + "UInt8", + typeof(byte), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: (byte)0); + + var uInt8Array = runtimeEntityType.AddProperty( + "UInt8Array", + typeof(byte[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var uInt8NestedCollection = runtimeEntityType.AddProperty( + "UInt8NestedCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt8NestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var uri = runtimeEntityType.AddProperty( + "Uri", + typeof(Uri), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Uri", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var uriArray = runtimeEntityType.AddProperty( + "UriArray", + typeof(Uri[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UriArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var uriToStringConverterProperty = runtimeEntityType.AddProperty( + "UriToStringConverterProperty", + typeof(Uri), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UriToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new UriToStringConverter()); + + var key = runtimeEntityType.AddKey( + new[] { id }); + runtimeEntityType.SetPrimaryKey(key); + + return runtimeEntityType; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedType0EntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedType0EntityType.cs new file mode 100644 index 00000000000..ba5cdffb308 --- /dev/null +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedType0EntityType.cs @@ -0,0 +1,159 @@ +// +using System; +using System.Collections.Generic; +using System.Net; +using System.Reflection; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class OwnedType0EntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalDerived>.ManyOwned#OwnedType", + typeof(CompiledModelTestBase.OwnedType), + baseEntityType, + sharedClrType: true, + propertyCount: 13, + servicePropertyCount: 1, + foreignKeyCount: 1, + keyCount: 1); + + var principalDerivedId = runtimeEntityType.AddProperty( + "PrincipalDerivedId", + typeof(long), + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: 0L); + + var principalDerivedAlternateId = runtimeEntityType.AddProperty( + "PrincipalDerivedAlternateId", + typeof(Guid), + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: new Guid("00000000-0000-0000-0000-000000000000")); + + var id = runtimeEntityType.AddProperty( + "Id", + typeof(int), + valueGenerated: ValueGenerated.OnAdd, + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: 0); + + var details = runtimeEntityType.AddProperty( + "Details", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("Details", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_details", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var number = runtimeEntityType.AddProperty( + "Number", + typeof(int), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("Number", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0); + + var refTypeArray = runtimeEntityType.AddProperty( + "RefTypeArray", + typeof(IPAddress[]), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeArray", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var refTypeEnumerable = runtimeEntityType.AddProperty( + "RefTypeEnumerable", + typeof(IEnumerable), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeEnumerable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeEnumerable", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var refTypeIList = runtimeEntityType.AddProperty( + "RefTypeIList", + typeof(IList), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeIList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeIList", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var refTypeList = runtimeEntityType.AddProperty( + "RefTypeList", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeList", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var valueTypeArray = runtimeEntityType.AddProperty( + "ValueTypeArray", + typeof(DateTime[]), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_valueTypeArray", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var valueTypeEnumerable = runtimeEntityType.AddProperty( + "ValueTypeEnumerable", + typeof(IEnumerable), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeEnumerable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_valueTypeEnumerable", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var valueTypeIList = runtimeEntityType.AddProperty( + "ValueTypeIList", + typeof(IList), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeIList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var valueTypeList = runtimeEntityType.AddProperty( + "ValueTypeList", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_valueTypeList", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var context = runtimeEntityType.AddServiceProperty( + "Context", + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("Context", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + serviceType: typeof(DbContext)); + + var key = runtimeEntityType.AddKey( + new[] { principalDerivedId, principalDerivedAlternateId, id }); + runtimeEntityType.SetPrimaryKey(key); + + return runtimeEntityType; + } + + public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("PrincipalDerivedId"), declaringEntityType.FindProperty("PrincipalDerivedAlternateId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("Id"), principalEntityType.FindProperty("AlternateId") }), + principalEntityType, + deleteBehavior: DeleteBehavior.Cascade, + required: true, + ownership: true); + + var manyOwned = principalEntityType.AddNavigation("ManyOwned", + runtimeForeignKey, + onDependent: false, + typeof(ICollection), + fieldInfo: typeof(CompiledModelTestBase.PrincipalDerived>).GetField("ManyOwned", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + eagerLoaded: true); + + return runtimeForeignKey; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedTypeEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedTypeEntityType.cs new file mode 100644 index 00000000000..1734e6dc9b1 --- /dev/null +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedTypeEntityType.cs @@ -0,0 +1,169 @@ +// +using System; +using System.Collections.Generic; +using System.Net; +using System.Reflection; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class OwnedTypeEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalBase.Owned#OwnedType", + typeof(CompiledModelTestBase.OwnedType), + baseEntityType, + sharedClrType: true, + changeTrackingStrategy: ChangeTrackingStrategy.ChangingAndChangedNotificationsWithOriginalValues, + propertyCount: 12, + servicePropertyCount: 1, + foreignKeyCount: 1, + keyCount: 1); + + var principalBaseId = runtimeEntityType.AddProperty( + "PrincipalBaseId", + typeof(long), + propertyAccessMode: PropertyAccessMode.Field, + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: 0L); + + var principalBaseAlternateId = runtimeEntityType.AddProperty( + "PrincipalBaseAlternateId", + typeof(Guid), + propertyAccessMode: PropertyAccessMode.Field, + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: new Guid("00000000-0000-0000-0000-000000000000")); + + var details = runtimeEntityType.AddProperty( + "Details", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("Details", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_details", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var number = runtimeEntityType.AddProperty( + "Number", + typeof(int), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("Number", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + sentinel: 0); + + var refTypeArray = runtimeEntityType.AddProperty( + "RefTypeArray", + typeof(IPAddress[]), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeArray", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var refTypeEnumerable = runtimeEntityType.AddProperty( + "RefTypeEnumerable", + typeof(IEnumerable), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeEnumerable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeEnumerable", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var refTypeIList = runtimeEntityType.AddProperty( + "RefTypeIList", + typeof(IList), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeIList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeIList", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var refTypeList = runtimeEntityType.AddProperty( + "RefTypeList", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeList", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var valueTypeArray = runtimeEntityType.AddProperty( + "ValueTypeArray", + typeof(DateTime[]), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_valueTypeArray", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var valueTypeEnumerable = runtimeEntityType.AddProperty( + "ValueTypeEnumerable", + typeof(IEnumerable), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeEnumerable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_valueTypeEnumerable", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var valueTypeIList = runtimeEntityType.AddProperty( + "ValueTypeIList", + typeof(IList), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeIList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var valueTypeList = runtimeEntityType.AddProperty( + "ValueTypeList", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_valueTypeList", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var context = runtimeEntityType.AddServiceProperty( + "Context", + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("Context", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + serviceType: typeof(DbContext)); + + var key = runtimeEntityType.AddKey( + new[] { principalBaseId, principalBaseAlternateId }); + runtimeEntityType.SetPrimaryKey(key); + + return runtimeEntityType; + } + + public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("PrincipalBaseId"), declaringEntityType.FindProperty("PrincipalBaseAlternateId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("Id"), principalEntityType.FindProperty("AlternateId") }), + principalEntityType, + deleteBehavior: DeleteBehavior.Cascade, + unique: true, + required: true, + requiredDependent: true, + ownership: true); + + var owned = principalEntityType.AddNavigation("Owned", + runtimeForeignKey, + onDependent: false, + typeof(CompiledModelTestBase.OwnedType), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("Owned", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("_ownedField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + eagerLoaded: true); + + return runtimeForeignKey; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBaseEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBaseEntityType.cs new file mode 100644 index 00000000000..f732733bf07 --- /dev/null +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBaseEntityType.cs @@ -0,0 +1,185 @@ +// +using System; +using System.Collections.Generic; +using System.Net; +using System.Reflection; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; +using Microsoft.EntityFrameworkCore.Storage.Json; +using Microsoft.EntityFrameworkCore.ValueGeneration; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class PrincipalBaseEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalBase", + typeof(CompiledModelTestBase.PrincipalBase), + baseEntityType, + discriminatorProperty: "Discriminator", + discriminatorValue: "PrincipalBase", + derivedTypesCount: 1, + propertyCount: 15, + navigationCount: 1, + skipNavigationCount: 1, + keyCount: 2); + + var id = runtimeEntityType.AddProperty( + "Id", + typeof(long?), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("Id", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + afterSaveBehavior: PropertySaveBehavior.Throw); + + var alternateId = runtimeEntityType.AddProperty( + "AlternateId", + typeof(Guid), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("AlternateId", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.FieldDuringConstruction, + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: new Guid("00000000-0000-0000-0000-000000000000"), + jsonValueReaderWriter: JsonGuidReaderWriter.Instance); + + var discriminator = runtimeEntityType.AddProperty( + "Discriminator", + typeof(string), + afterSaveBehavior: PropertySaveBehavior.Throw, + valueGeneratorFactory: new DiscriminatorValueGeneratorFactory().Create); + + var enum1 = runtimeEntityType.AddProperty( + "Enum1", + typeof(CompiledModelTestBase.AnEnum), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("Enum1", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: (CompiledModelTestBase.AnEnum)0); + + var enum2 = runtimeEntityType.AddProperty( + "Enum2", + typeof(CompiledModelTestBase.AnEnum?), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("Enum2", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var flagsEnum1 = runtimeEntityType.AddProperty( + "FlagsEnum1", + typeof(CompiledModelTestBase.AFlagsEnum), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("FlagsEnum1", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: (CompiledModelTestBase.AFlagsEnum)0); + + var flagsEnum2 = runtimeEntityType.AddProperty( + "FlagsEnum2", + typeof(CompiledModelTestBase.AFlagsEnum), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("FlagsEnum2", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Property, + sentinel: CompiledModelTestBase.AFlagsEnum.B | CompiledModelTestBase.AFlagsEnum.C); + + var refTypeArray = runtimeEntityType.AddProperty( + "RefTypeArray", + typeof(IPAddress[]), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("RefTypeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var refTypeEnumerable = runtimeEntityType.AddProperty( + "RefTypeEnumerable", + typeof(IEnumerable), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("RefTypeEnumerable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var refTypeIList = runtimeEntityType.AddProperty( + "RefTypeIList", + typeof(IList), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("RefTypeIList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var refTypeList = runtimeEntityType.AddProperty( + "RefTypeList", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("RefTypeList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var valueTypeArray = runtimeEntityType.AddProperty( + "ValueTypeArray", + typeof(DateTime[]), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("ValueTypeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var valueTypeEnumerable = runtimeEntityType.AddProperty( + "ValueTypeEnumerable", + typeof(IEnumerable), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("ValueTypeEnumerable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var valueTypeIList = runtimeEntityType.AddProperty( + "ValueTypeIList", + typeof(IList), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("ValueTypeIList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var valueTypeList = runtimeEntityType.AddProperty( + "ValueTypeList", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("ValueTypeList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var key = runtimeEntityType.AddKey( + new[] { id }); + + var key0 = runtimeEntityType.AddKey( + new[] { id, alternateId }); + runtimeEntityType.SetPrimaryKey(key0); + + return runtimeEntityType; + } + + public static RuntimeSkipNavigation CreateSkipNavigation1(RuntimeEntityType declaringEntityType, RuntimeEntityType targetEntityType, RuntimeEntityType joinEntityType) + { + var skipNavigation = declaringEntityType.AddSkipNavigation( + "Deriveds", + targetEntityType, + joinEntityType.FindForeignKey( + new[] { joinEntityType.FindProperty("PrincipalsId"), joinEntityType.FindProperty("PrincipalsAlternateId") }, + declaringEntityType.FindKey(new[] { declaringEntityType.FindProperty("Id"), declaringEntityType.FindProperty("AlternateId") }), + declaringEntityType), + true, + false, + typeof(ICollection), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("Deriveds", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var inverse = targetEntityType.FindSkipNavigation("Principals"); + if (inverse != null) + { + skipNavigation.Inverse = inverse; + inverse.Inverse = skipNavigation; + } + + return skipNavigation; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs new file mode 100644 index 00000000000..2fe1d6cd30b --- /dev/null +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs @@ -0,0 +1,97 @@ +// +using System; +using System.Collections.Generic; +using System.Reflection; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class PrincipalBasePrincipalDerivedDependentBasebyteEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "PrincipalBasePrincipalDerived>", + typeof(Dictionary), + baseEntityType, + sharedClrType: true, + indexerPropertyInfo: RuntimeEntityType.FindIndexerProperty(typeof(Dictionary)), + propertyBag: true, + propertyCount: 5, + foreignKeyCount: 2, + keyCount: 1); + + var derivedsId = runtimeEntityType.AddProperty( + "DerivedsId", + typeof(long), + propertyInfo: runtimeEntityType.FindIndexerPropertyInfo(), + afterSaveBehavior: PropertySaveBehavior.Throw); + + var derivedsAlternateId = runtimeEntityType.AddProperty( + "DerivedsAlternateId", + typeof(Guid), + propertyInfo: runtimeEntityType.FindIndexerPropertyInfo(), + afterSaveBehavior: PropertySaveBehavior.Throw); + + var principalsId = runtimeEntityType.AddProperty( + "PrincipalsId", + typeof(long), + propertyInfo: runtimeEntityType.FindIndexerPropertyInfo(), + afterSaveBehavior: PropertySaveBehavior.Throw); + + var principalsAlternateId = runtimeEntityType.AddProperty( + "PrincipalsAlternateId", + typeof(Guid), + propertyInfo: runtimeEntityType.FindIndexerPropertyInfo(), + afterSaveBehavior: PropertySaveBehavior.Throw); + + var rowid = runtimeEntityType.AddProperty( + "rowid", + typeof(byte[]), + propertyInfo: runtimeEntityType.FindIndexerPropertyInfo(), + nullable: true); + + var key = runtimeEntityType.AddKey( + new[] { derivedsId, derivedsAlternateId, principalsId, principalsAlternateId }); + runtimeEntityType.SetPrimaryKey(key); + + return runtimeEntityType; + } + + public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("DerivedsId"), declaringEntityType.FindProperty("DerivedsAlternateId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("Id"), principalEntityType.FindProperty("AlternateId") }), + principalEntityType, + deleteBehavior: DeleteBehavior.Cascade, + required: true); + + return runtimeForeignKey; + } + + public static RuntimeForeignKey CreateForeignKey2(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("PrincipalsId"), declaringEntityType.FindProperty("PrincipalsAlternateId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("Id"), principalEntityType.FindProperty("AlternateId") }), + principalEntityType, + deleteBehavior: DeleteBehavior.Cascade, + required: true); + + return runtimeForeignKey; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalDerivedEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalDerivedEntityType.cs new file mode 100644 index 00000000000..b366bffcd95 --- /dev/null +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalDerivedEntityType.cs @@ -0,0 +1,65 @@ +// +using System; +using System.Collections.Generic; +using System.Reflection; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class PrincipalDerivedEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalDerived>", + typeof(CompiledModelTestBase.PrincipalDerived>), + baseEntityType, + discriminatorProperty: "Discriminator", + discriminatorValue: "PrincipalDerived>", + propertyCount: 0, + navigationCount: 2, + skipNavigationCount: 1); + + return runtimeEntityType; + } + + public static RuntimeSkipNavigation CreateSkipNavigation1(RuntimeEntityType declaringEntityType, RuntimeEntityType targetEntityType, RuntimeEntityType joinEntityType) + { + var skipNavigation = declaringEntityType.AddSkipNavigation( + "Principals", + targetEntityType, + joinEntityType.FindForeignKey( + new[] { joinEntityType.FindProperty("DerivedsId"), joinEntityType.FindProperty("DerivedsAlternateId") }, + declaringEntityType.FindKey(new[] { declaringEntityType.FindProperty("Id"), declaringEntityType.FindProperty("AlternateId") }), + declaringEntityType), + true, + false, + typeof(ICollection), + propertyInfo: typeof(CompiledModelTestBase.PrincipalDerived>).GetProperty("Principals", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalDerived>).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var inverse = targetEntityType.FindSkipNavigation("Deriveds"); + if (inverse != null) + { + skipNavigation.Inverse = inverse; + inverse.Inverse = skipNavigation; + } + + return skipNavigation; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalBaseEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalBaseEntityType.cs index 0b09acd4b1a..9d059fbdb99 100644 --- a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalBaseEntityType.cs +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalBaseEntityType.cs @@ -82,9 +82,9 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas long (long v) => v), clrType: typeof(long), jsonValueReaderWriter: JsonInt64ReaderWriter.Instance); - id.SetValueComparer(new NullableValueComparer(id.TypeMapping.Comparer)); - id.SetKeyValueComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); id.SetCurrentValueComparer(new EntryCurrentValueComparer(id)); + id.SetComparer(new NullableValueComparer(id.TypeMapping.Comparer)); + id.SetKeyComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); var discriminator = runtimeEntityType.AddProperty( "Discriminator", @@ -204,8 +204,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas CompiledModelTestBase.AnEnum (CompiledModelTestBase.AnEnum v) => v), clrType: typeof(CompiledModelTestBase.AnEnum), jsonValueReaderWriter: JsonSignedEnumReaderWriter.Instance); - enum2.SetValueComparer(new NullableValueComparer(enum2.TypeMapping.Comparer)); - enum2.SetKeyValueComparer(new NullableValueComparer(enum2.TypeMapping.KeyComparer)); + enum2.SetComparer(new NullableValueComparer(enum2.TypeMapping.Comparer)); + enum2.SetKeyComparer(new NullableValueComparer(enum2.TypeMapping.KeyComparer)); var flagsEnum1 = runtimeEntityType.AddProperty( "FlagsEnum1", @@ -324,9 +324,9 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas long (long v) => v), clrType: typeof(long), jsonValueReaderWriter: JsonInt64ReaderWriter.Instance); - principalBaseId.SetValueComparer(new NullableValueComparer(principalBaseId.TypeMapping.Comparer)); - principalBaseId.SetKeyValueComparer(new NullableValueComparer(principalBaseId.TypeMapping.KeyComparer)); principalBaseId.SetCurrentValueComparer(new EntryCurrentValueComparer(principalBaseId)); + principalBaseId.SetComparer(new NullableValueComparer(principalBaseId.TypeMapping.Comparer)); + principalBaseId.SetKeyComparer(new NullableValueComparer(principalBaseId.TypeMapping.KeyComparer)); var refTypeArray = runtimeEntityType.AddProperty( "RefTypeArray", @@ -1767,8 +1767,8 @@ public static RuntimeComplexProperty Create(RuntimeComplexType declaringType) CompiledModelTestBase.AnEnum (CompiledModelTestBase.AnEnum v) => v), clrType: typeof(CompiledModelTestBase.AnEnum), jsonValueReaderWriter: JsonSignedEnumReaderWriter.Instance); - enum2.SetValueComparer(new NullableValueComparer(enum2.TypeMapping.Comparer)); - enum2.SetKeyValueComparer(new NullableValueComparer(enum2.TypeMapping.KeyComparer)); + enum2.SetComparer(new NullableValueComparer(enum2.TypeMapping.Comparer)); + enum2.SetKeyComparer(new NullableValueComparer(enum2.TypeMapping.KeyComparer)); var flagsEnum1 = complexType.AddProperty( "FlagsEnum1", @@ -1928,8 +1928,8 @@ public static RuntimeComplexProperty Create(RuntimeComplexType declaringType) long (long v) => v), clrType: typeof(long), jsonValueReaderWriter: JsonInt64ReaderWriter.Instance); - id.SetValueComparer(new NullableValueComparer(id.TypeMapping.Comparer)); - id.SetKeyValueComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); + id.SetComparer(new NullableValueComparer(id.TypeMapping.Comparer)); + id.SetKeyComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); var refTypeArray = complexType.AddProperty( "RefTypeArray", @@ -2569,53 +2569,53 @@ public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEnt public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var discriminator = runtimeEntityType.FindProperty("Discriminator")!; - var enum1 = runtimeEntityType.FindProperty("Enum1")!; - var enum2 = runtimeEntityType.FindProperty("Enum2")!; - var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1")!; - var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2")!; - var principalBaseId = runtimeEntityType.FindProperty("PrincipalBaseId")!; - var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray")!; - var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable")!; - var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList")!; - var refTypeList = runtimeEntityType.FindProperty("RefTypeList")!; - var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList")!; - var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList")!; - var owned = runtimeEntityType.FindComplexProperty("Owned")!; + var id = runtimeEntityType.FindProperty("Id"); + var discriminator = runtimeEntityType.FindProperty("Discriminator"); + var enum1 = runtimeEntityType.FindProperty("Enum1"); + var enum2 = runtimeEntityType.FindProperty("Enum2"); + var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1"); + var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2"); + var principalBaseId = runtimeEntityType.FindProperty("PrincipalBaseId"); + var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray"); + var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable"); + var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList"); + var refTypeList = runtimeEntityType.FindProperty("RefTypeList"); + var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList"); + var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList"); + var owned = runtimeEntityType.FindComplexProperty("Owned"); var ownedType = owned.ComplexType; - var details = ownedType.FindProperty("Details")!; - var number = ownedType.FindProperty("Number")!; - var refTypeArray0 = ownedType.FindProperty("RefTypeArray")!; - var refTypeEnumerable0 = ownedType.FindProperty("RefTypeEnumerable")!; - var refTypeIList0 = ownedType.FindProperty("RefTypeIList")!; - var refTypeList0 = ownedType.FindProperty("RefTypeList")!; - var valueTypeArray0 = ownedType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable0 = ownedType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList0 = ownedType.FindProperty("ValueTypeIList")!; - var valueTypeList0 = ownedType.FindProperty("ValueTypeList")!; - var principal = ownedType.FindComplexProperty("Principal")!; + var details = ownedType.FindProperty("Details"); + var number = ownedType.FindProperty("Number"); + var refTypeArray0 = ownedType.FindProperty("RefTypeArray"); + var refTypeEnumerable0 = ownedType.FindProperty("RefTypeEnumerable"); + var refTypeIList0 = ownedType.FindProperty("RefTypeIList"); + var refTypeList0 = ownedType.FindProperty("RefTypeList"); + var valueTypeArray0 = ownedType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable0 = ownedType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList0 = ownedType.FindProperty("ValueTypeIList"); + var valueTypeList0 = ownedType.FindProperty("ValueTypeList"); + var principal = ownedType.FindComplexProperty("Principal"); var principalBase = principal.ComplexType; - var alternateId = principalBase.FindProperty("AlternateId")!; - var enum10 = principalBase.FindProperty("Enum1")!; - var enum20 = principalBase.FindProperty("Enum2")!; - var flagsEnum10 = principalBase.FindProperty("FlagsEnum1")!; - var flagsEnum20 = principalBase.FindProperty("FlagsEnum2")!; - var id0 = principalBase.FindProperty("Id")!; - var refTypeArray1 = principalBase.FindProperty("RefTypeArray")!; - var refTypeEnumerable1 = principalBase.FindProperty("RefTypeEnumerable")!; - var refTypeIList1 = principalBase.FindProperty("RefTypeIList")!; - var refTypeList1 = principalBase.FindProperty("RefTypeList")!; - var valueTypeArray1 = principalBase.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable1 = principalBase.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList1 = principalBase.FindProperty("ValueTypeIList")!; - var valueTypeList1 = principalBase.FindProperty("ValueTypeList")!; + var alternateId = principalBase.FindProperty("AlternateId"); + var enum10 = principalBase.FindProperty("Enum1"); + var enum20 = principalBase.FindProperty("Enum2"); + var flagsEnum10 = principalBase.FindProperty("FlagsEnum1"); + var flagsEnum20 = principalBase.FindProperty("FlagsEnum2"); + var id0 = principalBase.FindProperty("Id"); + var refTypeArray1 = principalBase.FindProperty("RefTypeArray"); + var refTypeEnumerable1 = principalBase.FindProperty("RefTypeEnumerable"); + var refTypeIList1 = principalBase.FindProperty("RefTypeIList"); + var refTypeList1 = principalBase.FindProperty("RefTypeList"); + var valueTypeArray1 = principalBase.FindProperty("ValueTypeArray"); + var valueTypeEnumerable1 = principalBase.FindProperty("ValueTypeEnumerable"); + var valueTypeIList1 = principalBase.FindProperty("ValueTypeIList"); + var valueTypeList1 = principalBase.FindProperty("ValueTypeList"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); - var deriveds = runtimeEntityType.FindNavigation("Deriveds")!; + var deriveds = runtimeEntityType.FindNavigation("Deriveds"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalDerivedEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalDerivedEntityType.cs index 67fb300f589..3bedaad32cb 100644 --- a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalDerivedEntityType.cs +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalDerivedEntityType.cs @@ -33,50 +33,50 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var discriminator = runtimeEntityType.FindProperty("Discriminator")!; - var enum1 = runtimeEntityType.FindProperty("Enum1")!; - var enum2 = runtimeEntityType.FindProperty("Enum2")!; - var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1")!; - var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2")!; - var principalBaseId = runtimeEntityType.FindProperty("PrincipalBaseId")!; - var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray")!; - var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable")!; - var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList")!; - var refTypeList = runtimeEntityType.FindProperty("RefTypeList")!; - var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList")!; - var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList")!; - var owned = runtimeEntityType.FindComplexProperty("Owned")!; + var id = runtimeEntityType.FindProperty("Id"); + var discriminator = runtimeEntityType.FindProperty("Discriminator"); + var enum1 = runtimeEntityType.FindProperty("Enum1"); + var enum2 = runtimeEntityType.FindProperty("Enum2"); + var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1"); + var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2"); + var principalBaseId = runtimeEntityType.FindProperty("PrincipalBaseId"); + var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray"); + var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable"); + var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList"); + var refTypeList = runtimeEntityType.FindProperty("RefTypeList"); + var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList"); + var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList"); + var owned = runtimeEntityType.FindComplexProperty("Owned"); var ownedType = owned.ComplexType; - var details = ownedType.FindProperty("Details")!; - var number = ownedType.FindProperty("Number")!; - var refTypeArray0 = ownedType.FindProperty("RefTypeArray")!; - var refTypeEnumerable0 = ownedType.FindProperty("RefTypeEnumerable")!; - var refTypeIList0 = ownedType.FindProperty("RefTypeIList")!; - var refTypeList0 = ownedType.FindProperty("RefTypeList")!; - var valueTypeArray0 = ownedType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable0 = ownedType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList0 = ownedType.FindProperty("ValueTypeIList")!; - var valueTypeList0 = ownedType.FindProperty("ValueTypeList")!; - var principal = ownedType.FindComplexProperty("Principal")!; + var details = ownedType.FindProperty("Details"); + var number = ownedType.FindProperty("Number"); + var refTypeArray0 = ownedType.FindProperty("RefTypeArray"); + var refTypeEnumerable0 = ownedType.FindProperty("RefTypeEnumerable"); + var refTypeIList0 = ownedType.FindProperty("RefTypeIList"); + var refTypeList0 = ownedType.FindProperty("RefTypeList"); + var valueTypeArray0 = ownedType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable0 = ownedType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList0 = ownedType.FindProperty("ValueTypeIList"); + var valueTypeList0 = ownedType.FindProperty("ValueTypeList"); + var principal = ownedType.FindComplexProperty("Principal"); var principalBase = principal.ComplexType; - var alternateId = principalBase.FindProperty("AlternateId")!; - var enum10 = principalBase.FindProperty("Enum1")!; - var enum20 = principalBase.FindProperty("Enum2")!; - var flagsEnum10 = principalBase.FindProperty("FlagsEnum1")!; - var flagsEnum20 = principalBase.FindProperty("FlagsEnum2")!; - var id0 = principalBase.FindProperty("Id")!; - var refTypeArray1 = principalBase.FindProperty("RefTypeArray")!; - var refTypeEnumerable1 = principalBase.FindProperty("RefTypeEnumerable")!; - var refTypeIList1 = principalBase.FindProperty("RefTypeIList")!; - var refTypeList1 = principalBase.FindProperty("RefTypeList")!; - var valueTypeArray1 = principalBase.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable1 = principalBase.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList1 = principalBase.FindProperty("ValueTypeIList")!; - var valueTypeList1 = principalBase.FindProperty("ValueTypeList")!; - var deriveds = runtimeEntityType.FindNavigation("Deriveds")!; + var alternateId = principalBase.FindProperty("AlternateId"); + var enum10 = principalBase.FindProperty("Enum1"); + var enum20 = principalBase.FindProperty("Enum2"); + var flagsEnum10 = principalBase.FindProperty("FlagsEnum1"); + var flagsEnum20 = principalBase.FindProperty("FlagsEnum2"); + var id0 = principalBase.FindProperty("Id"); + var refTypeArray1 = principalBase.FindProperty("RefTypeArray"); + var refTypeEnumerable1 = principalBase.FindProperty("RefTypeEnumerable"); + var refTypeIList1 = principalBase.FindProperty("RefTypeIList"); + var refTypeList1 = principalBase.FindProperty("RefTypeList"); + var valueTypeArray1 = principalBase.FindProperty("ValueTypeArray"); + var valueTypeEnumerable1 = principalBase.FindProperty("ValueTypeEnumerable"); + var valueTypeIList1 = principalBase.FindProperty("ValueTypeIList"); + var valueTypeList1 = principalBase.FindProperty("ValueTypeList"); + var deriveds = runtimeEntityType.FindNavigation("Deriveds"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Custom_provider_value_comparer/MyEntityEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Custom_provider_value_comparer/MyEntityEntityType.cs index c59e42e3f69..d38f245caff 100644 --- a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Custom_provider_value_comparer/MyEntityEntityType.cs +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Custom_provider_value_comparer/MyEntityEntityType.cs @@ -98,11 +98,11 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas int (int v) => v), clrType: typeof(int), jsonValueReaderWriter: JsonInt32ReaderWriter.Instance); + id.SetCurrentValueComparer(new EntryCurrentValueComparer(id)); id.SetProviderValueComparer(new ValueComparer( bool (int l, int r) => false, int (int v) => 0, int (int v) => 1)); - id.SetCurrentValueComparer(new EntryCurrentValueComparer(id)); var key = runtimeEntityType.AddKey( new[] { id }); @@ -113,7 +113,7 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; + var id = runtimeEntityType.FindProperty("Id"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Custom_type_mapping/MyEntityEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Custom_type_mapping/MyEntityEntityType.cs index 92cf6b3178e..63dc6e53fb1 100644 --- a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Custom_type_mapping/MyEntityEntityType.cs +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Custom_type_mapping/MyEntityEntityType.cs @@ -108,7 +108,7 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; + var id = runtimeEntityType.FindProperty("Id"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Custom_value_comparer/MyEntityEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Custom_value_comparer/MyEntityEntityType.cs index e21509b6721..ca8ce88c85a 100644 --- a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Custom_value_comparer/MyEntityEntityType.cs +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Custom_value_comparer/MyEntityEntityType.cs @@ -98,11 +98,11 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas int (int v) => v), clrType: typeof(int), jsonValueReaderWriter: JsonInt32ReaderWriter.Instance); - id.SetValueComparer(new ValueComparer( + id.SetCurrentValueComparer(new EntryCurrentValueComparer(id)); + id.SetComparer(new ValueComparer( bool (int l, int r) => false, int (int v) => 0, int (int v) => 1)); - id.SetCurrentValueComparer(new EntryCurrentValueComparer(id)); var key = runtimeEntityType.AddKey( new[] { id }); @@ -113,7 +113,7 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; + var id = runtimeEntityType.FindProperty("Id"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Custom_value_converter/MyEntityEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Custom_value_converter/MyEntityEntityType.cs index c80a2ad312f..e5a686f3bde 100644 --- a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Custom_value_converter/MyEntityEntityType.cs +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Custom_value_converter/MyEntityEntityType.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Reflection; +using System.Text.Json; using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; using Microsoft.EntityFrameworkCore.InMemory.Storage.Internal; @@ -92,18 +93,18 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (int v1, int v2) => v1 == v2, int (int v) => v, int (int v) => v), - providerValueComparer: new ValueComparer( - bool (int v1, int v2) => v1 == v2, - int (int v) => v, - int (int v) => v), - converter: new ValueConverter( - int (int i) => i, - int (int i) => i), - jsonValueReaderWriter: new JsonConvertedValueReaderWriter( - JsonInt32ReaderWriter.Instance, - new ValueConverter( - int (int i) => i, - int (int i) => i))); + providerValueComparer: new ValueComparer( + bool (string v1, string v2) => v1 == v2, + int (string v) => ((object)v).GetHashCode(), + string (string v) => v), + converter: new ValueConverter( + string (int i) => JsonSerializer.Serialize(i, (JsonSerializerOptions)(null)), + int (string i) => JsonSerializer.Deserialize(i, (JsonSerializerOptions)(null))), + jsonValueReaderWriter: new JsonConvertedValueReaderWriter( + JsonStringReaderWriter.Instance, + new ValueConverter( + string (int i) => JsonSerializer.Serialize(i, (JsonSerializerOptions)(null)), + int (string i) => JsonSerializer.Deserialize(i, (JsonSerializerOptions)(null))))); id.SetCurrentValueComparer(new EntryCurrentValueComparer(id)); var key = runtimeEntityType.AddKey( @@ -115,7 +116,7 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; + var id = runtimeEntityType.FindProperty("Id"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Fully_qualified_model/IdentityUser0EntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Fully_qualified_model/IdentityUser0EntityType.cs index 830560ca502..2bfc2410a22 100644 --- a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Fully_qualified_model/IdentityUser0EntityType.cs +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Fully_qualified_model/IdentityUser0EntityType.cs @@ -32,22 +32,22 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var accessFailedCount = runtimeEntityType.FindProperty("AccessFailedCount")!; - var concurrencyStamp = runtimeEntityType.FindProperty("ConcurrencyStamp")!; - var discriminator = runtimeEntityType.FindProperty("Discriminator")!; - var email = runtimeEntityType.FindProperty("Email")!; - var emailConfirmed = runtimeEntityType.FindProperty("EmailConfirmed")!; - var lockoutEnabled = runtimeEntityType.FindProperty("LockoutEnabled")!; - var lockoutEnd = runtimeEntityType.FindProperty("LockoutEnd")!; - var normalizedEmail = runtimeEntityType.FindProperty("NormalizedEmail")!; - var normalizedUserName = runtimeEntityType.FindProperty("NormalizedUserName")!; - var passwordHash = runtimeEntityType.FindProperty("PasswordHash")!; - var phoneNumber = runtimeEntityType.FindProperty("PhoneNumber")!; - var phoneNumberConfirmed = runtimeEntityType.FindProperty("PhoneNumberConfirmed")!; - var securityStamp = runtimeEntityType.FindProperty("SecurityStamp")!; - var twoFactorEnabled = runtimeEntityType.FindProperty("TwoFactorEnabled")!; - var userName = runtimeEntityType.FindProperty("UserName")!; + var id = runtimeEntityType.FindProperty("Id"); + var accessFailedCount = runtimeEntityType.FindProperty("AccessFailedCount"); + var concurrencyStamp = runtimeEntityType.FindProperty("ConcurrencyStamp"); + var discriminator = runtimeEntityType.FindProperty("Discriminator"); + var email = runtimeEntityType.FindProperty("Email"); + var emailConfirmed = runtimeEntityType.FindProperty("EmailConfirmed"); + var lockoutEnabled = runtimeEntityType.FindProperty("LockoutEnabled"); + var lockoutEnd = runtimeEntityType.FindProperty("LockoutEnd"); + var normalizedEmail = runtimeEntityType.FindProperty("NormalizedEmail"); + var normalizedUserName = runtimeEntityType.FindProperty("NormalizedUserName"); + var passwordHash = runtimeEntityType.FindProperty("PasswordHash"); + var phoneNumber = runtimeEntityType.FindProperty("PhoneNumber"); + var phoneNumberConfirmed = runtimeEntityType.FindProperty("PhoneNumberConfirmed"); + var securityStamp = runtimeEntityType.FindProperty("SecurityStamp"); + var twoFactorEnabled = runtimeEntityType.FindProperty("TwoFactorEnabled"); + var userName = runtimeEntityType.FindProperty("UserName"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Fully_qualified_model/IdentityUserEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Fully_qualified_model/IdentityUserEntityType.cs index 82f4aa907d2..d1ae6773ad5 100644 --- a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Fully_qualified_model/IdentityUserEntityType.cs +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Fully_qualified_model/IdentityUserEntityType.cs @@ -367,8 +367,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas DateTimeOffset (DateTimeOffset v) => v), clrType: typeof(DateTimeOffset), jsonValueReaderWriter: JsonDateTimeOffsetReaderWriter.Instance); - lockoutEnd.SetValueComparer(new NullableValueComparer(lockoutEnd.TypeMapping.Comparer)); - lockoutEnd.SetKeyValueComparer(new NullableValueComparer(lockoutEnd.TypeMapping.KeyComparer)); + lockoutEnd.SetComparer(new NullableValueComparer(lockoutEnd.TypeMapping.Comparer)); + lockoutEnd.SetKeyComparer(new NullableValueComparer(lockoutEnd.TypeMapping.KeyComparer)); var normalizedEmail = runtimeEntityType.AddProperty( "NormalizedEmail", @@ -723,22 +723,22 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var accessFailedCount = runtimeEntityType.FindProperty("AccessFailedCount")!; - var concurrencyStamp = runtimeEntityType.FindProperty("ConcurrencyStamp")!; - var discriminator = runtimeEntityType.FindProperty("Discriminator")!; - var email = runtimeEntityType.FindProperty("Email")!; - var emailConfirmed = runtimeEntityType.FindProperty("EmailConfirmed")!; - var lockoutEnabled = runtimeEntityType.FindProperty("LockoutEnabled")!; - var lockoutEnd = runtimeEntityType.FindProperty("LockoutEnd")!; - var normalizedEmail = runtimeEntityType.FindProperty("NormalizedEmail")!; - var normalizedUserName = runtimeEntityType.FindProperty("NormalizedUserName")!; - var passwordHash = runtimeEntityType.FindProperty("PasswordHash")!; - var phoneNumber = runtimeEntityType.FindProperty("PhoneNumber")!; - var phoneNumberConfirmed = runtimeEntityType.FindProperty("PhoneNumberConfirmed")!; - var securityStamp = runtimeEntityType.FindProperty("SecurityStamp")!; - var twoFactorEnabled = runtimeEntityType.FindProperty("TwoFactorEnabled")!; - var userName = runtimeEntityType.FindProperty("UserName")!; + var id = runtimeEntityType.FindProperty("Id"); + var accessFailedCount = runtimeEntityType.FindProperty("AccessFailedCount"); + var concurrencyStamp = runtimeEntityType.FindProperty("ConcurrencyStamp"); + var discriminator = runtimeEntityType.FindProperty("Discriminator"); + var email = runtimeEntityType.FindProperty("Email"); + var emailConfirmed = runtimeEntityType.FindProperty("EmailConfirmed"); + var lockoutEnabled = runtimeEntityType.FindProperty("LockoutEnabled"); + var lockoutEnd = runtimeEntityType.FindProperty("LockoutEnd"); + var normalizedEmail = runtimeEntityType.FindProperty("NormalizedEmail"); + var normalizedUserName = runtimeEntityType.FindProperty("NormalizedUserName"); + var passwordHash = runtimeEntityType.FindProperty("PasswordHash"); + var phoneNumber = runtimeEntityType.FindProperty("PhoneNumber"); + var phoneNumberConfirmed = runtimeEntityType.FindProperty("PhoneNumberConfirmed"); + var securityStamp = runtimeEntityType.FindProperty("SecurityStamp"); + var twoFactorEnabled = runtimeEntityType.FindProperty("TwoFactorEnabled"); + var userName = runtimeEntityType.FindProperty("UserName"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Fully_qualified_model/IndexEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Fully_qualified_model/IndexEntityType.cs index 466e1d8164a..aae3f361c5d 100644 --- a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Fully_qualified_model/IndexEntityType.cs +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Fully_qualified_model/IndexEntityType.cs @@ -84,7 +84,7 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; + var id = runtimeEntityType.FindProperty("Id"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Fully_qualified_model/ScaffoldingEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Fully_qualified_model/ScaffoldingEntityType.cs index 470db067450..8086c267aec 100644 --- a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Fully_qualified_model/ScaffoldingEntityType.cs +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Fully_qualified_model/ScaffoldingEntityType.cs @@ -84,7 +84,7 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; + var id = runtimeEntityType.FindProperty("Id"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Global_namespace/EntityType1.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Global_namespace/EntityType1.cs index 75a3cbd93db..c14a5e96de3 100644 --- a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Global_namespace/EntityType1.cs +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Global_namespace/EntityType1.cs @@ -106,7 +106,7 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; + var id = runtimeEntityType.FindProperty("Id"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Lazy_loading_manual/LazyProxiesEntity3EntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Lazy_loading_manual/LazyProxiesEntity3EntityType.cs index 5cb4d36fa9c..32c18e26c42 100644 --- a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Lazy_loading_manual/LazyProxiesEntity3EntityType.cs +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Lazy_loading_manual/LazyProxiesEntity3EntityType.cs @@ -139,12 +139,12 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var name = runtimeEntityType.FindProperty("Name")!; + var id = runtimeEntityType.FindProperty("Id"); + var name = runtimeEntityType.FindProperty("Name"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); - var collectionNavigation = runtimeEntityType.FindNavigation("CollectionNavigation")!; + var collectionNavigation = runtimeEntityType.FindNavigation("CollectionNavigation"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Lazy_loading_manual/LazyProxiesEntity4EntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Lazy_loading_manual/LazyProxiesEntity4EntityType.cs index ee9a338e5a5..d9570ec1f5e 100644 --- a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Lazy_loading_manual/LazyProxiesEntity4EntityType.cs +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Lazy_loading_manual/LazyProxiesEntity4EntityType.cs @@ -292,14 +292,14 @@ public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEnt public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var content = runtimeEntityType.FindProperty("Content")!; - var referenceNavigationId = runtimeEntityType.FindProperty("ReferenceNavigationId")!; - var title = runtimeEntityType.FindProperty("Title")!; + var id = runtimeEntityType.FindProperty("Id"); + var content = runtimeEntityType.FindProperty("Content"); + var referenceNavigationId = runtimeEntityType.FindProperty("ReferenceNavigationId"); + var title = runtimeEntityType.FindProperty("Title"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); - var referenceNavigation = runtimeEntityType.FindNavigation("ReferenceNavigation")!; + var referenceNavigation = runtimeEntityType.FindNavigation("ReferenceNavigation"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Lazy_loading_proxies/LazyProxiesEntity1EntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Lazy_loading_proxies/LazyProxiesEntity1EntityType.cs index 2f75faad836..eada9dd1f24 100644 --- a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Lazy_loading_proxies/LazyProxiesEntity1EntityType.cs +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Lazy_loading_proxies/LazyProxiesEntity1EntityType.cs @@ -111,9 +111,9 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas int (int v) => v), clrType: typeof(int), jsonValueReaderWriter: JsonInt32ReaderWriter.Instance); - referenceNavigationId.SetValueComparer(new NullableValueComparer(referenceNavigationId.TypeMapping.Comparer)); - referenceNavigationId.SetKeyValueComparer(new NullableValueComparer(referenceNavigationId.TypeMapping.KeyComparer)); referenceNavigationId.SetCurrentValueComparer(new EntryCurrentValueComparer(referenceNavigationId)); + referenceNavigationId.SetComparer(new NullableValueComparer(referenceNavigationId.TypeMapping.Comparer)); + referenceNavigationId.SetKeyComparer(new NullableValueComparer(referenceNavigationId.TypeMapping.KeyComparer)); var lazyLoader = runtimeEntityType.AddServiceProperty( "LazyLoader", @@ -208,12 +208,12 @@ public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEnt public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var referenceNavigationId = runtimeEntityType.FindProperty("ReferenceNavigationId")!; + var id = runtimeEntityType.FindProperty("Id"); + var referenceNavigationId = runtimeEntityType.FindProperty("ReferenceNavigationId"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); - var referenceNavigation = runtimeEntityType.FindNavigation("ReferenceNavigation")!; + var referenceNavigation = runtimeEntityType.FindNavigation("ReferenceNavigation"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Lazy_loading_proxies/LazyProxiesEntity2EntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Lazy_loading_proxies/LazyProxiesEntity2EntityType.cs index bcc516a6f9b..4670b95f891 100644 --- a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Lazy_loading_proxies/LazyProxiesEntity2EntityType.cs +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Lazy_loading_proxies/LazyProxiesEntity2EntityType.cs @@ -97,11 +97,11 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; + var id = runtimeEntityType.FindProperty("Id"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); - var collectionNavigation = runtimeEntityType.FindNavigation("CollectionNavigation")!; + var collectionNavigation = runtimeEntityType.FindNavigation("CollectionNavigation"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Manual_lazy_loading/LazyConstructorEntityEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Manual_lazy_loading/LazyConstructorEntityEntityType.cs index 08602cd308e..139c76adeda 100644 --- a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Manual_lazy_loading/LazyConstructorEntityEntityType.cs +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Manual_lazy_loading/LazyConstructorEntityEntityType.cs @@ -97,12 +97,12 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; + var id = runtimeEntityType.FindProperty("Id"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); - var lazyPropertyDelegateEntity = runtimeEntityType.FindNavigation("LazyPropertyDelegateEntity")!; - var lazyPropertyEntity = runtimeEntityType.FindNavigation("LazyPropertyEntity")!; + var lazyPropertyDelegateEntity = runtimeEntityType.FindNavigation("LazyPropertyDelegateEntity"); + var lazyPropertyEntity = runtimeEntityType.FindNavigation("LazyPropertyEntity"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Manual_lazy_loading/LazyPropertyDelegateEntityEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Manual_lazy_loading/LazyPropertyDelegateEntityEntityType.cs index 6744e37085e..e087aa50710 100644 --- a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Manual_lazy_loading/LazyPropertyDelegateEntityEntityType.cs +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Manual_lazy_loading/LazyPropertyDelegateEntityEntityType.cs @@ -224,12 +224,12 @@ public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEnt public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var lazyConstructorEntityId = runtimeEntityType.FindProperty("LazyConstructorEntityId")!; + var id = runtimeEntityType.FindProperty("Id"); + var lazyConstructorEntityId = runtimeEntityType.FindProperty("LazyConstructorEntityId"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); - var lazyConstructorEntity = runtimeEntityType.FindNavigation("LazyConstructorEntity")!; + var lazyConstructorEntity = runtimeEntityType.FindNavigation("LazyConstructorEntity"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Manual_lazy_loading/LazyPropertyEntityEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Manual_lazy_loading/LazyPropertyEntityEntityType.cs index b2300d72033..d4c17d7bfb5 100644 --- a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Manual_lazy_loading/LazyPropertyEntityEntityType.cs +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Manual_lazy_loading/LazyPropertyEntityEntityType.cs @@ -213,12 +213,12 @@ public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEnt public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var lazyConstructorEntityId = runtimeEntityType.FindProperty("LazyConstructorEntityId")!; + var id = runtimeEntityType.FindProperty("Id"); + var lazyConstructorEntityId = runtimeEntityType.FindProperty("LazyConstructorEntityId"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); - var lazyConstructorEntity = runtimeEntityType.FindNavigation("LazyConstructorEntity")!; + var lazyConstructorEntity = runtimeEntityType.FindNavigation("LazyConstructorEntity"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextAssemblyAttributes.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextAssemblyAttributes.cs new file mode 100644 index 00000000000..c224873f6fa --- /dev/null +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextAssemblyAttributes.cs @@ -0,0 +1,9 @@ +// +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using TestNamespace; + +#pragma warning disable 219, 612, 618 +#nullable disable + +[assembly: DbContextModel(typeof(DbContext), typeof(DbContextModel))] diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextModel.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextModel.cs new file mode 100644 index 00000000000..583ee4d90cc --- /dev/null +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextModel.cs @@ -0,0 +1,48 @@ +// +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [DbContext(typeof(DbContext))] + public partial class DbContextModel : RuntimeModel + { + private static readonly bool _useOldBehavior31751 = + System.AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue31751", out var enabled31751) && enabled31751; + + static DbContextModel() + { + var model = new DbContextModel(); + + if (_useOldBehavior31751) + { + model.Initialize(); + } + else + { + var thread = new System.Threading.Thread(RunInitialization, 10 * 1024 * 1024); + thread.Start(); + thread.Join(); + + void RunInitialization() + { + model.Initialize(); + } + } + + model.Customize(); + _instance = (DbContextModel)model.FinalizeModel(); + } + + private static DbContextModel _instance; + public static IModel Instance => _instance; + + partial void Initialize(); + + partial void Customize(); + } +} diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextModelBuilder.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextModelBuilder.cs new file mode 100644 index 00000000000..b59436c7735 --- /dev/null +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextModelBuilder.cs @@ -0,0 +1,50 @@ +// +using System; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + public partial class DbContextModel + { + private DbContextModel() + : base(skipDetectChanges: false, modelId: new Guid("00000000-0000-0000-0000-000000000000"), entityTypeCount: 8) + { + } + + partial void Initialize() + { + var dependentBase = DependentBaseEntityType.Create(this); + var manyTypes = ManyTypesEntityType.Create(this); + var principalBase = PrincipalBaseEntityType.Create(this); + var ownedType = OwnedTypeEntityType.Create(this); + var ownedType0 = OwnedType0EntityType.Create(this); + var principalBasePrincipalDerivedDependentBasebyte = PrincipalBasePrincipalDerivedDependentBasebyteEntityType.Create(this); + var dependentDerived = DependentDerivedEntityType.Create(this, dependentBase); + var principalDerived = PrincipalDerivedEntityType.Create(this, principalBase); + + DependentBaseEntityType.CreateForeignKey1(dependentBase, principalBase); + DependentBaseEntityType.CreateForeignKey2(dependentBase, principalDerived); + OwnedTypeEntityType.CreateForeignKey1(ownedType, principalBase); + OwnedType0EntityType.CreateForeignKey1(ownedType0, principalDerived); + PrincipalBasePrincipalDerivedDependentBasebyteEntityType.CreateForeignKey1(principalBasePrincipalDerivedDependentBasebyte, principalDerived); + PrincipalBasePrincipalDerivedDependentBasebyteEntityType.CreateForeignKey2(principalBasePrincipalDerivedDependentBasebyte, principalBase); + + PrincipalBaseEntityType.CreateSkipNavigation1(principalBase, principalDerived, principalBasePrincipalDerivedDependentBasebyte); + PrincipalDerivedEntityType.CreateSkipNavigation1(principalDerived, principalBase, principalBasePrincipalDerivedDependentBasebyte); + + DependentBaseEntityType.CreateAnnotations(dependentBase); + ManyTypesEntityType.CreateAnnotations(manyTypes); + PrincipalBaseEntityType.CreateAnnotations(principalBase); + OwnedTypeEntityType.CreateAnnotations(ownedType); + OwnedType0EntityType.CreateAnnotations(ownedType0); + PrincipalBasePrincipalDerivedDependentBasebyteEntityType.CreateAnnotations(principalBasePrincipalDerivedDependentBasebyte); + DependentDerivedEntityType.CreateAnnotations(dependentDerived); + PrincipalDerivedEntityType.CreateAnnotations(principalDerived); + + } + } +} diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DependentBaseEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DependentBaseEntityType.cs new file mode 100644 index 00000000000..dc8d863b403 --- /dev/null +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DependentBaseEntityType.cs @@ -0,0 +1,114 @@ +// +using System; +using System.Reflection; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; +using Microsoft.EntityFrameworkCore.ValueGeneration; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class DependentBaseEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+DependentBase", + typeof(CompiledModelTestBase.DependentBase), + baseEntityType, + discriminatorProperty: "EnumDiscriminator", + discriminatorValue: CompiledModelTestBase.Enum1.One, + derivedTypesCount: 1, + propertyCount: 4, + navigationCount: 1, + foreignKeyCount: 2, + keyCount: 1); + + var principalId = runtimeEntityType.AddProperty( + "PrincipalId", + typeof(long), + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: 0L); + + var principalAlternateId = runtimeEntityType.AddProperty( + "PrincipalAlternateId", + typeof(Guid), + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: new Guid("00000000-0000-0000-0000-000000000000")); + + var enumDiscriminator = runtimeEntityType.AddProperty( + "EnumDiscriminator", + typeof(CompiledModelTestBase.Enum1), + afterSaveBehavior: PropertySaveBehavior.Throw, + valueGeneratorFactory: new DiscriminatorValueGeneratorFactory().Create, + sentinel: CompiledModelTestBase.Enum1.Default); + + var id = runtimeEntityType.AddProperty( + "Id", + typeof(byte?), + propertyInfo: typeof(CompiledModelTestBase.DependentBase).GetProperty("Id", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.DependentBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var key = runtimeEntityType.AddKey( + new[] { principalId, principalAlternateId }); + runtimeEntityType.SetPrimaryKey(key); + + return runtimeEntityType; + } + + public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("PrincipalId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("Id") }), + principalEntityType, + deleteBehavior: DeleteBehavior.Cascade, + unique: true, + required: true); + + return runtimeForeignKey; + } + + public static RuntimeForeignKey CreateForeignKey2(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("PrincipalId"), declaringEntityType.FindProperty("PrincipalAlternateId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("Id"), principalEntityType.FindProperty("AlternateId") }), + principalEntityType, + deleteBehavior: DeleteBehavior.ClientNoAction, + unique: true, + required: true); + + var principal = declaringEntityType.AddNavigation("Principal", + runtimeForeignKey, + onDependent: true, + typeof(CompiledModelTestBase.PrincipalDerived>), + propertyInfo: typeof(CompiledModelTestBase.DependentBase).GetProperty("Principal", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.DependentBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var dependent = principalEntityType.AddNavigation("Dependent", + runtimeForeignKey, + onDependent: false, + typeof(CompiledModelTestBase.DependentBase), + propertyInfo: typeof(CompiledModelTestBase.PrincipalDerived>).GetProperty("Dependent", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalDerived>).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + eagerLoaded: true, + lazyLoadingEnabled: false); + + return runtimeForeignKey; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + runtimeEntityType.AddAnnotation("DiscriminatorMappingComplete", false); + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DependentDerivedEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DependentDerivedEntityType.cs new file mode 100644 index 00000000000..74ff4f82ea1 --- /dev/null +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DependentDerivedEntityType.cs @@ -0,0 +1,53 @@ +// +using System; +using System.Reflection; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class DependentDerivedEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+DependentDerived", + typeof(CompiledModelTestBase.DependentDerived), + baseEntityType, + discriminatorProperty: "EnumDiscriminator", + discriminatorValue: CompiledModelTestBase.Enum1.Two, + propertyCount: 2); + + var data = runtimeEntityType.AddProperty( + "Data", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.DependentDerived).GetProperty("Data", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.DependentDerived).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true, + maxLength: 20, + unicode: false); + + var money = runtimeEntityType.AddProperty( + "Money", + typeof(decimal), + precision: 9, + scale: 3, + sentinel: 0m); + + return runtimeEntityType; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/ManyTypesEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/ManyTypesEntityType.cs new file mode 100644 index 00000000000..1af80a9af87 --- /dev/null +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/ManyTypesEntityType.cs @@ -0,0 +1,1779 @@ +// +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.NetworkInformation; +using System.Reflection; +using System.Text; +using Microsoft.EntityFrameworkCore.ChangeTracking; +using Microsoft.EntityFrameworkCore.InMemory.Storage.Internal; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; +using Microsoft.EntityFrameworkCore.Storage.Json; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class ManyTypesEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+ManyTypes", + typeof(CompiledModelTestBase.ManyTypes), + baseEntityType, + propertyCount: 258, + keyCount: 1); + + var id = runtimeEntityType.AddProperty( + "Id", + typeof(CompiledModelTestBase.ManyTypesId), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Id", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueGenerated: ValueGenerated.OnAdd, + afterSaveBehavior: PropertySaveBehavior.Throw, + valueConverter: new CompiledModelTestBase.ManyTypesIdConverter()); + id.SetSentinelFromProviderValue(0); + + var @bool = runtimeEntityType.AddProperty( + "Bool", + typeof(bool), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Bool", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: false); + + var boolArray = runtimeEntityType.AddProperty( + "BoolArray", + typeof(bool[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BoolArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var boolNestedCollection = runtimeEntityType.AddProperty( + "BoolNestedCollection", + typeof(bool[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BoolNestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var boolToStringConverterProperty = runtimeEntityType.AddProperty( + "BoolToStringConverterProperty", + typeof(bool), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BoolToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + boolToStringConverterProperty.TypeMapping = InMemoryTypeMapping.Default.Clone( + comparer: new ValueComparer( + bool (bool v1, bool v2) => v1 == v2, + int (bool v) => ((object)v).GetHashCode(), + bool (bool v) => v), + keyComparer: new ValueComparer( + bool (bool v1, bool v2) => v1 == v2, + int (bool v) => ((object)v).GetHashCode(), + bool (bool v) => v), + providerValueComparer: new ValueComparer( + bool (string v1, string v2) => v1 == v2, + int (string v) => ((object)v).GetHashCode(), + string (string v) => v), + converter: new ValueConverter( + string (bool v) => ((string)((v ? "B" : "A"))), + bool (string v) => !(string.IsNullOrEmpty(v)) && ((int)(v.ToUpperInvariant()[0])) == ((int)("B".ToUpperInvariant()[0]))), + jsonValueReaderWriter: new JsonConvertedValueReaderWriter( + JsonStringReaderWriter.Instance, + new ValueConverter( + string (bool v) => ((string)((v ? "B" : "A"))), + bool (string v) => !(string.IsNullOrEmpty(v)) && ((int)(v.ToUpperInvariant()[0])) == ((int)("B".ToUpperInvariant()[0]))))); + boolToStringConverterProperty.SetSentinelFromProviderValue("A"); + + var boolToTwoValuesConverterProperty = runtimeEntityType.AddProperty( + "BoolToTwoValuesConverterProperty", + typeof(bool), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BoolToTwoValuesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + boolToTwoValuesConverterProperty.SetValueConverter(new ValueConverter( + byte (bool v) => ((byte)((v ? 1 : 0))), + bool (byte v) => v == 1)); + boolToTwoValuesConverterProperty.SetSentinelFromProviderValue((byte)0); + + var boolToZeroOneConverterProperty = runtimeEntityType.AddProperty( + "BoolToZeroOneConverterProperty", + typeof(bool), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BoolToZeroOneConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new BoolToZeroOneConverter()); + boolToZeroOneConverterProperty.SetSentinelFromProviderValue((short)0); + + var bytes = runtimeEntityType.AddProperty( + "Bytes", + typeof(byte[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Bytes", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var bytesArray = runtimeEntityType.AddProperty( + "BytesArray", + typeof(byte[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BytesArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var bytesNestedCollection = runtimeEntityType.AddProperty( + "BytesNestedCollection", + typeof(byte[][][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BytesNestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var bytesToStringConverterProperty = runtimeEntityType.AddProperty( + "BytesToStringConverterProperty", + typeof(byte[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BytesToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new BytesToStringConverter(), + valueComparer: new ArrayStructuralComparer()); + + var castingConverterProperty = runtimeEntityType.AddProperty( + "CastingConverterProperty", + typeof(int), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("CastingConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new CastingConverter()); + castingConverterProperty.SetSentinelFromProviderValue(0m); + + var @char = runtimeEntityType.AddProperty( + "Char", + typeof(char), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Char", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: '\0'); + + var charArray = runtimeEntityType.AddProperty( + "CharArray", + typeof(char[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("CharArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var charNestedCollection = runtimeEntityType.AddProperty( + "CharNestedCollection", + typeof(char[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("CharNestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var charToStringConverterProperty = runtimeEntityType.AddProperty( + "CharToStringConverterProperty", + typeof(char), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("CharToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new CharToStringConverter()); + charToStringConverterProperty.SetSentinelFromProviderValue("\0"); + + var dateOnly = runtimeEntityType.AddProperty( + "DateOnly", + typeof(DateOnly), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateOnly", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: new DateOnly(1, 1, 1)); + + var dateOnlyArray = runtimeEntityType.AddProperty( + "DateOnlyArray", + typeof(DateOnly[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateOnlyArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var dateOnlyToStringConverterProperty = runtimeEntityType.AddProperty( + "DateOnlyToStringConverterProperty", + typeof(DateOnly), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateOnlyToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new DateOnlyToStringConverter()); + dateOnlyToStringConverterProperty.SetSentinelFromProviderValue("0001-01-01"); + + var dateTime = runtimeEntityType.AddProperty( + "DateTime", + typeof(DateTime), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTime", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + var dateTimeArray = runtimeEntityType.AddProperty( + "DateTimeArray", + typeof(DateTime[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var dateTimeOffsetToBinaryConverterProperty = runtimeEntityType.AddProperty( + "DateTimeOffsetToBinaryConverterProperty", + typeof(DateTimeOffset), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeOffsetToBinaryConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new DateTimeOffsetToBinaryConverter()); + dateTimeOffsetToBinaryConverterProperty.SetSentinelFromProviderValue(0L); + + var dateTimeOffsetToBytesConverterProperty = runtimeEntityType.AddProperty( + "DateTimeOffsetToBytesConverterProperty", + typeof(DateTimeOffset), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeOffsetToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new DateTimeOffsetToBytesConverter()); + dateTimeOffsetToBytesConverterProperty.SetSentinelFromProviderValue(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }); + + var dateTimeOffsetToStringConverterProperty = runtimeEntityType.AddProperty( + "DateTimeOffsetToStringConverterProperty", + typeof(DateTimeOffset), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeOffsetToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new DateTimeOffsetToStringConverter()); + dateTimeOffsetToStringConverterProperty.SetSentinelFromProviderValue("0001-01-01 00:00:00+00:00"); + + var dateTimeToBinaryConverterProperty = runtimeEntityType.AddProperty( + "DateTimeToBinaryConverterProperty", + typeof(DateTime), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeToBinaryConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new DateTimeToBinaryConverter()); + dateTimeToBinaryConverterProperty.SetSentinelFromProviderValue(0L); + + var dateTimeToStringConverterProperty = runtimeEntityType.AddProperty( + "DateTimeToStringConverterProperty", + typeof(DateTime), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new DateTimeToStringConverter()); + dateTimeToStringConverterProperty.SetSentinelFromProviderValue("0001-01-01 00:00:00"); + + var dateTimeToTicksConverterProperty = runtimeEntityType.AddProperty( + "DateTimeToTicksConverterProperty", + typeof(DateTime), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeToTicksConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + var @decimal = runtimeEntityType.AddProperty( + "Decimal", + typeof(decimal), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Decimal", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0m); + + var decimalArray = runtimeEntityType.AddProperty( + "DecimalArray", + typeof(decimal[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DecimalArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var decimalNumberToBytesConverterProperty = runtimeEntityType.AddProperty( + "DecimalNumberToBytesConverterProperty", + typeof(decimal), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DecimalNumberToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new NumberToBytesConverter()); + decimalNumberToBytesConverterProperty.SetSentinelFromProviderValue(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }); + + var decimalNumberToStringConverterProperty = runtimeEntityType.AddProperty( + "DecimalNumberToStringConverterProperty", + typeof(decimal), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DecimalNumberToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new NumberToStringConverter()); + decimalNumberToStringConverterProperty.SetSentinelFromProviderValue("0"); + + var @double = runtimeEntityType.AddProperty( + "Double", + typeof(double), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Double", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0.0); + + var doubleArray = runtimeEntityType.AddProperty( + "DoubleArray", + typeof(double[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DoubleArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var doubleNumberToBytesConverterProperty = runtimeEntityType.AddProperty( + "DoubleNumberToBytesConverterProperty", + typeof(double), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DoubleNumberToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new NumberToBytesConverter()); + doubleNumberToBytesConverterProperty.SetSentinelFromProviderValue(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }); + + var doubleNumberToStringConverterProperty = runtimeEntityType.AddProperty( + "DoubleNumberToStringConverterProperty", + typeof(double), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DoubleNumberToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new NumberToStringConverter()); + doubleNumberToStringConverterProperty.SetSentinelFromProviderValue("0"); + + var enum16 = runtimeEntityType.AddProperty( + "Enum16", + typeof(CompiledModelTestBase.Enum16), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: CompiledModelTestBase.Enum16.Default); + + var enum16Array = runtimeEntityType.AddProperty( + "Enum16Array", + typeof(CompiledModelTestBase.Enum16[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum16AsString = runtimeEntityType.AddProperty( + "Enum16AsString", + typeof(CompiledModelTestBase.Enum16), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum16AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enum16AsString.SetSentinelFromProviderValue("Default"); + + var enum16AsStringArray = runtimeEntityType.AddProperty( + "Enum16AsStringArray", + typeof(CompiledModelTestBase.Enum16[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum16AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum16AsStringCollection = runtimeEntityType.AddProperty( + "Enum16AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum16AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum16Collection = runtimeEntityType.AddProperty( + "Enum16Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum16Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum32 = runtimeEntityType.AddProperty( + "Enum32", + typeof(CompiledModelTestBase.Enum32), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: CompiledModelTestBase.Enum32.Default); + + var enum32Array = runtimeEntityType.AddProperty( + "Enum32Array", + typeof(CompiledModelTestBase.Enum32[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum32AsString = runtimeEntityType.AddProperty( + "Enum32AsString", + typeof(CompiledModelTestBase.Enum32), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum32AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enum32AsString.SetSentinelFromProviderValue("Default"); + + var enum32AsStringArray = runtimeEntityType.AddProperty( + "Enum32AsStringArray", + typeof(CompiledModelTestBase.Enum32[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum32AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum32AsStringCollection = runtimeEntityType.AddProperty( + "Enum32AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum32AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum32Collection = runtimeEntityType.AddProperty( + "Enum32Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum32Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum32NestedCollection = runtimeEntityType.AddProperty( + "Enum32NestedCollection", + typeof(List[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum32NestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum64 = runtimeEntityType.AddProperty( + "Enum64", + typeof(CompiledModelTestBase.Enum64), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: CompiledModelTestBase.Enum64.Default); + + var enum64Array = runtimeEntityType.AddProperty( + "Enum64Array", + typeof(CompiledModelTestBase.Enum64[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum64AsString = runtimeEntityType.AddProperty( + "Enum64AsString", + typeof(CompiledModelTestBase.Enum64), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum64AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enum64AsString.SetSentinelFromProviderValue("Default"); + + var enum64AsStringArray = runtimeEntityType.AddProperty( + "Enum64AsStringArray", + typeof(CompiledModelTestBase.Enum64[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum64AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum64AsStringCollection = runtimeEntityType.AddProperty( + "Enum64AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum64AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum64Collection = runtimeEntityType.AddProperty( + "Enum64Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum64Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum8 = runtimeEntityType.AddProperty( + "Enum8", + typeof(CompiledModelTestBase.Enum8), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: CompiledModelTestBase.Enum8.Default); + + var enum8Array = runtimeEntityType.AddProperty( + "Enum8Array", + typeof(CompiledModelTestBase.Enum8[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum8AsString = runtimeEntityType.AddProperty( + "Enum8AsString", + typeof(CompiledModelTestBase.Enum8), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum8AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enum8AsString.SetSentinelFromProviderValue("Default"); + + var enum8AsStringArray = runtimeEntityType.AddProperty( + "Enum8AsStringArray", + typeof(CompiledModelTestBase.Enum8[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum8AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum8AsStringCollection = runtimeEntityType.AddProperty( + "Enum8AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum8AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum8Collection = runtimeEntityType.AddProperty( + "Enum8Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum8Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum8NestedCollection = runtimeEntityType.AddProperty( + "Enum8NestedCollection", + typeof(CompiledModelTestBase.Enum8[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum8NestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumToNumberConverterProperty = runtimeEntityType.AddProperty( + "EnumToNumberConverterProperty", + typeof(CompiledModelTestBase.Enum32), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumToNumberConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new EnumToNumberConverter()); + enumToNumberConverterProperty.SetSentinelFromProviderValue(0); + + var enumToStringConverterProperty = runtimeEntityType.AddProperty( + "EnumToStringConverterProperty", + typeof(CompiledModelTestBase.Enum32), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new EnumToStringConverter()); + enumToStringConverterProperty.SetSentinelFromProviderValue("Default"); + + var enumU16 = runtimeEntityType.AddProperty( + "EnumU16", + typeof(CompiledModelTestBase.EnumU16), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: CompiledModelTestBase.EnumU16.Min); + + var enumU16Array = runtimeEntityType.AddProperty( + "EnumU16Array", + typeof(CompiledModelTestBase.EnumU16[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU16AsString = runtimeEntityType.AddProperty( + "EnumU16AsString", + typeof(CompiledModelTestBase.EnumU16), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU16AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enumU16AsString.SetSentinelFromProviderValue("Min"); + + var enumU16AsStringArray = runtimeEntityType.AddProperty( + "EnumU16AsStringArray", + typeof(CompiledModelTestBase.EnumU16[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU16AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU16AsStringCollection = runtimeEntityType.AddProperty( + "EnumU16AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU16AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU16Collection = runtimeEntityType.AddProperty( + "EnumU16Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU16Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU32 = runtimeEntityType.AddProperty( + "EnumU32", + typeof(CompiledModelTestBase.EnumU32), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: CompiledModelTestBase.EnumU32.Min); + + var enumU32Array = runtimeEntityType.AddProperty( + "EnumU32Array", + typeof(CompiledModelTestBase.EnumU32[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU32AsString = runtimeEntityType.AddProperty( + "EnumU32AsString", + typeof(CompiledModelTestBase.EnumU32), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU32AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enumU32AsString.SetSentinelFromProviderValue("Min"); + + var enumU32AsStringArray = runtimeEntityType.AddProperty( + "EnumU32AsStringArray", + typeof(CompiledModelTestBase.EnumU32[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU32AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU32AsStringCollection = runtimeEntityType.AddProperty( + "EnumU32AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU32AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU32Collection = runtimeEntityType.AddProperty( + "EnumU32Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU32Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU64 = runtimeEntityType.AddProperty( + "EnumU64", + typeof(CompiledModelTestBase.EnumU64), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: CompiledModelTestBase.EnumU64.Min); + + var enumU64Array = runtimeEntityType.AddProperty( + "EnumU64Array", + typeof(CompiledModelTestBase.EnumU64[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU64AsString = runtimeEntityType.AddProperty( + "EnumU64AsString", + typeof(CompiledModelTestBase.EnumU64), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU64AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enumU64AsString.SetSentinelFromProviderValue("Min"); + + var enumU64AsStringArray = runtimeEntityType.AddProperty( + "EnumU64AsStringArray", + typeof(CompiledModelTestBase.EnumU64[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU64AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU64AsStringCollection = runtimeEntityType.AddProperty( + "EnumU64AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU64AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU64Collection = runtimeEntityType.AddProperty( + "EnumU64Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU64Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU64NestedCollection = runtimeEntityType.AddProperty( + "EnumU64NestedCollection", + typeof(CompiledModelTestBase.EnumU64[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU64NestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU8 = runtimeEntityType.AddProperty( + "EnumU8", + typeof(CompiledModelTestBase.EnumU8), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: CompiledModelTestBase.EnumU8.Min); + + var enumU8Array = runtimeEntityType.AddProperty( + "EnumU8Array", + typeof(CompiledModelTestBase.EnumU8[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU8AsString = runtimeEntityType.AddProperty( + "EnumU8AsString", + typeof(CompiledModelTestBase.EnumU8), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU8AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enumU8AsString.SetSentinelFromProviderValue("Min"); + + var enumU8AsStringArray = runtimeEntityType.AddProperty( + "EnumU8AsStringArray", + typeof(CompiledModelTestBase.EnumU8[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU8AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU8AsStringCollection = runtimeEntityType.AddProperty( + "EnumU8AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU8AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU8Collection = runtimeEntityType.AddProperty( + "EnumU8Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU8Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var @float = runtimeEntityType.AddProperty( + "Float", + typeof(float), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Float", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0f); + + var floatArray = runtimeEntityType.AddProperty( + "FloatArray", + typeof(float[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("FloatArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var guid = runtimeEntityType.AddProperty( + "Guid", + typeof(Guid), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Guid", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: new Guid("00000000-0000-0000-0000-000000000000")); + + var guidArray = runtimeEntityType.AddProperty( + "GuidArray", + typeof(Guid[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("GuidArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var guidNestedCollection = runtimeEntityType.AddProperty( + "GuidNestedCollection", + typeof(ICollection), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("GuidNestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var guidToBytesConverterProperty = runtimeEntityType.AddProperty( + "GuidToBytesConverterProperty", + typeof(Guid), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("GuidToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new GuidToBytesConverter()); + guidToBytesConverterProperty.SetSentinelFromProviderValue(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }); + + var guidToStringConverterProperty = runtimeEntityType.AddProperty( + "GuidToStringConverterProperty", + typeof(Guid), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("GuidToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new GuidToStringConverter()); + guidToStringConverterProperty.SetSentinelFromProviderValue("00000000-0000-0000-0000-000000000000"); + + var iPAddress = runtimeEntityType.AddProperty( + "IPAddress", + typeof(IPAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("IPAddress", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var iPAddressArray = runtimeEntityType.AddProperty( + "IPAddressArray", + typeof(IPAddress[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("IPAddressArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var iPAddressToBytesConverterProperty = runtimeEntityType.AddProperty( + "IPAddressToBytesConverterProperty", + typeof(IPAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("IPAddressToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new IPAddressToBytesConverter()); + + var iPAddressToStringConverterProperty = runtimeEntityType.AddProperty( + "IPAddressToStringConverterProperty", + typeof(IPAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("IPAddressToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new IPAddressToStringConverter()); + + var int16 = runtimeEntityType.AddProperty( + "Int16", + typeof(short), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: (short)0); + + var int16Array = runtimeEntityType.AddProperty( + "Int16Array", + typeof(short[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var int32 = runtimeEntityType.AddProperty( + "Int32", + typeof(int), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0); + + var int32Array = runtimeEntityType.AddProperty( + "Int32Array", + typeof(int[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var int32NestedCollection = runtimeEntityType.AddProperty( + "Int32NestedCollection", + typeof(int[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int32NestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var int64 = runtimeEntityType.AddProperty( + "Int64", + typeof(long), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0L); + + var int64Array = runtimeEntityType.AddProperty( + "Int64Array", + typeof(long[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var int64NestedCollection = runtimeEntityType.AddProperty( + "Int64NestedCollection", + typeof(IList[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int64NestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var int8 = runtimeEntityType.AddProperty( + "Int8", + typeof(sbyte), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: (sbyte)0); + + var int8Array = runtimeEntityType.AddProperty( + "Int8Array", + typeof(sbyte[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var int8NestedCollection = runtimeEntityType.AddProperty( + "Int8NestedCollection", + typeof(sbyte[][][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int8NestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var intNumberToBytesConverterProperty = runtimeEntityType.AddProperty( + "IntNumberToBytesConverterProperty", + typeof(int), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("IntNumberToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new NumberToBytesConverter()); + intNumberToBytesConverterProperty.SetSentinelFromProviderValue(new byte[] { 0, 0, 0, 0 }); + + var intNumberToStringConverterProperty = runtimeEntityType.AddProperty( + "IntNumberToStringConverterProperty", + typeof(int), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("IntNumberToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new NumberToStringConverter()); + intNumberToStringConverterProperty.SetSentinelFromProviderValue("0"); + + var nullIntToNullStringConverterProperty = runtimeEntityType.AddProperty( + "NullIntToNullStringConverterProperty", + typeof(int?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullIntToNullStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true, + valueConverter: new CompiledModelTestBase.NullIntToNullStringConverter()); + + var nullableBool = runtimeEntityType.AddProperty( + "NullableBool", + typeof(bool?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableBool", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableBoolArray = runtimeEntityType.AddProperty( + "NullableBoolArray", + typeof(bool?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableBoolArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableBytes = runtimeEntityType.AddProperty( + "NullableBytes", + typeof(byte[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableBytes", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableBytesArray = runtimeEntityType.AddProperty( + "NullableBytesArray", + typeof(byte[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableBytesArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableBytesNestedCollection = runtimeEntityType.AddProperty( + "NullableBytesNestedCollection", + typeof(byte[][][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableBytesNestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableChar = runtimeEntityType.AddProperty( + "NullableChar", + typeof(char?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableChar", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableCharArray = runtimeEntityType.AddProperty( + "NullableCharArray", + typeof(char?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableCharArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableDateOnly = runtimeEntityType.AddProperty( + "NullableDateOnly", + typeof(DateOnly?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDateOnly", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableDateOnlyArray = runtimeEntityType.AddProperty( + "NullableDateOnlyArray", + typeof(DateOnly?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDateOnlyArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableDateTime = runtimeEntityType.AddProperty( + "NullableDateTime", + typeof(DateTime?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDateTime", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableDateTimeArray = runtimeEntityType.AddProperty( + "NullableDateTimeArray", + typeof(DateTime?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDateTimeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableDecimal = runtimeEntityType.AddProperty( + "NullableDecimal", + typeof(decimal?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDecimal", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableDecimalArray = runtimeEntityType.AddProperty( + "NullableDecimalArray", + typeof(decimal?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDecimalArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableDouble = runtimeEntityType.AddProperty( + "NullableDouble", + typeof(double?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDouble", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableDoubleArray = runtimeEntityType.AddProperty( + "NullableDoubleArray", + typeof(double?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDoubleArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum16 = runtimeEntityType.AddProperty( + "NullableEnum16", + typeof(CompiledModelTestBase.Enum16?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnum16Array = runtimeEntityType.AddProperty( + "NullableEnum16Array", + typeof(CompiledModelTestBase.Enum16?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum16AsString = runtimeEntityType.AddProperty( + "NullableEnum16AsString", + typeof(CompiledModelTestBase.Enum16?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum16AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnum16AsStringArray = runtimeEntityType.AddProperty( + "NullableEnum16AsStringArray", + typeof(CompiledModelTestBase.Enum16?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum16AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum16AsStringCollection = runtimeEntityType.AddProperty( + "NullableEnum16AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum16AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum16Collection = runtimeEntityType.AddProperty( + "NullableEnum16Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum16Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum32 = runtimeEntityType.AddProperty( + "NullableEnum32", + typeof(CompiledModelTestBase.Enum32?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnum32Array = runtimeEntityType.AddProperty( + "NullableEnum32Array", + typeof(CompiledModelTestBase.Enum32?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum32AsString = runtimeEntityType.AddProperty( + "NullableEnum32AsString", + typeof(CompiledModelTestBase.Enum32?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum32AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnum32AsStringArray = runtimeEntityType.AddProperty( + "NullableEnum32AsStringArray", + typeof(CompiledModelTestBase.Enum32?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum32AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum32AsStringCollection = runtimeEntityType.AddProperty( + "NullableEnum32AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum32AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum32Collection = runtimeEntityType.AddProperty( + "NullableEnum32Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum32Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum32NestedCollection = runtimeEntityType.AddProperty( + "NullableEnum32NestedCollection", + typeof(CompiledModelTestBase.Enum32?[][][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum32NestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum64 = runtimeEntityType.AddProperty( + "NullableEnum64", + typeof(CompiledModelTestBase.Enum64?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnum64Array = runtimeEntityType.AddProperty( + "NullableEnum64Array", + typeof(CompiledModelTestBase.Enum64?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum64AsString = runtimeEntityType.AddProperty( + "NullableEnum64AsString", + typeof(CompiledModelTestBase.Enum64?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum64AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnum64AsStringArray = runtimeEntityType.AddProperty( + "NullableEnum64AsStringArray", + typeof(CompiledModelTestBase.Enum64?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum64AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum64AsStringCollection = runtimeEntityType.AddProperty( + "NullableEnum64AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum64AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum64Collection = runtimeEntityType.AddProperty( + "NullableEnum64Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum64Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum8 = runtimeEntityType.AddProperty( + "NullableEnum8", + typeof(CompiledModelTestBase.Enum8?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnum8Array = runtimeEntityType.AddProperty( + "NullableEnum8Array", + typeof(CompiledModelTestBase.Enum8?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum8AsString = runtimeEntityType.AddProperty( + "NullableEnum8AsString", + typeof(CompiledModelTestBase.Enum8?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum8AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnum8AsStringArray = runtimeEntityType.AddProperty( + "NullableEnum8AsStringArray", + typeof(CompiledModelTestBase.Enum8?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum8AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum8AsStringCollection = runtimeEntityType.AddProperty( + "NullableEnum8AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum8AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum8Collection = runtimeEntityType.AddProperty( + "NullableEnum8Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum8Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum8NestedCollection = runtimeEntityType.AddProperty( + "NullableEnum8NestedCollection", + typeof(CompiledModelTestBase.Enum8?[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum8NestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU16 = runtimeEntityType.AddProperty( + "NullableEnumU16", + typeof(CompiledModelTestBase.EnumU16?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnumU16Array = runtimeEntityType.AddProperty( + "NullableEnumU16Array", + typeof(CompiledModelTestBase.EnumU16?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU16AsString = runtimeEntityType.AddProperty( + "NullableEnumU16AsString", + typeof(CompiledModelTestBase.EnumU16?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU16AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnumU16AsStringArray = runtimeEntityType.AddProperty( + "NullableEnumU16AsStringArray", + typeof(CompiledModelTestBase.EnumU16?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU16AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU16AsStringCollection = runtimeEntityType.AddProperty( + "NullableEnumU16AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU16AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU16Collection = runtimeEntityType.AddProperty( + "NullableEnumU16Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU16Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU32 = runtimeEntityType.AddProperty( + "NullableEnumU32", + typeof(CompiledModelTestBase.EnumU32?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnumU32Array = runtimeEntityType.AddProperty( + "NullableEnumU32Array", + typeof(CompiledModelTestBase.EnumU32?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU32AsString = runtimeEntityType.AddProperty( + "NullableEnumU32AsString", + typeof(CompiledModelTestBase.EnumU32?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU32AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnumU32AsStringArray = runtimeEntityType.AddProperty( + "NullableEnumU32AsStringArray", + typeof(CompiledModelTestBase.EnumU32?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU32AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU32AsStringCollection = runtimeEntityType.AddProperty( + "NullableEnumU32AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU32AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU32Collection = runtimeEntityType.AddProperty( + "NullableEnumU32Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU32Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU64 = runtimeEntityType.AddProperty( + "NullableEnumU64", + typeof(CompiledModelTestBase.EnumU64?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnumU64Array = runtimeEntityType.AddProperty( + "NullableEnumU64Array", + typeof(CompiledModelTestBase.EnumU64?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU64AsString = runtimeEntityType.AddProperty( + "NullableEnumU64AsString", + typeof(CompiledModelTestBase.EnumU64?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU64AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnumU64AsStringArray = runtimeEntityType.AddProperty( + "NullableEnumU64AsStringArray", + typeof(CompiledModelTestBase.EnumU64?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU64AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU64AsStringCollection = runtimeEntityType.AddProperty( + "NullableEnumU64AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU64AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU64Collection = runtimeEntityType.AddProperty( + "NullableEnumU64Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU64Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU64NestedCollection = runtimeEntityType.AddProperty( + "NullableEnumU64NestedCollection", + typeof(CompiledModelTestBase.EnumU64?[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU64NestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU8 = runtimeEntityType.AddProperty( + "NullableEnumU8", + typeof(CompiledModelTestBase.EnumU8?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnumU8Array = runtimeEntityType.AddProperty( + "NullableEnumU8Array", + typeof(CompiledModelTestBase.EnumU8?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU8AsString = runtimeEntityType.AddProperty( + "NullableEnumU8AsString", + typeof(CompiledModelTestBase.EnumU8?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU8AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnumU8AsStringArray = runtimeEntityType.AddProperty( + "NullableEnumU8AsStringArray", + typeof(CompiledModelTestBase.EnumU8?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU8AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU8AsStringCollection = runtimeEntityType.AddProperty( + "NullableEnumU8AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU8AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU8Collection = runtimeEntityType.AddProperty( + "NullableEnumU8Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU8Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableFloat = runtimeEntityType.AddProperty( + "NullableFloat", + typeof(float?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableFloat", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableFloatArray = runtimeEntityType.AddProperty( + "NullableFloatArray", + typeof(float?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableFloatArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableGuid = runtimeEntityType.AddProperty( + "NullableGuid", + typeof(Guid?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableGuid", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableGuidArray = runtimeEntityType.AddProperty( + "NullableGuidArray", + typeof(Guid?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableGuidArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableGuidNestedCollection = runtimeEntityType.AddProperty( + "NullableGuidNestedCollection", + typeof(Guid?[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableGuidNestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableIPAddress = runtimeEntityType.AddProperty( + "NullableIPAddress", + typeof(IPAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableIPAddress", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableIPAddressArray = runtimeEntityType.AddProperty( + "NullableIPAddressArray", + typeof(IPAddress[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableIPAddressArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableInt16 = runtimeEntityType.AddProperty( + "NullableInt16", + typeof(short?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableInt16Array = runtimeEntityType.AddProperty( + "NullableInt16Array", + typeof(short?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableInt32 = runtimeEntityType.AddProperty( + "NullableInt32", + typeof(int?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableInt32Array = runtimeEntityType.AddProperty( + "NullableInt32Array", + typeof(int?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableInt32NestedCollection = runtimeEntityType.AddProperty( + "NullableInt32NestedCollection", + typeof(int?[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt32NestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableInt64 = runtimeEntityType.AddProperty( + "NullableInt64", + typeof(long?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableInt64Array = runtimeEntityType.AddProperty( + "NullableInt64Array", + typeof(long?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableInt64NestedCollection = runtimeEntityType.AddProperty( + "NullableInt64NestedCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt64NestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableInt8 = runtimeEntityType.AddProperty( + "NullableInt8", + typeof(sbyte?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableInt8Array = runtimeEntityType.AddProperty( + "NullableInt8Array", + typeof(sbyte?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullablePhysicalAddress = runtimeEntityType.AddProperty( + "NullablePhysicalAddress", + typeof(PhysicalAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullablePhysicalAddress", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullablePhysicalAddressArray = runtimeEntityType.AddProperty( + "NullablePhysicalAddressArray", + typeof(PhysicalAddress[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullablePhysicalAddressArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullablePhysicalAddressNestedCollection = runtimeEntityType.AddProperty( + "NullablePhysicalAddressNestedCollection", + typeof(IEnumerable), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullablePhysicalAddressNestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableString = runtimeEntityType.AddProperty( + "NullableString", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableStringArray = runtimeEntityType.AddProperty( + "NullableStringArray", + typeof(string[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableStringNestedCollection = runtimeEntityType.AddProperty( + "NullableStringNestedCollection", + typeof(string[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableStringNestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableTimeOnly = runtimeEntityType.AddProperty( + "NullableTimeOnly", + typeof(TimeOnly?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableTimeOnly", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableTimeOnlyArray = runtimeEntityType.AddProperty( + "NullableTimeOnlyArray", + typeof(TimeOnly?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableTimeOnlyArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableTimeSpan = runtimeEntityType.AddProperty( + "NullableTimeSpan", + typeof(TimeSpan?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableTimeSpan", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableTimeSpanArray = runtimeEntityType.AddProperty( + "NullableTimeSpanArray", + typeof(TimeSpan?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableTimeSpanArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableUInt16 = runtimeEntityType.AddProperty( + "NullableUInt16", + typeof(ushort?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableUInt16Array = runtimeEntityType.AddProperty( + "NullableUInt16Array", + typeof(ushort?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableUInt32 = runtimeEntityType.AddProperty( + "NullableUInt32", + typeof(uint?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableUInt32Array = runtimeEntityType.AddProperty( + "NullableUInt32Array", + typeof(uint?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableUInt64 = runtimeEntityType.AddProperty( + "NullableUInt64", + typeof(ulong?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableUInt64Array = runtimeEntityType.AddProperty( + "NullableUInt64Array", + typeof(ulong?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableUInt8 = runtimeEntityType.AddProperty( + "NullableUInt8", + typeof(byte?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableUInt8Array = runtimeEntityType.AddProperty( + "NullableUInt8Array", + typeof(byte?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableUInt8NestedCollection = runtimeEntityType.AddProperty( + "NullableUInt8NestedCollection", + typeof(byte?[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt8NestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableUri = runtimeEntityType.AddProperty( + "NullableUri", + typeof(Uri), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUri", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableUriArray = runtimeEntityType.AddProperty( + "NullableUriArray", + typeof(Uri[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUriArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var physicalAddress = runtimeEntityType.AddProperty( + "PhysicalAddress", + typeof(PhysicalAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("PhysicalAddress", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var physicalAddressArray = runtimeEntityType.AddProperty( + "PhysicalAddressArray", + typeof(PhysicalAddress[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("PhysicalAddressArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var physicalAddressToBytesConverterProperty = runtimeEntityType.AddProperty( + "PhysicalAddressToBytesConverterProperty", + typeof(PhysicalAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("PhysicalAddressToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new PhysicalAddressToBytesConverter()); + + var physicalAddressToStringConverterProperty = runtimeEntityType.AddProperty( + "PhysicalAddressToStringConverterProperty", + typeof(PhysicalAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("PhysicalAddressToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new PhysicalAddressToStringConverter()); + + var @string = runtimeEntityType.AddProperty( + "String", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("String", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var stringArray = runtimeEntityType.AddProperty( + "StringArray", + typeof(string[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var stringNestedCollection = runtimeEntityType.AddProperty( + "StringNestedCollection", + typeof(string[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringNestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var stringToBoolConverterProperty = runtimeEntityType.AddProperty( + "StringToBoolConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToBoolConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToBoolConverter()); + + var stringToBytesConverterProperty = runtimeEntityType.AddProperty( + "StringToBytesConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + stringToBytesConverterProperty.SetValueConverter(new ValueConverter( + byte[] (string v) => Encoding.GetEncoding(12000).GetBytes(v), + string (byte[] v) => Encoding.GetEncoding(12000).GetString(v))); + + var stringToCharConverterProperty = runtimeEntityType.AddProperty( + "StringToCharConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToCharConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToCharConverter()); + + var stringToDateOnlyConverterProperty = runtimeEntityType.AddProperty( + "StringToDateOnlyConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToDateOnlyConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToDateOnlyConverter()); + + var stringToDateTimeConverterProperty = runtimeEntityType.AddProperty( + "StringToDateTimeConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToDateTimeConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToDateTimeConverter()); + + var stringToDateTimeOffsetConverterProperty = runtimeEntityType.AddProperty( + "StringToDateTimeOffsetConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToDateTimeOffsetConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToDateTimeOffsetConverter()); + + var stringToDecimalNumberConverterProperty = runtimeEntityType.AddProperty( + "StringToDecimalNumberConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToDecimalNumberConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToNumberConverter()); + + var stringToDoubleNumberConverterProperty = runtimeEntityType.AddProperty( + "StringToDoubleNumberConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToDoubleNumberConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToNumberConverter()); + + var stringToEnumConverterProperty = runtimeEntityType.AddProperty( + "StringToEnumConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToEnumConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToEnumConverter()); + + var stringToGuidConverterProperty = runtimeEntityType.AddProperty( + "StringToGuidConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToGuidConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var stringToIntNumberConverterProperty = runtimeEntityType.AddProperty( + "StringToIntNumberConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToIntNumberConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToNumberConverter()); + + var stringToTimeOnlyConverterProperty = runtimeEntityType.AddProperty( + "StringToTimeOnlyConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToTimeOnlyConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToTimeOnlyConverter()); + + var stringToTimeSpanConverterProperty = runtimeEntityType.AddProperty( + "StringToTimeSpanConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToTimeSpanConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToTimeSpanConverter()); + + var stringToUriConverterProperty = runtimeEntityType.AddProperty( + "StringToUriConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToUriConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToUriConverter()); + + var timeOnly = runtimeEntityType.AddProperty( + "TimeOnly", + typeof(TimeOnly), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeOnly", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: new TimeOnly(0, 0, 0)); + + var timeOnlyArray = runtimeEntityType.AddProperty( + "TimeOnlyArray", + typeof(TimeOnly[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeOnlyArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var timeOnlyToStringConverterProperty = runtimeEntityType.AddProperty( + "TimeOnlyToStringConverterProperty", + typeof(TimeOnly), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeOnlyToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new TimeOnlyToStringConverter()); + timeOnlyToStringConverterProperty.SetSentinelFromProviderValue("00:00:00"); + + var timeOnlyToTicksConverterProperty = runtimeEntityType.AddProperty( + "TimeOnlyToTicksConverterProperty", + typeof(TimeOnly), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeOnlyToTicksConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new TimeOnlyToTicksConverter()); + timeOnlyToTicksConverterProperty.SetSentinelFromProviderValue(0L); + + var timeSpan = runtimeEntityType.AddProperty( + "TimeSpan", + typeof(TimeSpan), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeSpan", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: new TimeSpan(0, 0, 0, 0, 0)); + + var timeSpanArray = runtimeEntityType.AddProperty( + "TimeSpanArray", + typeof(TimeSpan[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeSpanArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var timeSpanToStringConverterProperty = runtimeEntityType.AddProperty( + "TimeSpanToStringConverterProperty", + typeof(TimeSpan), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeSpanToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new TimeSpanToStringConverter()); + timeSpanToStringConverterProperty.SetSentinelFromProviderValue("00:00:00"); + + var timeSpanToTicksConverterProperty = runtimeEntityType.AddProperty( + "TimeSpanToTicksConverterProperty", + typeof(TimeSpan), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeSpanToTicksConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new TimeSpanToTicksConverter()); + timeSpanToTicksConverterProperty.SetSentinelFromProviderValue(0L); + + var uInt16 = runtimeEntityType.AddProperty( + "UInt16", + typeof(ushort), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: (ushort)0); + + var uInt16Array = runtimeEntityType.AddProperty( + "UInt16Array", + typeof(ushort[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var uInt32 = runtimeEntityType.AddProperty( + "UInt32", + typeof(uint), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0u); + + var uInt32Array = runtimeEntityType.AddProperty( + "UInt32Array", + typeof(uint[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var uInt64 = runtimeEntityType.AddProperty( + "UInt64", + typeof(ulong), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0ul); + + var uInt64Array = runtimeEntityType.AddProperty( + "UInt64Array", + typeof(ulong[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var uInt8 = runtimeEntityType.AddProperty( + "UInt8", + typeof(byte), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: (byte)0); + + var uInt8Array = runtimeEntityType.AddProperty( + "UInt8Array", + typeof(byte[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var uInt8NestedCollection = runtimeEntityType.AddProperty( + "UInt8NestedCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt8NestedCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var uri = runtimeEntityType.AddProperty( + "Uri", + typeof(Uri), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Uri", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var uriArray = runtimeEntityType.AddProperty( + "UriArray", + typeof(Uri[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UriArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var uriToStringConverterProperty = runtimeEntityType.AddProperty( + "UriToStringConverterProperty", + typeof(Uri), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UriToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new UriToStringConverter()); + + var key = runtimeEntityType.AddKey( + new[] { id }); + runtimeEntityType.SetPrimaryKey(key); + + return runtimeEntityType; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/OwnedType0EntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/OwnedType0EntityType.cs new file mode 100644 index 00000000000..ba5cdffb308 --- /dev/null +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/OwnedType0EntityType.cs @@ -0,0 +1,159 @@ +// +using System; +using System.Collections.Generic; +using System.Net; +using System.Reflection; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class OwnedType0EntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalDerived>.ManyOwned#OwnedType", + typeof(CompiledModelTestBase.OwnedType), + baseEntityType, + sharedClrType: true, + propertyCount: 13, + servicePropertyCount: 1, + foreignKeyCount: 1, + keyCount: 1); + + var principalDerivedId = runtimeEntityType.AddProperty( + "PrincipalDerivedId", + typeof(long), + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: 0L); + + var principalDerivedAlternateId = runtimeEntityType.AddProperty( + "PrincipalDerivedAlternateId", + typeof(Guid), + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: new Guid("00000000-0000-0000-0000-000000000000")); + + var id = runtimeEntityType.AddProperty( + "Id", + typeof(int), + valueGenerated: ValueGenerated.OnAdd, + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: 0); + + var details = runtimeEntityType.AddProperty( + "Details", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("Details", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_details", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var number = runtimeEntityType.AddProperty( + "Number", + typeof(int), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("Number", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0); + + var refTypeArray = runtimeEntityType.AddProperty( + "RefTypeArray", + typeof(IPAddress[]), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeArray", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var refTypeEnumerable = runtimeEntityType.AddProperty( + "RefTypeEnumerable", + typeof(IEnumerable), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeEnumerable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeEnumerable", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var refTypeIList = runtimeEntityType.AddProperty( + "RefTypeIList", + typeof(IList), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeIList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeIList", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var refTypeList = runtimeEntityType.AddProperty( + "RefTypeList", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeList", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var valueTypeArray = runtimeEntityType.AddProperty( + "ValueTypeArray", + typeof(DateTime[]), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_valueTypeArray", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var valueTypeEnumerable = runtimeEntityType.AddProperty( + "ValueTypeEnumerable", + typeof(IEnumerable), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeEnumerable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_valueTypeEnumerable", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var valueTypeIList = runtimeEntityType.AddProperty( + "ValueTypeIList", + typeof(IList), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeIList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var valueTypeList = runtimeEntityType.AddProperty( + "ValueTypeList", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_valueTypeList", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var context = runtimeEntityType.AddServiceProperty( + "Context", + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("Context", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + serviceType: typeof(DbContext)); + + var key = runtimeEntityType.AddKey( + new[] { principalDerivedId, principalDerivedAlternateId, id }); + runtimeEntityType.SetPrimaryKey(key); + + return runtimeEntityType; + } + + public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("PrincipalDerivedId"), declaringEntityType.FindProperty("PrincipalDerivedAlternateId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("Id"), principalEntityType.FindProperty("AlternateId") }), + principalEntityType, + deleteBehavior: DeleteBehavior.Cascade, + required: true, + ownership: true); + + var manyOwned = principalEntityType.AddNavigation("ManyOwned", + runtimeForeignKey, + onDependent: false, + typeof(ICollection), + fieldInfo: typeof(CompiledModelTestBase.PrincipalDerived>).GetField("ManyOwned", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + eagerLoaded: true); + + return runtimeForeignKey; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/OwnedTypeEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/OwnedTypeEntityType.cs new file mode 100644 index 00000000000..1734e6dc9b1 --- /dev/null +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/OwnedTypeEntityType.cs @@ -0,0 +1,169 @@ +// +using System; +using System.Collections.Generic; +using System.Net; +using System.Reflection; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class OwnedTypeEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalBase.Owned#OwnedType", + typeof(CompiledModelTestBase.OwnedType), + baseEntityType, + sharedClrType: true, + changeTrackingStrategy: ChangeTrackingStrategy.ChangingAndChangedNotificationsWithOriginalValues, + propertyCount: 12, + servicePropertyCount: 1, + foreignKeyCount: 1, + keyCount: 1); + + var principalBaseId = runtimeEntityType.AddProperty( + "PrincipalBaseId", + typeof(long), + propertyAccessMode: PropertyAccessMode.Field, + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: 0L); + + var principalBaseAlternateId = runtimeEntityType.AddProperty( + "PrincipalBaseAlternateId", + typeof(Guid), + propertyAccessMode: PropertyAccessMode.Field, + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: new Guid("00000000-0000-0000-0000-000000000000")); + + var details = runtimeEntityType.AddProperty( + "Details", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("Details", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_details", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var number = runtimeEntityType.AddProperty( + "Number", + typeof(int), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("Number", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + sentinel: 0); + + var refTypeArray = runtimeEntityType.AddProperty( + "RefTypeArray", + typeof(IPAddress[]), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeArray", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var refTypeEnumerable = runtimeEntityType.AddProperty( + "RefTypeEnumerable", + typeof(IEnumerable), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeEnumerable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeEnumerable", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var refTypeIList = runtimeEntityType.AddProperty( + "RefTypeIList", + typeof(IList), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeIList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeIList", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var refTypeList = runtimeEntityType.AddProperty( + "RefTypeList", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeList", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var valueTypeArray = runtimeEntityType.AddProperty( + "ValueTypeArray", + typeof(DateTime[]), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_valueTypeArray", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var valueTypeEnumerable = runtimeEntityType.AddProperty( + "ValueTypeEnumerable", + typeof(IEnumerable), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeEnumerable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_valueTypeEnumerable", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var valueTypeIList = runtimeEntityType.AddProperty( + "ValueTypeIList", + typeof(IList), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeIList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var valueTypeList = runtimeEntityType.AddProperty( + "ValueTypeList", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_valueTypeList", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var context = runtimeEntityType.AddServiceProperty( + "Context", + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("Context", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + serviceType: typeof(DbContext)); + + var key = runtimeEntityType.AddKey( + new[] { principalBaseId, principalBaseAlternateId }); + runtimeEntityType.SetPrimaryKey(key); + + return runtimeEntityType; + } + + public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("PrincipalBaseId"), declaringEntityType.FindProperty("PrincipalBaseAlternateId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("Id"), principalEntityType.FindProperty("AlternateId") }), + principalEntityType, + deleteBehavior: DeleteBehavior.Cascade, + unique: true, + required: true, + requiredDependent: true, + ownership: true); + + var owned = principalEntityType.AddNavigation("Owned", + runtimeForeignKey, + onDependent: false, + typeof(CompiledModelTestBase.OwnedType), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("Owned", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("_ownedField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + eagerLoaded: true); + + return runtimeForeignKey; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalBaseEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalBaseEntityType.cs new file mode 100644 index 00000000000..f732733bf07 --- /dev/null +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalBaseEntityType.cs @@ -0,0 +1,185 @@ +// +using System; +using System.Collections.Generic; +using System.Net; +using System.Reflection; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; +using Microsoft.EntityFrameworkCore.Storage.Json; +using Microsoft.EntityFrameworkCore.ValueGeneration; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class PrincipalBaseEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalBase", + typeof(CompiledModelTestBase.PrincipalBase), + baseEntityType, + discriminatorProperty: "Discriminator", + discriminatorValue: "PrincipalBase", + derivedTypesCount: 1, + propertyCount: 15, + navigationCount: 1, + skipNavigationCount: 1, + keyCount: 2); + + var id = runtimeEntityType.AddProperty( + "Id", + typeof(long?), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("Id", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + afterSaveBehavior: PropertySaveBehavior.Throw); + + var alternateId = runtimeEntityType.AddProperty( + "AlternateId", + typeof(Guid), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("AlternateId", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.FieldDuringConstruction, + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: new Guid("00000000-0000-0000-0000-000000000000"), + jsonValueReaderWriter: JsonGuidReaderWriter.Instance); + + var discriminator = runtimeEntityType.AddProperty( + "Discriminator", + typeof(string), + afterSaveBehavior: PropertySaveBehavior.Throw, + valueGeneratorFactory: new DiscriminatorValueGeneratorFactory().Create); + + var enum1 = runtimeEntityType.AddProperty( + "Enum1", + typeof(CompiledModelTestBase.AnEnum), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("Enum1", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: (CompiledModelTestBase.AnEnum)0); + + var enum2 = runtimeEntityType.AddProperty( + "Enum2", + typeof(CompiledModelTestBase.AnEnum?), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("Enum2", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var flagsEnum1 = runtimeEntityType.AddProperty( + "FlagsEnum1", + typeof(CompiledModelTestBase.AFlagsEnum), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("FlagsEnum1", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: (CompiledModelTestBase.AFlagsEnum)0); + + var flagsEnum2 = runtimeEntityType.AddProperty( + "FlagsEnum2", + typeof(CompiledModelTestBase.AFlagsEnum), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("FlagsEnum2", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Property, + sentinel: CompiledModelTestBase.AFlagsEnum.B | CompiledModelTestBase.AFlagsEnum.C); + + var refTypeArray = runtimeEntityType.AddProperty( + "RefTypeArray", + typeof(IPAddress[]), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("RefTypeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var refTypeEnumerable = runtimeEntityType.AddProperty( + "RefTypeEnumerable", + typeof(IEnumerable), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("RefTypeEnumerable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var refTypeIList = runtimeEntityType.AddProperty( + "RefTypeIList", + typeof(IList), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("RefTypeIList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var refTypeList = runtimeEntityType.AddProperty( + "RefTypeList", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("RefTypeList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var valueTypeArray = runtimeEntityType.AddProperty( + "ValueTypeArray", + typeof(DateTime[]), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("ValueTypeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var valueTypeEnumerable = runtimeEntityType.AddProperty( + "ValueTypeEnumerable", + typeof(IEnumerable), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("ValueTypeEnumerable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var valueTypeIList = runtimeEntityType.AddProperty( + "ValueTypeIList", + typeof(IList), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("ValueTypeIList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var valueTypeList = runtimeEntityType.AddProperty( + "ValueTypeList", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("ValueTypeList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var key = runtimeEntityType.AddKey( + new[] { id }); + + var key0 = runtimeEntityType.AddKey( + new[] { id, alternateId }); + runtimeEntityType.SetPrimaryKey(key0); + + return runtimeEntityType; + } + + public static RuntimeSkipNavigation CreateSkipNavigation1(RuntimeEntityType declaringEntityType, RuntimeEntityType targetEntityType, RuntimeEntityType joinEntityType) + { + var skipNavigation = declaringEntityType.AddSkipNavigation( + "Deriveds", + targetEntityType, + joinEntityType.FindForeignKey( + new[] { joinEntityType.FindProperty("PrincipalsId"), joinEntityType.FindProperty("PrincipalsAlternateId") }, + declaringEntityType.FindKey(new[] { declaringEntityType.FindProperty("Id"), declaringEntityType.FindProperty("AlternateId") }), + declaringEntityType), + true, + false, + typeof(ICollection), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("Deriveds", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var inverse = targetEntityType.FindSkipNavigation("Principals"); + if (inverse != null) + { + skipNavigation.Inverse = inverse; + inverse.Inverse = skipNavigation; + } + + return skipNavigation; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs new file mode 100644 index 00000000000..2fe1d6cd30b --- /dev/null +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs @@ -0,0 +1,97 @@ +// +using System; +using System.Collections.Generic; +using System.Reflection; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class PrincipalBasePrincipalDerivedDependentBasebyteEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "PrincipalBasePrincipalDerived>", + typeof(Dictionary), + baseEntityType, + sharedClrType: true, + indexerPropertyInfo: RuntimeEntityType.FindIndexerProperty(typeof(Dictionary)), + propertyBag: true, + propertyCount: 5, + foreignKeyCount: 2, + keyCount: 1); + + var derivedsId = runtimeEntityType.AddProperty( + "DerivedsId", + typeof(long), + propertyInfo: runtimeEntityType.FindIndexerPropertyInfo(), + afterSaveBehavior: PropertySaveBehavior.Throw); + + var derivedsAlternateId = runtimeEntityType.AddProperty( + "DerivedsAlternateId", + typeof(Guid), + propertyInfo: runtimeEntityType.FindIndexerPropertyInfo(), + afterSaveBehavior: PropertySaveBehavior.Throw); + + var principalsId = runtimeEntityType.AddProperty( + "PrincipalsId", + typeof(long), + propertyInfo: runtimeEntityType.FindIndexerPropertyInfo(), + afterSaveBehavior: PropertySaveBehavior.Throw); + + var principalsAlternateId = runtimeEntityType.AddProperty( + "PrincipalsAlternateId", + typeof(Guid), + propertyInfo: runtimeEntityType.FindIndexerPropertyInfo(), + afterSaveBehavior: PropertySaveBehavior.Throw); + + var rowid = runtimeEntityType.AddProperty( + "rowid", + typeof(byte[]), + propertyInfo: runtimeEntityType.FindIndexerPropertyInfo(), + nullable: true); + + var key = runtimeEntityType.AddKey( + new[] { derivedsId, derivedsAlternateId, principalsId, principalsAlternateId }); + runtimeEntityType.SetPrimaryKey(key); + + return runtimeEntityType; + } + + public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("DerivedsId"), declaringEntityType.FindProperty("DerivedsAlternateId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("Id"), principalEntityType.FindProperty("AlternateId") }), + principalEntityType, + deleteBehavior: DeleteBehavior.Cascade, + required: true); + + return runtimeForeignKey; + } + + public static RuntimeForeignKey CreateForeignKey2(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("PrincipalsId"), declaringEntityType.FindProperty("PrincipalsAlternateId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("Id"), principalEntityType.FindProperty("AlternateId") }), + principalEntityType, + deleteBehavior: DeleteBehavior.Cascade, + required: true); + + return runtimeForeignKey; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalDerivedEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalDerivedEntityType.cs new file mode 100644 index 00000000000..b366bffcd95 --- /dev/null +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalDerivedEntityType.cs @@ -0,0 +1,65 @@ +// +using System; +using System.Collections.Generic; +using System.Reflection; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class PrincipalDerivedEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalDerived>", + typeof(CompiledModelTestBase.PrincipalDerived>), + baseEntityType, + discriminatorProperty: "Discriminator", + discriminatorValue: "PrincipalDerived>", + propertyCount: 0, + navigationCount: 2, + skipNavigationCount: 1); + + return runtimeEntityType; + } + + public static RuntimeSkipNavigation CreateSkipNavigation1(RuntimeEntityType declaringEntityType, RuntimeEntityType targetEntityType, RuntimeEntityType joinEntityType) + { + var skipNavigation = declaringEntityType.AddSkipNavigation( + "Principals", + targetEntityType, + joinEntityType.FindForeignKey( + new[] { joinEntityType.FindProperty("DerivedsId"), joinEntityType.FindProperty("DerivedsAlternateId") }, + declaringEntityType.FindKey(new[] { declaringEntityType.FindProperty("Id"), declaringEntityType.FindProperty("AlternateId") }), + declaringEntityType), + true, + false, + typeof(ICollection), + propertyInfo: typeof(CompiledModelTestBase.PrincipalDerived>).GetProperty("Principals", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalDerived>).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var inverse = targetEntityType.FindSkipNavigation("Deriveds"); + if (inverse != null) + { + skipNavigation.Inverse = inverse; + inverse.Inverse = skipNavigation; + } + + return skipNavigation; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/RelationshipCycles/DependentBaseEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/RelationshipCycles/DependentBaseEntityType.cs index 0c1ebcab188..e55ca19320c 100644 --- a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/RelationshipCycles/DependentBaseEntityType.cs +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/RelationshipCycles/DependentBaseEntityType.cs @@ -75,9 +75,9 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas long (long v) => v), clrType: typeof(long), jsonValueReaderWriter: JsonInt64ReaderWriter.Instance); - id.SetValueComparer(new NullableValueComparer(id.TypeMapping.Comparer)); - id.SetKeyValueComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); id.SetCurrentValueComparer(new EntryCurrentValueComparer(id)); + id.SetComparer(new NullableValueComparer(id.TypeMapping.Comparer)); + id.SetKeyComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); var principalId = runtimeEntityType.AddProperty( "PrincipalId", @@ -193,15 +193,15 @@ public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEnt public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var principalId = runtimeEntityType.FindProperty("PrincipalId")!; + var id = runtimeEntityType.FindProperty("Id"); + var principalId = runtimeEntityType.FindProperty("PrincipalId"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); var key0 = runtimeEntityType.FindKey(new[] { principalId }); key0.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key0)); key0.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key0)); - var principal = runtimeEntityType.FindNavigation("Principal")!; + var principal = runtimeEntityType.FindNavigation("Principal"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/RelationshipCycles/PrincipalBaseEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/RelationshipCycles/PrincipalBaseEntityType.cs index bdfc9f07e57..d7b161d2ec7 100644 --- a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/RelationshipCycles/PrincipalBaseEntityType.cs +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/RelationshipCycles/PrincipalBaseEntityType.cs @@ -80,9 +80,9 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas long (long v) => v), clrType: typeof(long), jsonValueReaderWriter: JsonInt64ReaderWriter.Instance); - id.SetValueComparer(new NullableValueComparer(id.TypeMapping.Comparer)); - id.SetKeyValueComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); id.SetCurrentValueComparer(new EntryCurrentValueComparer(id)); + id.SetComparer(new NullableValueComparer(id.TypeMapping.Comparer)); + id.SetKeyComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); var discriminator = runtimeEntityType.AddProperty( "Discriminator", @@ -202,8 +202,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas CompiledModelTestBase.AnEnum (CompiledModelTestBase.AnEnum v) => v), clrType: typeof(CompiledModelTestBase.AnEnum), jsonValueReaderWriter: JsonSignedEnumReaderWriter.Instance); - enum2.SetValueComparer(new NullableValueComparer(enum2.TypeMapping.Comparer)); - enum2.SetKeyValueComparer(new NullableValueComparer(enum2.TypeMapping.KeyComparer)); + enum2.SetComparer(new NullableValueComparer(enum2.TypeMapping.Comparer)); + enum2.SetKeyComparer(new NullableValueComparer(enum2.TypeMapping.KeyComparer)); var flagsEnum1 = runtimeEntityType.AddProperty( "FlagsEnum1", @@ -814,27 +814,27 @@ public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEnt public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var discriminator = runtimeEntityType.FindProperty("Discriminator")!; - var enum1 = runtimeEntityType.FindProperty("Enum1")!; - var enum2 = runtimeEntityType.FindProperty("Enum2")!; - var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1")!; - var principalId = runtimeEntityType.FindProperty("PrincipalId")!; - var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray")!; - var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable")!; - var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList")!; - var refTypeList = runtimeEntityType.FindProperty("RefTypeList")!; - var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList")!; - var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList")!; + var id = runtimeEntityType.FindProperty("Id"); + var discriminator = runtimeEntityType.FindProperty("Discriminator"); + var enum1 = runtimeEntityType.FindProperty("Enum1"); + var enum2 = runtimeEntityType.FindProperty("Enum2"); + var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1"); + var principalId = runtimeEntityType.FindProperty("PrincipalId"); + var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray"); + var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable"); + var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList"); + var refTypeList = runtimeEntityType.FindProperty("RefTypeList"); + var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList"); + var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); var key0 = runtimeEntityType.FindKey(new[] { principalId }); key0.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key0)); key0.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key0)); - var deriveds = runtimeEntityType.FindNavigation("Deriveds")!; + var deriveds = runtimeEntityType.FindNavigation("Deriveds"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/RelationshipCycles/PrincipalDerivedEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/RelationshipCycles/PrincipalDerivedEntityType.cs index c05153ac914..ef59537bf47 100644 --- a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/RelationshipCycles/PrincipalDerivedEntityType.cs +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/RelationshipCycles/PrincipalDerivedEntityType.cs @@ -81,22 +81,22 @@ public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEnt public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var discriminator = runtimeEntityType.FindProperty("Discriminator")!; - var enum1 = runtimeEntityType.FindProperty("Enum1")!; - var enum2 = runtimeEntityType.FindProperty("Enum2")!; - var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1")!; - var principalId = runtimeEntityType.FindProperty("PrincipalId")!; - var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray")!; - var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable")!; - var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList")!; - var refTypeList = runtimeEntityType.FindProperty("RefTypeList")!; - var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList")!; - var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList")!; - var deriveds = runtimeEntityType.FindNavigation("Deriveds")!; - var dependent = runtimeEntityType.FindNavigation("Dependent")!; + var id = runtimeEntityType.FindProperty("Id"); + var discriminator = runtimeEntityType.FindProperty("Discriminator"); + var enum1 = runtimeEntityType.FindProperty("Enum1"); + var enum2 = runtimeEntityType.FindProperty("Enum2"); + var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1"); + var principalId = runtimeEntityType.FindProperty("PrincipalId"); + var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray"); + var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable"); + var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList"); + var refTypeList = runtimeEntityType.FindProperty("RefTypeList"); + var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList"); + var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList"); + var deriveds = runtimeEntityType.FindNavigation("Deriveds"); + var dependent = runtimeEntityType.FindNavigation("Dependent"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Self_referential_property/SelfReferentialEntityEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Self_referential_property/SelfReferentialEntityEntityType.cs index b9b2aeb7329..72d8b1bcd9f 100644 --- a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Self_referential_property/SelfReferentialEntityEntityType.cs +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Self_referential_property/SelfReferentialEntityEntityType.cs @@ -24,8 +24,8 @@ public partial class SelfReferentialEntityEntityType public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) { var runtimeEntityType = model.AddEntityType( - "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelInMemoryTest+SelfReferentialEntity", - typeof(CompiledModelInMemoryTest.SelfReferentialEntity), + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelInMemoryTest+SelfReferentialEntity", + typeof(CompiledModelInMemoryTest.SelfReferentialEntity), baseEntityType, propertyCount: 2, keyCount: 1); @@ -33,23 +33,23 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas var id = runtimeEntityType.AddProperty( "Id", typeof(long), - propertyInfo: typeof(CompiledModelInMemoryTest.SelfReferentialEntity).GetProperty("Id", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), - fieldInfo: typeof(CompiledModelInMemoryTest.SelfReferentialEntity).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyInfo: typeof(CompiledModelInMemoryTest.SelfReferentialEntity).GetProperty("Id", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelInMemoryTest.SelfReferentialEntity).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), valueGenerated: ValueGenerated.OnAdd, afterSaveBehavior: PropertySaveBehavior.Throw, sentinel: 0L); id.SetGetter( - long (CompiledModelInMemoryTest.SelfReferentialEntity entity) => SelfReferentialEntityUnsafeAccessors.Id(entity), - bool (CompiledModelInMemoryTest.SelfReferentialEntity entity) => SelfReferentialEntityUnsafeAccessors.Id(entity) == 0L, - long (CompiledModelInMemoryTest.SelfReferentialEntity instance) => SelfReferentialEntityUnsafeAccessors.Id(instance), - bool (CompiledModelInMemoryTest.SelfReferentialEntity instance) => SelfReferentialEntityUnsafeAccessors.Id(instance) == 0L); + long (CompiledModelInMemoryTest.SelfReferentialEntity entity) => SelfReferentialEntityUnsafeAccessors.Id(entity), + bool (CompiledModelInMemoryTest.SelfReferentialEntity entity) => SelfReferentialEntityUnsafeAccessors.Id(entity) == 0L, + long (CompiledModelInMemoryTest.SelfReferentialEntity instance) => SelfReferentialEntityUnsafeAccessors.Id(instance), + bool (CompiledModelInMemoryTest.SelfReferentialEntity instance) => SelfReferentialEntityUnsafeAccessors.Id(instance) == 0L); id.SetSetter( - (CompiledModelInMemoryTest.SelfReferentialEntity entity, long value) => SelfReferentialEntityUnsafeAccessors.Id(entity) = value); + (CompiledModelInMemoryTest.SelfReferentialEntity entity, long value) => SelfReferentialEntityUnsafeAccessors.Id(entity) = value); id.SetMaterializationSetter( - (CompiledModelInMemoryTest.SelfReferentialEntity entity, long value) => SelfReferentialEntityUnsafeAccessors.Id(entity) = value); + (CompiledModelInMemoryTest.SelfReferentialEntity entity, long value) => SelfReferentialEntityUnsafeAccessors.Id(entity) = value); id.SetAccessors( - long (InternalEntityEntry entry) => (entry.FlaggedAsStoreGenerated(0) ? entry.ReadStoreGeneratedValue(0) : (entry.FlaggedAsTemporary(0) && SelfReferentialEntityUnsafeAccessors.Id(((CompiledModelInMemoryTest.SelfReferentialEntity)(entry.Entity))) == 0L ? entry.ReadTemporaryValue(0) : SelfReferentialEntityUnsafeAccessors.Id(((CompiledModelInMemoryTest.SelfReferentialEntity)(entry.Entity))))), - long (InternalEntityEntry entry) => SelfReferentialEntityUnsafeAccessors.Id(((CompiledModelInMemoryTest.SelfReferentialEntity)(entry.Entity))), + long (InternalEntityEntry entry) => (entry.FlaggedAsStoreGenerated(0) ? entry.ReadStoreGeneratedValue(0) : (entry.FlaggedAsTemporary(0) && SelfReferentialEntityUnsafeAccessors.Id(((CompiledModelInMemoryTest.SelfReferentialEntity)(entry.Entity))) == 0L ? entry.ReadTemporaryValue(0) : SelfReferentialEntityUnsafeAccessors.Id(((CompiledModelInMemoryTest.SelfReferentialEntity)(entry.Entity))))), + long (InternalEntityEntry entry) => SelfReferentialEntityUnsafeAccessors.Id(((CompiledModelInMemoryTest.SelfReferentialEntity)(entry.Entity))), long (InternalEntityEntry entry) => entry.ReadOriginalValue(id, 0), long (InternalEntityEntry entry) => entry.ReadRelationshipSnapshotValue(id, 0), object (ValueBuffer valueBuffer) => valueBuffer[0]); @@ -79,22 +79,22 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas var collection = runtimeEntityType.AddProperty( "Collection", typeof(CompiledModelInMemoryTest.SelfReferentialProperty), - propertyInfo: typeof(CompiledModelInMemoryTest.SelfReferentialEntity).GetProperty("Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), - fieldInfo: typeof(CompiledModelInMemoryTest.SelfReferentialEntity).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyInfo: typeof(CompiledModelInMemoryTest.SelfReferentialEntity).GetProperty("Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelInMemoryTest.SelfReferentialEntity).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), nullable: true, - valueConverter: new CompiledModelInMemoryTest.SelfReferentialPropertyValueConverter()); + valueConverter: new CompiledModelInMemoryTest.SelfReferentialEntity.NonGeneric.SelfReferentialPropertyValueConverter()); collection.SetGetter( - CompiledModelInMemoryTest.SelfReferentialProperty (CompiledModelInMemoryTest.SelfReferentialEntity entity) => SelfReferentialEntityUnsafeAccessors.Collection(entity), - bool (CompiledModelInMemoryTest.SelfReferentialEntity entity) => SelfReferentialEntityUnsafeAccessors.Collection(entity) == null, - CompiledModelInMemoryTest.SelfReferentialProperty (CompiledModelInMemoryTest.SelfReferentialEntity instance) => SelfReferentialEntityUnsafeAccessors.Collection(instance), - bool (CompiledModelInMemoryTest.SelfReferentialEntity instance) => SelfReferentialEntityUnsafeAccessors.Collection(instance) == null); + CompiledModelInMemoryTest.SelfReferentialProperty (CompiledModelInMemoryTest.SelfReferentialEntity entity) => SelfReferentialEntityUnsafeAccessors.Collection(entity), + bool (CompiledModelInMemoryTest.SelfReferentialEntity entity) => SelfReferentialEntityUnsafeAccessors.Collection(entity) == null, + CompiledModelInMemoryTest.SelfReferentialProperty (CompiledModelInMemoryTest.SelfReferentialEntity instance) => SelfReferentialEntityUnsafeAccessors.Collection(instance), + bool (CompiledModelInMemoryTest.SelfReferentialEntity instance) => SelfReferentialEntityUnsafeAccessors.Collection(instance) == null); collection.SetSetter( - (CompiledModelInMemoryTest.SelfReferentialEntity entity, CompiledModelInMemoryTest.SelfReferentialProperty value) => SelfReferentialEntityUnsafeAccessors.Collection(entity) = value); + (CompiledModelInMemoryTest.SelfReferentialEntity entity, CompiledModelInMemoryTest.SelfReferentialProperty value) => SelfReferentialEntityUnsafeAccessors.Collection(entity) = value); collection.SetMaterializationSetter( - (CompiledModelInMemoryTest.SelfReferentialEntity entity, CompiledModelInMemoryTest.SelfReferentialProperty value) => SelfReferentialEntityUnsafeAccessors.Collection(entity) = value); + (CompiledModelInMemoryTest.SelfReferentialEntity entity, CompiledModelInMemoryTest.SelfReferentialProperty value) => SelfReferentialEntityUnsafeAccessors.Collection(entity) = value); collection.SetAccessors( - CompiledModelInMemoryTest.SelfReferentialProperty (InternalEntityEntry entry) => SelfReferentialEntityUnsafeAccessors.Collection(((CompiledModelInMemoryTest.SelfReferentialEntity)(entry.Entity))), - CompiledModelInMemoryTest.SelfReferentialProperty (InternalEntityEntry entry) => SelfReferentialEntityUnsafeAccessors.Collection(((CompiledModelInMemoryTest.SelfReferentialEntity)(entry.Entity))), + CompiledModelInMemoryTest.SelfReferentialProperty (InternalEntityEntry entry) => SelfReferentialEntityUnsafeAccessors.Collection(((CompiledModelInMemoryTest.SelfReferentialEntity)(entry.Entity))), + CompiledModelInMemoryTest.SelfReferentialProperty (InternalEntityEntry entry) => SelfReferentialEntityUnsafeAccessors.Collection(((CompiledModelInMemoryTest.SelfReferentialEntity)(entry.Entity))), CompiledModelInMemoryTest.SelfReferentialProperty (InternalEntityEntry entry) => entry.ReadOriginalValue(collection, 1), CompiledModelInMemoryTest.SelfReferentialProperty (InternalEntityEntry entry) => entry.GetCurrentValue(collection), object (ValueBuffer valueBuffer) => valueBuffer[1]); @@ -118,13 +118,13 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas int (string v) => ((object)v).GetHashCode(), string (string v) => v), converter: new ValueConverter( - string (CompiledModelInMemoryTest.SelfReferentialProperty v) => null, - CompiledModelInMemoryTest.SelfReferentialProperty (string v) => null), + string (CompiledModelInMemoryTest.SelfReferentialProperty v) => CompiledModelInMemoryTest.SelfReferentialEntity.NonGeneric.SelfReferentialPropertyValueConverter.ToProvider(v), + CompiledModelInMemoryTest.SelfReferentialProperty (string v) => CompiledModelInMemoryTest.SelfReferentialEntity.NonGeneric.SelfReferentialPropertyValueConverter.FromProvider(v)), jsonValueReaderWriter: new JsonConvertedValueReaderWriter( JsonStringReaderWriter.Instance, new ValueConverter( - string (CompiledModelInMemoryTest.SelfReferentialProperty v) => null, - CompiledModelInMemoryTest.SelfReferentialProperty (string v) => null))); + string (CompiledModelInMemoryTest.SelfReferentialProperty v) => CompiledModelInMemoryTest.SelfReferentialEntity.NonGeneric.SelfReferentialPropertyValueConverter.ToProvider(v), + CompiledModelInMemoryTest.SelfReferentialProperty (string v) => CompiledModelInMemoryTest.SelfReferentialEntity.NonGeneric.SelfReferentialPropertyValueConverter.FromProvider(v)))); var key = runtimeEntityType.AddKey( new[] { id }); @@ -135,15 +135,15 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var collection = runtimeEntityType.FindProperty("Collection")!; + var id = runtimeEntityType.FindProperty("Id"); + var collection = runtimeEntityType.FindProperty("Collection"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { - var entity = ((CompiledModelInMemoryTest.SelfReferentialEntity)(source.Entity)); + var entity = ((CompiledModelInMemoryTest.SelfReferentialEntity)(source.Entity)); return ((ISnapshot)(new Snapshot(((ValueComparer)(((IProperty)id).GetValueComparer())).Snapshot(source.GetCurrentValue(id)), (source.GetCurrentValue(collection) == null ? null : ((ValueComparer)(((IProperty)collection).GetValueComparer())).Snapshot(source.GetCurrentValue(collection)))))); }); runtimeEntityType.SetStoreGeneratedValuesFactory( @@ -157,7 +157,7 @@ public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) runtimeEntityType.SetRelationshipSnapshotFactory( ISnapshot (InternalEntityEntry source) => { - var entity = ((CompiledModelInMemoryTest.SelfReferentialEntity)(source.Entity)); + var entity = ((CompiledModelInMemoryTest.SelfReferentialEntity)(source.Entity)); return ((ISnapshot)(new Snapshot(((ValueComparer)(((IProperty)id).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(id))))); }); runtimeEntityType.Counts = new PropertyCounts( diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Self_referential_property/SelfReferentialEntityUnsafeAccessors.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Self_referential_property/SelfReferentialEntityUnsafeAccessors.cs index 115dc3e01fb..7285733920a 100644 --- a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Self_referential_property/SelfReferentialEntityUnsafeAccessors.cs +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Self_referential_property/SelfReferentialEntityUnsafeAccessors.cs @@ -1,5 +1,4 @@ // -using System; using System.Runtime.CompilerServices; using Microsoft.EntityFrameworkCore.Scaffolding; @@ -8,12 +7,13 @@ namespace TestNamespace { - public static class SelfReferentialEntityUnsafeAccessors + public static class SelfReferentialEntityUnsafeAccessors + where T : struct { [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "k__BackingField")] - public static extern ref long Id(CompiledModelInMemoryTest.SelfReferentialEntity @this); + public static extern ref T Id(CompiledModelInMemoryTest.SelfReferentialEntity @this); [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "k__BackingField")] - public static extern ref CompiledModelInMemoryTest.SelfReferentialProperty Collection(CompiledModelInMemoryTest.SelfReferentialEntity @this); + public static extern ref CompiledModelInMemoryTest.SelfReferentialProperty Collection(CompiledModelInMemoryTest.SelfReferentialEntity @this); } } diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/SimpleModel/DependentDerivedEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/SimpleModel/DependentDerivedEntityType.cs index b0c187360a6..ea51d37a5c8 100644 --- a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/SimpleModel/DependentDerivedEntityType.cs +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/SimpleModel/DependentDerivedEntityType.cs @@ -126,8 +126,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var data = runtimeEntityType.FindProperty("Data")!; + var id = runtimeEntityType.FindProperty("Id"); + var data = runtimeEntityType.FindProperty("Data"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/CompiledModelInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/CompiledModelInMemoryTest.cs index a068f873459..73d200e8f14 100644 --- a/test/EFCore.InMemory.FunctionalTests/Scaffolding/CompiledModelInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/CompiledModelInMemoryTest.cs @@ -6,6 +6,7 @@ #nullable enable using System.Runtime.CompilerServices; +using System.Text.Json; using Microsoft.EntityFrameworkCore.Design.Internal; using Microsoft.EntityFrameworkCore.InMemory.Storage.Internal; using Microsoft.EntityFrameworkCore.Internal; @@ -31,45 +32,57 @@ public virtual Task Empty_model() [ConditionalFact] public virtual Task Global_namespace() => Test( - modelBuilder => modelBuilder.Entity("1", e => - { - e.Property("Id"); - e.HasKey("Id"); - }), + modelBuilder => modelBuilder.Entity( + "1", e => + { + e.Property("Id"); + e.HasKey("Id"); + }), model => { Assert.NotNull(model.FindEntityType("1")); }, - options: new CompiledModelCodeGenerationOptions { ModelNamespace = string.Empty }); + options: new CompiledModelCodeGenerationOptions { ModelNamespace = string.Empty, ForNativeAot = true }); [ConditionalFact] public virtual Task Self_referential_property() => Test( modelBuilder => - modelBuilder.Entity( - eb => - { - eb.Property(e => e.Collection).HasConversion(typeof(SelfReferentialPropertyValueConverter)); - }), + modelBuilder.Entity>(eb => + { + eb.Property(e => e.Collection) + .HasConversion.NonGeneric.SelfReferentialPropertyValueConverter>(); + }), model => { Assert.Single(model.GetEntityTypes()); } ); - public class SelfReferentialPropertyValueConverter(ConverterMappingHints hints) : ValueConverter(v => null, v => null, hints) + public class SelfReferentialEntity + where T : struct { - public SelfReferentialPropertyValueConverter() - : this(new ConverterMappingHints()) + public T Id { get; set; } + + public SelfReferentialProperty? Collection { get; set; } + + public static class NonGeneric { - } - } + public class SelfReferentialPropertyValueConverter(ConverterMappingHints hints) + : ValueConverter(v => ToProvider(v), v => FromProvider(v), hints) + { + public SelfReferentialPropertyValueConverter() + : this(new ConverterMappingHints()) + { + } - public class SelfReferentialEntity - { - public long Id { get; set; } + public static TTarget? ToProvider(SelfReferentialProperty? v) + => default; - public SelfReferentialProperty? Collection { get; set; } + public static SelfReferentialProperty? FromProvider(TTarget? v) + => null; + } + } } public class SelfReferentialProperty : List; @@ -91,7 +104,8 @@ public virtual Task Throws_for_constructor_binding() [ConditionalFact] public virtual Task Manual_lazy_loading() => Test( - modelBuilder => { + modelBuilder => + { modelBuilder.Entity(); modelBuilder.Entity( @@ -168,8 +182,7 @@ public virtual Task Lazy_loading_proxies() { var principal = new LazyProxiesEntity2 { - Id = 1, - CollectionNavigation = new List { new LazyProxiesEntity1 { Id = 1 } } + Id = 1, CollectionNavigation = new List { new() { Id = 1 } } }; c.Set().Add(principal); @@ -182,7 +195,7 @@ public virtual Task Lazy_loading_proxies() Assert.Same(principal, principal.CollectionNavigation!.Single().ReferenceNavigation); }, options => options.UseLazyLoadingProxies(), - new CompiledModelCodeGenerationOptions { UseNullableReferenceTypes = true }, + new CompiledModelCodeGenerationOptions { UseNullableReferenceTypes = true, ForNativeAot = true }, services => services.AddEntityFrameworkProxies()); [ConditionalFact] @@ -204,8 +217,7 @@ public virtual Task Lazy_loading_manual() { var principal = new LazyProxiesEntity3 { - Id = 1, - CollectionNavigation = new List { new LazyProxiesEntity4 { Id = 1 } } + Id = 1, CollectionNavigation = new List { new() { Id = 1 } } }; c.Set().Add(principal); @@ -242,9 +254,7 @@ public LazyProxiesEntity3() } protected LazyProxiesEntity3(ILazyLoader lazyLoader) - { - LazyLoader = lazyLoader; - } + => LazyLoader = lazyLoader; private ILazyLoader? LazyLoader { get; set; } @@ -271,9 +281,7 @@ public LazyProxiesEntity4() } protected LazyProxiesEntity4(Action lazyLoader) - { - LazyLoader = lazyLoader; - } + => LazyLoader = lazyLoader; private Action? LazyLoader { get; set; } @@ -320,38 +328,44 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalFact] public virtual Task Throws_for_value_generator() => Test( - modelBuilder => modelBuilder.Entity("MyEntity", e => - { - e.Property("Id").HasValueGenerator((p, e) => null!); - e.HasKey("Id"); - }), + modelBuilder => modelBuilder.Entity( + "MyEntity", e => + { + e.Property("Id").HasValueGenerator((p, e) => null!); + e.HasKey("Id"); + }), expectedExceptionMessage: DesignStrings.CompiledModelValueGenerator( "MyEntity", "Id", nameof(PropertyBuilder.HasValueGeneratorFactory))); [ConditionalFact] public virtual Task Custom_value_converter() => Test( - modelBuilder => modelBuilder.Entity("MyEntity", e => - { - e.Property("Id").HasConversion(i => i, i => i); - e.HasKey("Id"); - }), + modelBuilder => modelBuilder.Entity( + "MyEntity", e => + { + e.Property("Id").HasConversion( + i => JsonSerializer.Serialize(i, (JsonSerializerOptions?)default), + i => JsonSerializer.Deserialize(i, (JsonSerializerOptions?)null)); + e.HasKey("Id"); + }), model => { var entityType = model.GetEntityTypes().Single(); var converter = entityType.FindProperty("Id")!.GetTypeMapping().Converter!; - Assert.Equal(1, converter.ConvertToProvider(1)); - }); + Assert.Equal("1", converter.ConvertToProvider(1)); + }, + options: new CompiledModelCodeGenerationOptions { UseNullableReferenceTypes = true, ForNativeAot = true }); [ConditionalFact] public virtual Task Custom_value_comparer() => Test( - modelBuilder => modelBuilder.Entity("MyEntity", e => - { - e.Property("Id").HasConversion(typeof(int), new FakeValueComparer()); - e.HasKey("Id"); - }), + modelBuilder => modelBuilder.Entity( + "MyEntity", e => + { + e.Property("Id").HasConversion(typeof(int), new FakeValueComparer()); + e.HasKey("Id"); + }), model => { var entityType = model.GetEntityTypes().Single(); @@ -380,11 +394,12 @@ public override object Snapshot(object? instance) [ConditionalFact] public virtual Task Custom_provider_value_comparer() => Test( - modelBuilder => modelBuilder.Entity("MyEntity", e => - { - e.Property("Id").HasConversion(typeof(int), null, new FakeValueComparer()); - e.HasKey("Id"); - }), + modelBuilder => modelBuilder.Entity( + "MyEntity", e => + { + e.Property("Id").HasConversion(typeof(int), null, new FakeValueComparer()); + e.HasKey("Id"); + }), model => { var entityType = model.GetEntityTypes().Single(); @@ -400,12 +415,13 @@ is Expression> lambda [ConditionalFact] public virtual Task Custom_type_mapping() => Test( - modelBuilder => modelBuilder.Entity("MyEntity", e => - { - e.Property("Id").Metadata.SetTypeMapping( + modelBuilder => modelBuilder.Entity( + "MyEntity", e => + { + e.Property("Id").Metadata.SetTypeMapping( new InMemoryTypeMapping(typeof(int), jsonValueReaderWriter: JsonInt32ReaderWriter.Instance)); - e.HasKey("Id"); - }), + e.HasKey("Id"); + }), model => { var entityType = model.GetEntityTypes().Single(); @@ -418,10 +434,11 @@ public virtual Task Custom_type_mapping() [ConditionalFact] public virtual Task Fully_qualified_model() => Test( - modelBuilder => { + modelBuilder => + { modelBuilder.Entity(); modelBuilder.Entity(); - modelBuilder.Entity( + modelBuilder.Entity( eb => { eb.HasDiscriminator().HasValue("DerivedIdentityUser"); @@ -433,7 +450,7 @@ public virtual Task Fully_qualified_model() Assert.Equal(4, model.GetEntityTypes().Count()); Assert.Same(model, model.FindRuntimeAnnotationValue("ReadOnlyModel")); }, - options: new CompiledModelCodeGenerationOptions { ModelNamespace = "Scaffolding" }, + options: new CompiledModelCodeGenerationOptions { ModelNamespace = "Scaffolding", ForNativeAot = true }, addDesignTimeServices: services => services.AddSingleton()); [ConditionalFact] @@ -441,7 +458,7 @@ public virtual Task RelationshipCycles() => Test( BuildCyclesModel, AssertCyclesModel, - options: new CompiledModelCodeGenerationOptions { UseNullableReferenceTypes = true }); + options: new CompiledModelCodeGenerationOptions { UseNullableReferenceTypes = true, ForNativeAot = true }); protected virtual void BuildCyclesModel(ModelBuilder modelBuilder) { @@ -511,8 +528,11 @@ protected override bool ShouldUseFullName(string shortTypeName) => base.ShouldUseFullName(shortTypeName) || shortTypeName is nameof(System.Index) or nameof(Internal); } - protected override TestHelpers TestHelpers => InMemoryTestHelpers.Instance; - protected override ITestStoreFactory TestStoreFactory => InMemoryTestStoreFactory.Instance; + protected override TestHelpers TestHelpers + => InMemoryTestHelpers.Instance; + + protected override ITestStoreFactory TestStoreFactory + => InMemoryTestStoreFactory.Instance; protected override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) => base.AddOptions(builder) diff --git a/test/EFCore.InMemory.FunctionalTests/ShadowStateUpdateTest.cs b/test/EFCore.InMemory.FunctionalTests/ShadowStateUpdateTest.cs index 9a3f75ba2e5..8dfa647fc22 100644 --- a/test/EFCore.InMemory.FunctionalTests/ShadowStateUpdateTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/ShadowStateUpdateTest.cs @@ -80,9 +80,7 @@ public async Task Can_add_update_delete_end_to_end_using_partial_shadow_state() private class Customer { private Customer(object[] values) - { - Id = (int)values[0]; - } + => Id = (int)values[0]; public Customer() { diff --git a/test/EFCore.InMemory.FunctionalTests/StoreGeneratedFixupInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/StoreGeneratedFixupInMemoryTest.cs index 589eeaaf615..24982ced5f5 100644 --- a/test/EFCore.InMemory.FunctionalTests/StoreGeneratedFixupInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/StoreGeneratedFixupInMemoryTest.cs @@ -5,8 +5,9 @@ namespace Microsoft.EntityFrameworkCore; -public class StoreGeneratedFixupInMemoryTest(StoreGeneratedFixupInMemoryTest.StoreGeneratedFixupInMemoryFixture fixture) : StoreGeneratedFixupTestBase< - StoreGeneratedFixupInMemoryTest.StoreGeneratedFixupInMemoryFixture>(fixture) +public class StoreGeneratedFixupInMemoryTest(StoreGeneratedFixupInMemoryTest.StoreGeneratedFixupInMemoryFixture fixture) + : StoreGeneratedFixupTestBase< + StoreGeneratedFixupInMemoryTest.StoreGeneratedFixupInMemoryFixture>(fixture) { public override void Temporary_value_equals_database_generated_value() { diff --git a/test/EFCore.InMemory.FunctionalTests/UpdatesInMemoryWithSensitiveDataLoggingTest.cs b/test/EFCore.InMemory.FunctionalTests/UpdatesInMemoryWithSensitiveDataLoggingTest.cs index 9e6ab16d058..da4f9f3e979 100644 --- a/test/EFCore.InMemory.FunctionalTests/UpdatesInMemoryWithSensitiveDataLoggingTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/UpdatesInMemoryWithSensitiveDataLoggingTest.cs @@ -5,8 +5,9 @@ namespace Microsoft.EntityFrameworkCore; -public class UpdatesInMemoryWithSensitiveDataLoggingTest(UpdatesInMemoryWithSensitiveDataLoggingTest.UpdatesInMemoryWithSensitiveDataLoggingFixture fixture) - : UpdatesInMemoryTestBase(fixture) +public class UpdatesInMemoryWithSensitiveDataLoggingTest( + UpdatesInMemoryWithSensitiveDataLoggingTest.UpdatesInMemoryWithSensitiveDataLoggingFixture fixture) + : UpdatesInMemoryTestBase(fixture) { protected override string UpdateConcurrencyTokenMessage => InMemoryStrings.UpdateConcurrencyTokenExceptionSensitive( diff --git a/test/EFCore.InMemory.FunctionalTests/UpdatesInMemoryWithoutSensitiveDataLoggingTest.cs b/test/EFCore.InMemory.FunctionalTests/UpdatesInMemoryWithoutSensitiveDataLoggingTest.cs index 99ac79afb33..4421cddf0f9 100644 --- a/test/EFCore.InMemory.FunctionalTests/UpdatesInMemoryWithoutSensitiveDataLoggingTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/UpdatesInMemoryWithoutSensitiveDataLoggingTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore; -public class UpdatesInMemoryWithoutSensitiveDataLoggingTest(UpdatesInMemoryWithoutSensitiveDataLoggingTest.UpdatesInMemoryWithoutSensitiveDataLoggingFixture fixture) +public class UpdatesInMemoryWithoutSensitiveDataLoggingTest( + UpdatesInMemoryWithoutSensitiveDataLoggingTest.UpdatesInMemoryWithoutSensitiveDataLoggingFixture fixture) : UpdatesInMemoryTestBase(fixture) { protected override string UpdateConcurrencyTokenMessage diff --git a/test/EFCore.InMemory.Tests/Storage/InMemoryDatabaseCreatorTest.cs b/test/EFCore.InMemory.Tests/Storage/InMemoryDatabaseCreatorTest.cs index 6b4fb66192a..19fe82ac5f7 100644 --- a/test/EFCore.InMemory.Tests/Storage/InMemoryDatabaseCreatorTest.cs +++ b/test/EFCore.InMemory.Tests/Storage/InMemoryDatabaseCreatorTest.cs @@ -46,7 +46,30 @@ private static InMemoryDatabaseCreator CreateDatabaseCreator(IServiceProvider se optionsBuilder.UseInMemoryDatabase(nameof(InMemoryDatabaseCreatorTest)); var contextServices = InMemoryTestHelpers.Instance.CreateContextServices(serviceProvider, optionsBuilder.Options); - return new InMemoryDatabaseCreator(contextServices.GetRequiredService()); + return new InMemoryDatabaseCreator( + contextServices.GetRequiredService(), + contextServices.GetRequiredService(), + contextServices.GetRequiredService()); + } + + [ConditionalFact] + public void EnsureCreated_throws_for_missing_seed() + { + using var context = new FraggleContext(asyncSeed: true); + + Assert.Equal( + CoreStrings.MissingSeeder, + Assert.Throws(() => context.Database.EnsureCreated()).Message); + } + + [ConditionalFact] + public async Task EnsureCreatedAsync_throws_for_missing_seed() + { + using var context = new FraggleContext(seed: true); + + Assert.Equal( + CoreStrings.MissingSeeder, + (await Assert.ThrowsAsync(() => context.Database.EnsureCreatedAsync())).Message); } [ConditionalFact] @@ -100,15 +123,27 @@ private static async Task Delete_clears_all_in_memory_data_test(bool async) } } - private class FraggleContext : DbContext + private class FraggleContext(bool seed = false, bool asyncSeed = false) : DbContext { // ReSharper disable once UnusedAutoPropertyAccessor.Local public DbSet Fraggles { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - => optionsBuilder + { + optionsBuilder .UseInternalServiceProvider(InMemoryFixture.DefaultServiceProvider) .UseInMemoryDatabase(nameof(FraggleContext)); + + if (seed) + { + optionsBuilder.UseSeeding((_, __) => { }); + } + + if (asyncSeed) + { + optionsBuilder.UseAsyncSeeding((_, __, ___) => Task.CompletedTask); + } + } } private class Fraggle diff --git a/test/EFCore.InMemory.Tests/ValueGeneration/InMemoryIntegerValueGeneratorTest.cs b/test/EFCore.InMemory.Tests/ValueGeneration/InMemoryIntegerValueGeneratorTest.cs index b9cef3f4bea..711dd3eacf2 100644 --- a/test/EFCore.InMemory.Tests/ValueGeneration/InMemoryIntegerValueGeneratorTest.cs +++ b/test/EFCore.InMemory.Tests/ValueGeneration/InMemoryIntegerValueGeneratorTest.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. - // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. diff --git a/test/EFCore.InMemory.Tests/ValueGeneration/InMemoryValueGeneratorSelectorTest.cs b/test/EFCore.InMemory.Tests/ValueGeneration/InMemoryValueGeneratorSelectorTest.cs index c0987d6155a..c3345646048 100644 --- a/test/EFCore.InMemory.Tests/ValueGeneration/InMemoryValueGeneratorSelectorTest.cs +++ b/test/EFCore.InMemory.Tests/ValueGeneration/InMemoryValueGeneratorSelectorTest.cs @@ -49,26 +49,46 @@ public void Returns_built_in_generators_for_types_setup_for_value_generation_usi var selector = InMemoryTestHelpers.Instance.CreateContextServices(model).GetRequiredService(); - Assert.IsType(selector.TrySelect(entityType.FindProperty("Custom")!, entityType, out var generator) ? generator : null); - Assert.IsType>(selector.TrySelect(entityType.FindProperty("Id")!, entityType, out generator) ? generator : null); - Assert.IsType>(selector.TrySelect(entityType.FindProperty("Long")!, entityType, out generator) ? generator : null); - Assert.IsType>(selector.TrySelect(entityType.FindProperty("Short")!, entityType, out generator) ? generator : null); - Assert.IsType>(selector.TrySelect(entityType.FindProperty("Byte")!, entityType, out generator) ? generator : null); - Assert.IsType>(selector.TrySelect(entityType.FindProperty("NullableInt")!, entityType, out generator) ? generator : null); - Assert.IsType>(selector.TrySelect(entityType.FindProperty("NullableLong")!, entityType, out generator) ? generator : null); - Assert.IsType>(selector.TrySelect(entityType.FindProperty("NullableShort")!, entityType, out generator) ? generator : null); - Assert.IsType>(selector.TrySelect(entityType.FindProperty("NullableByte")!, entityType, out generator) ? generator : null); - Assert.IsType>(selector.TrySelect(entityType.FindProperty("UInt")!, entityType, out generator) ? generator : null); - Assert.IsType>(selector.TrySelect(entityType.FindProperty("ULong")!, entityType, out generator) ? generator : null); - Assert.IsType>(selector.TrySelect(entityType.FindProperty("UShort")!, entityType, out generator) ? generator : null); - Assert.IsType>(selector.TrySelect(entityType.FindProperty("SByte")!, entityType, out generator) ? generator : null); - Assert.IsType>(selector.TrySelect(entityType.FindProperty("NullableUInt")!, entityType, out generator) ? generator : null); - Assert.IsType>(selector.TrySelect(entityType.FindProperty("NullableULong")!, entityType, out generator) ? generator : null); - Assert.IsType>(selector.TrySelect(entityType.FindProperty("NullableUShort")!, entityType, out generator) ? generator : null); - Assert.IsType>(selector.TrySelect(entityType.FindProperty("NullableSByte")!, entityType, out generator) ? generator : null); - Assert.IsType(selector.TrySelect(entityType.FindProperty("String")!, entityType, out generator) ? generator : null); - Assert.IsType(selector.TrySelect(entityType.FindProperty("Guid")!, entityType, out generator) ? generator : null); - Assert.IsType(selector.TrySelect(entityType.FindProperty("Binary")!, entityType, out generator) ? generator : null); + Assert.IsType( + selector.TrySelect(entityType.FindProperty("Custom")!, entityType, out var generator) ? generator : null); + Assert.IsType>( + selector.TrySelect(entityType.FindProperty("Id")!, entityType, out generator) ? generator : null); + Assert.IsType>( + selector.TrySelect(entityType.FindProperty("Long")!, entityType, out generator) ? generator : null); + Assert.IsType>( + selector.TrySelect(entityType.FindProperty("Short")!, entityType, out generator) ? generator : null); + Assert.IsType>( + selector.TrySelect(entityType.FindProperty("Byte")!, entityType, out generator) ? generator : null); + Assert.IsType>( + selector.TrySelect(entityType.FindProperty("NullableInt")!, entityType, out generator) ? generator : null); + Assert.IsType>( + selector.TrySelect(entityType.FindProperty("NullableLong")!, entityType, out generator) ? generator : null); + Assert.IsType>( + selector.TrySelect(entityType.FindProperty("NullableShort")!, entityType, out generator) ? generator : null); + Assert.IsType>( + selector.TrySelect(entityType.FindProperty("NullableByte")!, entityType, out generator) ? generator : null); + Assert.IsType>( + selector.TrySelect(entityType.FindProperty("UInt")!, entityType, out generator) ? generator : null); + Assert.IsType>( + selector.TrySelect(entityType.FindProperty("ULong")!, entityType, out generator) ? generator : null); + Assert.IsType>( + selector.TrySelect(entityType.FindProperty("UShort")!, entityType, out generator) ? generator : null); + Assert.IsType>( + selector.TrySelect(entityType.FindProperty("SByte")!, entityType, out generator) ? generator : null); + Assert.IsType>( + selector.TrySelect(entityType.FindProperty("NullableUInt")!, entityType, out generator) ? generator : null); + Assert.IsType>( + selector.TrySelect(entityType.FindProperty("NullableULong")!, entityType, out generator) ? generator : null); + Assert.IsType>( + selector.TrySelect(entityType.FindProperty("NullableUShort")!, entityType, out generator) ? generator : null); + Assert.IsType>( + selector.TrySelect(entityType.FindProperty("NullableSByte")!, entityType, out generator) ? generator : null); + Assert.IsType( + selector.TrySelect(entityType.FindProperty("String")!, entityType, out generator) ? generator : null); + Assert.IsType( + selector.TrySelect(entityType.FindProperty("Guid")!, entityType, out generator) ? generator : null); + Assert.IsType( + selector.TrySelect(entityType.FindProperty("Binary")!, entityType, out generator) ? generator : null); } [ConditionalTheory] diff --git a/test/EFCore.NativeAotTests/EFCore.NativeAotTests.csproj b/test/EFCore.NativeAotTests/EFCore.NativeAotTests.csproj index 4d8d1305f54..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.OData.FunctionalTests/Query/ComplexNavigationsODataQueryTestFixture.cs b/test/EFCore.OData.FunctionalTests/Query/ComplexNavigationsODataQueryTestFixture.cs index b23140662de..dffd4677e47 100644 --- a/test/EFCore.OData.FunctionalTests/Query/ComplexNavigationsODataQueryTestFixture.cs +++ b/test/EFCore.OData.FunctionalTests/Query/ComplexNavigationsODataQueryTestFixture.cs @@ -16,10 +16,8 @@ protected override string StoreName => "ODataComplexNavigations"; public ComplexNavigationsODataQueryTestFixture() - { - (BaseAddress, ClientFactory, _selfHostServer) + => (BaseAddress, ClientFactory, _selfHostServer) = ODataQueryTestFixtureInitializer.Initialize(StoreName, GetEdmModel()); - } private static IEdmModel GetEdmModel() { diff --git a/test/EFCore.OData.FunctionalTests/Query/ComplexNavigationsODataQueryTests.cs b/test/EFCore.OData.FunctionalTests/Query/ComplexNavigationsODataQueryTests.cs index abb3a3cbd1a..b53523594b7 100644 --- a/test/EFCore.OData.FunctionalTests/Query/ComplexNavigationsODataQueryTests.cs +++ b/test/EFCore.OData.FunctionalTests/Query/ComplexNavigationsODataQueryTests.cs @@ -7,7 +7,8 @@ namespace Microsoft.EntityFrameworkCore.Query; -public class ComplexNavigationsODataQueryTests(ComplexNavigationsODataQueryTestFixture fixture) : ODataQueryTestBase(fixture), IClassFixture +public class ComplexNavigationsODataQueryTests(ComplexNavigationsODataQueryTestFixture fixture) + : ODataQueryTestBase(fixture), IClassFixture { [ConditionalFact] public async Task Query_level_ones() diff --git a/test/EFCore.OData.FunctionalTests/Query/GearsOfWarODataQueryTestFixture.cs b/test/EFCore.OData.FunctionalTests/Query/GearsOfWarODataQueryTestFixture.cs index e62ff277de8..02a2c8cf189 100644 --- a/test/EFCore.OData.FunctionalTests/Query/GearsOfWarODataQueryTestFixture.cs +++ b/test/EFCore.OData.FunctionalTests/Query/GearsOfWarODataQueryTestFixture.cs @@ -16,10 +16,8 @@ protected override string StoreName => "ODataGearsOfWarQueryTest"; public GearsOfWarODataQueryTestFixture() - { - (BaseAddress, ClientFactory, _selfHostServer) + => (BaseAddress, ClientFactory, _selfHostServer) = ODataQueryTestFixtureInitializer.Initialize(StoreName, GetEdmModel()); - } private static IEdmModel GetEdmModel() { diff --git a/test/EFCore.OData.FunctionalTests/Query/GearsOfWarODataQueryTests.cs b/test/EFCore.OData.FunctionalTests/Query/GearsOfWarODataQueryTests.cs index a4388b98d18..cad179ec81d 100644 --- a/test/EFCore.OData.FunctionalTests/Query/GearsOfWarODataQueryTests.cs +++ b/test/EFCore.OData.FunctionalTests/Query/GearsOfWarODataQueryTests.cs @@ -7,7 +7,8 @@ namespace Microsoft.EntityFrameworkCore.Query; -public class GearsOfWarODataQueryTests(GearsOfWarODataQueryTestFixture fixture) : ODataQueryTestBase(fixture), IClassFixture +public class GearsOfWarODataQueryTests(GearsOfWarODataQueryTestFixture fixture) + : ODataQueryTestBase(fixture), IClassFixture { [ConditionalFact] public async Task Basic_query_gears() diff --git a/test/EFCore.OData.FunctionalTests/Query/NorthwindODataQueryTestFixture.cs b/test/EFCore.OData.FunctionalTests/Query/NorthwindODataQueryTestFixture.cs index 4f78ca62ad9..52ccbfffc94 100644 --- a/test/EFCore.OData.FunctionalTests/Query/NorthwindODataQueryTestFixture.cs +++ b/test/EFCore.OData.FunctionalTests/Query/NorthwindODataQueryTestFixture.cs @@ -19,13 +19,11 @@ protected override string StoreName => "ODataNorthwind"; public NorthwindODataQueryTestFixture() - { - (BaseAddress, ClientFactory, _selfHostServer) + => (BaseAddress, ClientFactory, _selfHostServer) = ODataQueryTestFixtureInitializer.Initialize( StoreName, GetEdmModel(), [new OrderDetailsControllerActionConvention()]); - } private static IEdmModel GetEdmModel() { diff --git a/test/EFCore.OData.FunctionalTests/Query/NorthwindODataQueryTests.cs b/test/EFCore.OData.FunctionalTests/Query/NorthwindODataQueryTests.cs index e05ec472681..f656928f57b 100644 --- a/test/EFCore.OData.FunctionalTests/Query/NorthwindODataQueryTests.cs +++ b/test/EFCore.OData.FunctionalTests/Query/NorthwindODataQueryTests.cs @@ -7,7 +7,8 @@ namespace Microsoft.EntityFrameworkCore.Query; -public class NorthwindODataQueryTests(NorthwindODataQueryTestFixture fixture) : ODataQueryTestBase(fixture), IClassFixture +public class NorthwindODataQueryTests(NorthwindODataQueryTestFixture fixture) + : ODataQueryTestBase(fixture), IClassFixture { [ConditionalFact] public async Task Basic_query_customers() diff --git a/test/EFCore.OData.FunctionalTests/TestControllers.cs b/test/EFCore.OData.FunctionalTests/TestControllers.cs index 62778f563ab..56fb978d66d 100644 --- a/test/EFCore.OData.FunctionalTests/TestControllers.cs +++ b/test/EFCore.OData.FunctionalTests/TestControllers.cs @@ -93,25 +93,19 @@ public class TestOkObjectResult : TestObjectResult { public TestOkObjectResult(object innerResult) : base(innerResult) - { - StatusCode = 200; - } + => StatusCode = 200; } public class TestOkObjectResult : TestObjectResult { public TestOkObjectResult(object innerResult) : base(innerResult) - { - StatusCode = 200; - } + => StatusCode = 200; public TestOkObjectResult(T content, TestODataController controller) : base(content) - { - // Controller is unused. - StatusCode = 200; - } + // Controller is unused. + => StatusCode = 200; } public class TestStatusCodeObjectResult(ObjectResult innerResult) : TestObjectResult(innerResult); diff --git a/test/EFCore.Proxies.Tests/ChangeDetectionProxyTests.cs b/test/EFCore.Proxies.Tests/ChangeDetectionProxyTests.cs index a79d9d7e3f5..29acbdab89d 100644 --- a/test/EFCore.Proxies.Tests/ChangeDetectionProxyTests.cs +++ b/test/EFCore.Proxies.Tests/ChangeDetectionProxyTests.cs @@ -313,8 +313,8 @@ private class ChangeContext( bool useLazyLoading = false, bool checkEquality = true, Action> entityBuilderAction = null) : TestContext( - dbName: "ChangeDetectionContext", useLazyLoading: useLazyLoading, useChangeDetection: true, - checkEquality: checkEquality) + dbName: "ChangeDetectionContext", useLazyLoading: useLazyLoading, useChangeDetection: true, + checkEquality: checkEquality) where TEntity : class { private readonly Action> _entityBuilderAction = entityBuilderAction; diff --git a/test/EFCore.Proxies.Tests/ProxiesApiConsistencyTest.cs b/test/EFCore.Proxies.Tests/ProxiesApiConsistencyTest.cs index 2d264014772..d8fbbdc6469 100644 --- a/test/EFCore.Proxies.Tests/ProxiesApiConsistencyTest.cs +++ b/test/EFCore.Proxies.Tests/ProxiesApiConsistencyTest.cs @@ -3,7 +3,8 @@ namespace Microsoft.EntityFrameworkCore; -public class ProxiesApiConsistencyTest(ProxiesApiConsistencyTest.ProxiesApiConsistencyFixture fixture) : ApiConsistencyTestBase(fixture) +public class ProxiesApiConsistencyTest(ProxiesApiConsistencyTest.ProxiesApiConsistencyFixture fixture) + : ApiConsistencyTestBase(fixture) { protected override void AddServices(ServiceCollection serviceCollection) => serviceCollection.AddEntityFrameworkProxies(); diff --git a/test/EFCore.Proxies.Tests/ProxyTests.cs b/test/EFCore.Proxies.Tests/ProxyTests.cs index 80c87439beb..bd88895f110 100644 --- a/test/EFCore.Proxies.Tests/ProxyTests.cs +++ b/test/EFCore.Proxies.Tests/ProxyTests.cs @@ -336,10 +336,11 @@ public record IndyCar; private class NeweyContext(string dbName = null, bool useLazyLoading = true, bool useChangeDetection = false) : DbContext { private readonly IServiceProvider _internalServiceProvider - = new ServiceCollection() - .AddEntityFrameworkInMemoryDatabase() - .AddEntityFrameworkProxies() - .BuildServiceProvider(validateScopes: true); + = new ServiceCollection() + .AddEntityFrameworkInMemoryDatabase() + .AddEntityFrameworkProxies() + .BuildServiceProvider(validateScopes: true); + private static readonly InMemoryDatabaseRoot _dbRoot = new(); private readonly bool _useLazyLoadingProxies = useLazyLoading; private readonly bool _useChangeDetectionProxies = useChangeDetection; @@ -351,9 +352,7 @@ public NeweyContext( bool useLazyLoading = true, bool useChangeDetection = false) : this(dbName, useLazyLoading, useChangeDetection) - { - _internalServiceProvider = internalServiceProvider; - } + => _internalServiceProvider = internalServiceProvider; protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { diff --git a/test/EFCore.Relational.Specification.Tests/BulkUpdates/NonSharedModelBulkUpdatesRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/BulkUpdates/NonSharedModelBulkUpdatesRelationalTestBase.cs index c3dc5ad63d8..dd1d733fbb0 100644 --- a/test/EFCore.Relational.Specification.Tests/BulkUpdates/NonSharedModelBulkUpdatesRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/BulkUpdates/NonSharedModelBulkUpdatesRelationalTestBase.cs @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.ComponentModel.DataAnnotations.Schema; + namespace Microsoft.EntityFrameworkCore.BulkUpdates; #nullable disable @@ -27,6 +29,7 @@ await AssertTranslationFailedWithDetails( context => context.Set(), rowsAffectedCount: 0), RelationalStrings.ExecuteDeleteOnTableSplitting(nameof(Owner))); } + [ConditionalTheory] [MemberData(nameof(IsAsyncData))] public virtual async Task Update_main_table_in_entity_with_entity_splitting(bool async) @@ -83,6 +86,86 @@ await AssertUpdate( rowsAffectedCount: 1); } + [ConditionalTheory] // #34677 + [MemberData(nameof(IsAsyncData))] + public virtual async Task Delete_with_view_mapping(bool async) + { + var contextFactory = await InitializeAsync(seed: async context => await context.Seed()); + + await AssertDelete( + async, + contextFactory.CreateContext, + ss => ss.Foos, + rowsAffectedCount: 1); + } + + [ConditionalTheory] // #34677 + [MemberData(nameof(IsAsyncData))] + public virtual async Task Update_with_view_mapping(bool async) + { + var contextFactory = await InitializeAsync(seed: async context => await context.Seed()); + + await AssertUpdate( + async, + contextFactory.CreateContext, + ss => ss.Foos, + s => s.SetProperty(f => f.Data, "Updated"), + rowsAffectedCount: 1); + } + + [ConditionalTheory] // #34677, #34706 + [MemberData(nameof(IsAsyncData))] + public virtual async Task Update_complex_type_with_view_mapping(bool async) + { + var contextFactory = await InitializeAsync(seed: async context => await context.Seed()); + + // #34706 + await Assert.ThrowsAsync(() => AssertUpdate( + async, + contextFactory.CreateContext, + ss => ss.Foos, + s => s.SetProperty(f => f.ComplexThing, new Context34677.ComplexThing { Prop1 = 3, Prop2 = 4 }), + rowsAffectedCount: 1)); + } + + protected class Context34677(DbContextOptions options) : DbContext(options) + { + public DbSet Foos + => Set(); + + protected override void OnModelCreating(ModelBuilder modelBuilder) + => modelBuilder.Entity(eb => eb + .ToTable("Blogs") + .ToView("BlogsView") + .ComplexProperty(b => b.ComplexThing).IsRequired()); + + public async Task Seed() + { + Add( + new Foo + { + Id = 1, + Data = "Data", + ComplexThing = new ComplexThing { Prop1 = 1, Prop2 = 2 } + }); + await SaveChangesAsync(); + } + + public class Foo + { + [DatabaseGenerated(DatabaseGeneratedOption.None)] + public int Id { get; set; } + public string Data { get; set; } + public ComplexThing ComplexThing { get; set; } + } + + public class ComplexThing + { + public int Prop1 { get; set; } + public int Prop2 { get; set; } + } + } + #region HelperMethods protected static async Task AssertTranslationFailedWithDetails(Func query, string details) diff --git a/test/EFCore.Relational.Specification.Tests/BulkUpdates/NorthwindBulkUpdatesRelationalFixture.cs b/test/EFCore.Relational.Specification.Tests/BulkUpdates/NorthwindBulkUpdatesRelationalFixture.cs index 3ea28305a1f..1878095aa3b 100644 --- a/test/EFCore.Relational.Specification.Tests/BulkUpdates/NorthwindBulkUpdatesRelationalFixture.cs +++ b/test/EFCore.Relational.Specification.Tests/BulkUpdates/NorthwindBulkUpdatesRelationalFixture.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore.BulkUpdates; #nullable disable -public abstract class NorthwindBulkUpdatesRelationalFixture : NorthwindBulkUpdatesFixture, ITestSqlLoggerFactory +public abstract class NorthwindBulkUpdatesRelationalFixture : NorthwindBulkUpdatesFixture, + ITestSqlLoggerFactory where TModelCustomizer : ITestModelCustomizer, new() { public new RelationalTestStore TestStore 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 e3e6935f96b..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,12 +49,7 @@ - - - - - - + diff --git a/test/EFCore.Relational.Specification.Tests/LoggingRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/LoggingRelationalTestBase.cs index 76a247782f8..67b0b5f213d 100644 --- a/test/EFCore.Relational.Specification.Tests/LoggingRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/LoggingRelationalTestBase.cs @@ -64,7 +64,8 @@ public virtual void IndexPropertiesBothMappedAndNotMappedToTable_throws_by_defau () => context.Model).Message); } - protected class IndexPropertiesBothMappedAndNotMappedToTableContext(DbContextOptionsBuilder optionsBuilder) : DbContext(optionsBuilder.Options) + protected class IndexPropertiesBothMappedAndNotMappedToTableContext(DbContextOptionsBuilder optionsBuilder) + : DbContext(optionsBuilder.Options) { protected override void OnModelCreating(ModelBuilder modelBuilder) { @@ -89,7 +90,8 @@ public virtual void UnnamedIndexPropertiesMappedToNonOverlappingTables_throws_by () => context.Model).Message); } - protected class UnnamedIndexPropertiesMappedToNonOverlappingTablesContext(DbContextOptionsBuilder optionsBuilder) : DbContext(optionsBuilder.Options) + protected class UnnamedIndexPropertiesMappedToNonOverlappingTablesContext(DbContextOptionsBuilder optionsBuilder) + : DbContext(optionsBuilder.Options) { protected override void OnModelCreating(ModelBuilder modelBuilder) { @@ -121,7 +123,8 @@ public virtual void ForeignKeyPropertiesMappedToUnrelatedTables_throws_by_defaul () => context.Model).Message); } - protected class ForeignKeyPropertiesMappedToUnrelatedTablesContext(DbContextOptionsBuilder optionsBuilder) : DbContext(optionsBuilder.Options) + protected class ForeignKeyPropertiesMappedToUnrelatedTablesContext(DbContextOptionsBuilder optionsBuilder) + : DbContext(optionsBuilder.Options) { protected override void OnModelCreating(ModelBuilder modelBuilder) { diff --git a/test/EFCore.Relational.Specification.Tests/Migrations/MigrationsInfrastructureTestBase.cs b/test/EFCore.Relational.Specification.Tests/Migrations/MigrationsInfrastructureTestBase.cs index f5baf42669c..e7c079cc774 100644 --- a/test/EFCore.Relational.Specification.Tests/Migrations/MigrationsInfrastructureTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Migrations/MigrationsInfrastructureTestBase.cs @@ -3,8 +3,6 @@ // ReSharper disable InconsistentNaming -using Microsoft.EntityFrameworkCore.Diagnostics.Internal; - namespace Microsoft.EntityFrameworkCore.Migrations; #nullable disable @@ -19,6 +17,7 @@ protected MigrationsInfrastructureTestBase(TFixture fixture) Fixture = fixture; Fixture.TestStore.CloseConnection(); Fixture.TestSqlLoggerFactory.Clear(); + Fixture.ResetCounts(); } protected string Sql { get; private set; } @@ -71,12 +70,9 @@ public virtual void Can_apply_all_migrations() GiveMeSomeTime(db); - MigrationsInfrastructureFixtureBase.MigratorPlugin.ResetCounts(); - db.Database.Migrate((c, d) => - { - c.Add(new MigrationsInfrastructureFixtureBase.Foo { Id = 1, Bar = 10, Description = "Test" }); - c.SaveChanges(); - }); + Assert.Equal(0, Fixture.SeedCallCount); + + db.Database.Migrate(); var history = db.GetService(); Assert.Collection( @@ -89,12 +85,8 @@ public virtual void Can_apply_all_migrations() x => Assert.Equal("00000000000006_Migration6", x.MigrationId), x => Assert.Equal("00000000000007_Migration7", x.MigrationId)); - Assert.NotNull(db.Find(1)); - - Assert.Equal(1, MigrationsInfrastructureFixtureBase.MigratorPlugin.MigratingCallCount); - Assert.Equal(1, MigrationsInfrastructureFixtureBase.MigratorPlugin.MigratedCallCount); - Assert.Equal(0, MigrationsInfrastructureFixtureBase.MigratorPlugin.MigratingAsyncCallCount); - Assert.Equal(0, MigrationsInfrastructureFixtureBase.MigratorPlugin.MigratedAsyncCallCount); + Assert.Equal(1, Fixture.SeedCallCount); + Assert.Equal(0, Fixture.SeedAsyncCallCount); } [ConditionalFact] @@ -105,12 +97,9 @@ public virtual async Task Can_apply_all_migrations_async() await GiveMeSomeTimeAsync(db); - MigrationsInfrastructureFixtureBase.MigratorPlugin.ResetCounts(); - await db.Database.MigrateAsync(async (c, d, ct) => - { - c.Add(new MigrationsInfrastructureFixtureBase.Foo { Id = 1, Bar = 10, Description = "Test" }); - await c.SaveChangesAsync(ct); - }); + Assert.Equal(0, Fixture.SeedAsyncCallCount); + + await db.Database.MigrateAsync(); var history = db.GetService(); Assert.Collection( @@ -123,12 +112,8 @@ await history.GetAppliedMigrationsAsync(), x => Assert.Equal("00000000000006_Migration6", x.MigrationId), x => Assert.Equal("00000000000007_Migration7", x.MigrationId)); - Assert.NotNull(await db.FindAsync(1)); - - Assert.Equal(0, MigrationsInfrastructureFixtureBase.MigratorPlugin.MigratingCallCount); - Assert.Equal(0, MigrationsInfrastructureFixtureBase.MigratorPlugin.MigratedCallCount); - Assert.Equal(1, MigrationsInfrastructureFixtureBase.MigratorPlugin.MigratingAsyncCallCount); - Assert.Equal(1, MigrationsInfrastructureFixtureBase.MigratorPlugin.MigratedAsyncCallCount); + Assert.Equal(0, Fixture.SeedCallCount); + Assert.Equal(1, Fixture.SeedAsyncCallCount); } [ConditionalFact] @@ -139,7 +124,7 @@ public virtual void Can_apply_range_of_migrations() GiveMeSomeTime(db); - db.Database.Migrate(null, "Migration6"); + db.Database.Migrate("Migration6"); var history = db.GetService(); Assert.Collection( @@ -161,14 +146,15 @@ public virtual void Can_apply_one_migration() GiveMeSomeTime(db); var migrator = db.GetService(); - migrator.Migrate(targetMigration: "Migration1"); + migrator.Migrate("Migration1"); var history = db.GetService(); Assert.Collection( history.GetAppliedMigrations(), x => Assert.Equal("00000000000001_Migration1", x.MigrationId)); - Assert.Equal(LogLevel.Error, + Assert.Equal( + LogLevel.Error, Fixture.TestSqlLoggerFactory.Log.Single(l => l.Id == RelationalEventId.PendingModelChangesWarning).Level); } @@ -181,8 +167,8 @@ public virtual void Can_revert_all_migrations() GiveMeSomeTime(db); var migrator = db.GetService(); - migrator.Migrate(targetMigration: "Migration5"); - migrator.Migrate(targetMigration: Migration.InitialDatabase); + migrator.Migrate("Migration5"); + migrator.Migrate(Migration.InitialDatabase); var history = db.GetService(); Assert.Empty(history.GetAppliedMigrations()); @@ -197,8 +183,8 @@ public virtual void Can_revert_one_migrations() GiveMeSomeTime(db); var migrator = db.GetService(); - migrator.Migrate(targetMigration: "Migration5"); - migrator.Migrate(targetMigration: "Migration4"); + migrator.Migrate("Migration5"); + migrator.Migrate("Migration4"); var history = db.GetService(); Assert.Collection( @@ -217,12 +203,13 @@ public virtual void Can_apply_one_migration_in_parallel() GiveMeSomeTime(db); db.GetService().Create(); - Parallel.For(0, Environment.ProcessorCount, i => - { - using var context = Fixture.CreateContext(); - var migrator = context.GetService(); - migrator.Migrate(targetMigration: "Migration1"); - }); + Parallel.For( + 0, Environment.ProcessorCount, i => + { + using var context = Fixture.CreateContext(); + var migrator = context.GetService(); + migrator.Migrate("Migration1"); + }); var history = db.GetService(); Assert.Collection( @@ -238,12 +225,13 @@ public virtual async Task Can_apply_one_migration_in_parallel_async() await GiveMeSomeTimeAsync(db); await db.GetService().CreateAsync(); - await Parallel.ForAsync(0, Environment.ProcessorCount, async (i, _) => - { - using var context = Fixture.CreateContext(); - var migrator = context.GetService(); - await migrator.MigrateAsync(targetMigration: "Migration1"); - }); + await Parallel.ForAsync( + 0, Environment.ProcessorCount, async (i, _) => + { + using var context = Fixture.CreateContext(); + var migrator = context.GetService(); + await migrator.MigrateAsync("Migration1"); + }); var history = db.GetService(); Assert.Collection( @@ -257,14 +245,15 @@ public virtual void Can_apply_second_migration_in_parallel() using var db = Fixture.CreateContext(); db.Database.EnsureDeleted(); GiveMeSomeTime(db); - db.GetService().Migrate(targetMigration: "Migration1"); + db.GetService().Migrate("Migration1"); - Parallel.For(0, Environment.ProcessorCount, i => - { - using var context = Fixture.CreateContext(); - var migrator = context.GetService(); - migrator.Migrate(targetMigration: "Migration2"); - }); + Parallel.For( + 0, Environment.ProcessorCount, i => + { + using var context = Fixture.CreateContext(); + var migrator = context.GetService(); + migrator.Migrate("Migration2"); + }); var history = db.GetService(); Assert.Collection( @@ -279,14 +268,15 @@ public virtual async Task Can_apply_second_migration_in_parallel_async() using var db = Fixture.CreateContext(); await db.Database.EnsureDeletedAsync(); await GiveMeSomeTimeAsync(db); - await db.GetService().MigrateAsync(targetMigration: "Migration1"); + await db.GetService().MigrateAsync("Migration1"); - await Parallel.ForAsync(0, Environment.ProcessorCount, async (i, _) => - { - using var context = Fixture.CreateContext(); - var migrator = context.GetService(); - await migrator.MigrateAsync(targetMigration: "Migration2"); - }); + await Parallel.ForAsync( + 0, Environment.ProcessorCount, async (i, _) => + { + using var context = Fixture.CreateContext(); + var migrator = context.GetService(); + await migrator.MigrateAsync("Migration2"); + }); var history = db.GetService(); Assert.Collection( @@ -456,7 +446,7 @@ protected virtual void DiffSnapshot(ModelSnapshot snapshot, DbContext context) Assert.Equal(0, operations.Count); } - private void SetSql(string value) + protected void SetSql(string value) => Sql = value.Replace(ProductInfo.GetVersion(), "7.0.0-test"); } @@ -468,11 +458,19 @@ public abstract class MigrationsInfrastructureFixtureBase public new RelationalTestStore TestStore => (RelationalTestStore)base.TestStore; + public int SeedCallCount { get; private set; } + public int SeedAsyncCallCount { get; private set; } + + public void ResetCounts() + { + SeedCallCount = 0; + SeedAsyncCallCount = 0; + } + protected override IServiceCollection AddServices(IServiceCollection serviceCollection) { TestStore.UseConnectionString = true; - return base.AddServices(serviceCollection) - .AddSingleton(); + return base.AddServices(serviceCollection); } protected override string StoreName @@ -499,15 +497,26 @@ public class MigrationsContext(DbContextOptions options) : PoolableDbContext(opt } protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) - { - modelBuilder.Entity(b => b.ToTable("Table1")); - } + => modelBuilder.Entity(b => b.ToTable("Table1")); public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) - => base.AddOptions(builder).ConfigureWarnings(e => e - .Log(RelationalEventId.PendingModelChangesWarning) - .Log(RelationalEventId.NonTransactionalMigrationOperationWarning) - ); + => base.AddOptions(builder) + .UseSeeding( + (context, migrated) => + { + SeedCallCount++; + }) + .UseAsyncSeeding( + (context, migrated, token) => + { + SeedAsyncCallCount++; + return Task.CompletedTask; + }) + .ConfigureWarnings( + e => e + .Log(RelationalEventId.PendingModelChangesWarning) + .Log(RelationalEventId.NonTransactionalMigrationOperationWarning) + ); protected override bool ShouldLogCategory(string logCategory) => logCategory == DbLoggerCategory.Migrations.Name; @@ -519,42 +528,6 @@ public class Foo public string Description { get; set; } } - public class MigratorPlugin : IMigratorPlugin - { - public static int MigratedCallCount { get; private set; } - public static int MigratedAsyncCallCount { get; private set; } - public static int MigratingCallCount { get; private set; } - public static int MigratingAsyncCallCount { get; private set; } - - public static void ResetCounts() - { - MigratedCallCount = 0; - MigratedAsyncCallCount = 0; - MigratingCallCount = 0; - MigratingAsyncCallCount = 0; - } - - public void Migrated(DbContext context, IMigratorData data) - { - MigratedCallCount++; - } - - public Task MigratedAsync(DbContext context, IMigratorData data, CancellationToken cancellationToken) - { - MigratedAsyncCallCount++; - return Task.CompletedTask; - } - - public void Migrating(DbContext context, IMigratorData data) - => MigratingCallCount++; - - public Task MigratingAsync(DbContext context, IMigratorData data, CancellationToken cancellationToken = default) - { - MigratingAsyncCallCount++; - return Task.CompletedTask; - } - } - [DbContext(typeof(MigrationsContext))] [Migration("00000000000001_Migration1")] private class Migration1 : Migration @@ -566,7 +539,12 @@ protected override void Up(MigrationBuilder migrationBuilder) migrationBuilder .CreateTable( name: "Table1", - columns: x => new { Id = x.Column(), Foo = x.Column(), Description = x.Column() }) + columns: x => new + { + Id = x.Column(), + Foo = x.Column(), + Description = x.Column() + }) .PrimaryKey( name: "PK_Table1", columns: x => x.Id); @@ -619,7 +597,8 @@ protected override void Up(MigrationBuilder migrationBuilder) { if (ActiveProvider == "Microsoft.EntityFrameworkCore.SqlServer") { - migrationBuilder.Sql(""" + migrationBuilder.Sql( + """ CREATE PROCEDURE [dbo].[GotoReproduction] AS BEGIN @@ -660,13 +639,10 @@ Empty Lines """; protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.Sql($"INSERT INTO Table1 (Id, Bar, Description) VALUES (-1, 3, '{TestValue}')"); - } + => migrationBuilder.Sql($"INSERT INTO Table1 (Id, Bar, Description) VALUES (-1, 3, '{TestValue}')"); protected override void Down(MigrationBuilder migrationBuilder) { - } } @@ -682,13 +658,10 @@ Empty Lines """; protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.Sql($"INSERT INTO Table1 (Id, Bar, Description) VALUES (-2, 4, '{TestValue}')"); - } + => migrationBuilder.Sql($"INSERT INTO Table1 (Id, Bar, Description) VALUES (-2, 4, '{TestValue}')"); protected override void Down(MigrationBuilder migrationBuilder) { - } } @@ -707,13 +680,10 @@ Empty Lines """; protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.Sql($"INSERT INTO Table1 (Id, Bar, Description) VALUES (-3, 5, '{TestValue}')"); - } + => migrationBuilder.Sql($"INSERT INTO Table1 (Id, Bar, Description) VALUES (-3, 5, '{TestValue}')"); protected override void Down(MigrationBuilder migrationBuilder) { - } } } diff --git a/test/EFCore.Relational.Specification.Tests/Migrations/MigrationsSqlGeneratorTestBase.cs b/test/EFCore.Relational.Specification.Tests/Migrations/MigrationsSqlGeneratorTestBase.cs index f03b89e7609..307cf0420d4 100644 --- a/test/EFCore.Relational.Specification.Tests/Migrations/MigrationsSqlGeneratorTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Migrations/MigrationsSqlGeneratorTestBase.cs @@ -181,20 +181,14 @@ public virtual void SqlOperation() [new Coordinate(1.1, 2.2), new Coordinate(2.2, 2.2), new Coordinate(2.2, 1.1), new Coordinate(7.1, 7.2)]) { SRID = 4326 }; private static readonly LineString _lineString2 = new( - [new Coordinate(7.1, 7.2), new Coordinate(20.2, 20.2), new Coordinate(20.20, 1.1), new Coordinate(70.1, 70.2)]) - { - SRID = 4326 - }; + [new Coordinate(7.1, 7.2), new Coordinate(20.2, 20.2), new Coordinate(20.20, 1.1), new Coordinate(70.1, 70.2)]) { SRID = 4326 }; private static readonly MultiPoint _multiPoint = new( [new Point(1.1, 2.2), new Point(2.2, 2.2), new Point(2.2, 1.1)]) { SRID = 4326 }; private static readonly Polygon _polygon1 = new( new LinearRing( - [new Coordinate(1.1, 2.2), new Coordinate(2.2, 2.2), new Coordinate(2.2, 1.1), new Coordinate(1.1, 2.2)])) - { - SRID = 4326 - }; + [new Coordinate(1.1, 2.2), new Coordinate(2.2, 2.2), new Coordinate(2.2, 1.1), new Coordinate(1.1, 2.2)])) { SRID = 4326 }; private static readonly Polygon _polygon2 = new( new LinearRing( @@ -212,10 +206,7 @@ public virtual void SqlOperation() [_polygon2, _polygon1]) { SRID = 4326 }; private static readonly GeometryCollection _geometryCollection = new( - [_lineString1, _lineString2, _multiPoint, _polygon1, _polygon2, _point1, _multiLineString, _multiPolygon]) - { - SRID = 4326 - }; + [_lineString1, _lineString2, _multiPoint, _polygon1, _polygon2, _point1, _multiLineString, _multiPolygon]) { SRID = 4326 }; [ConditionalFact] public virtual void InsertDataOperation_all_args_spatial() diff --git a/test/EFCore.Relational.Specification.Tests/Migrations/MigrationsTestBase.cs b/test/EFCore.Relational.Specification.Tests/Migrations/MigrationsTestBase.cs index 71f0e702ed5..f83e2575b6b 100644 --- a/test/EFCore.Relational.Specification.Tests/Migrations/MigrationsTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Migrations/MigrationsTestBase.cs @@ -2864,7 +2864,7 @@ public virtual Task Add_required_primitive_collection_with_custom_converter_to_e new ValueConverter, string>( convertToProviderExpression: x => x != null && x.Count > 0 ? "some numbers" : "nothing", convertFromProviderExpression: x => x == "nothing" - ? new List { } + ? new List() : new List { 7, @@ -2908,7 +2908,7 @@ public virtual Task Add_required_primitive_collection_with_custom_converter_and_ new ValueConverter, string>( convertToProviderExpression: x => x != null && x.Count > 0 ? "some numbers" : "nothing", convertFromProviderExpression: x => x == "nothing" - ? new List { } + ? new List() : new List { 7, @@ -3145,7 +3145,7 @@ public virtual Task Add_required_primitve_collection_with_custom_converter_to_ex new ValueConverter, string>( convertToProviderExpression: x => x != null && x.Count > 0 ? "some numbers" : "nothing", convertFromProviderExpression: x => x == "nothing" - ? new List { } + ? new List() : new List { 7, @@ -3189,7 +3189,7 @@ public virtual Task Add_required_primitve_collection_with_custom_converter_and_c new ValueConverter, string>( convertToProviderExpression: x => x != null && x.Count > 0 ? "some numbers" : "nothing", convertFromProviderExpression: x => x == "nothing" - ? new List { } + ? new List() : new List { 7, diff --git a/test/EFCore.Relational.Specification.Tests/ModelBuilding/RelationalModelBuilderTest.cs b/test/EFCore.Relational.Specification.Tests/ModelBuilding/RelationalModelBuilderTest.cs index 4a9096d6012..b854cde3b93 100644 --- a/test/EFCore.Relational.Specification.Tests/ModelBuilding/RelationalModelBuilderTest.cs +++ b/test/EFCore.Relational.Specification.Tests/ModelBuilding/RelationalModelBuilderTest.cs @@ -716,32 +716,36 @@ public virtual void Can_use_ForeignKeyAttribute_with_InversePropertyAttribute() var model = modelBuilder.FinalizeModel(); - Assert.Collection(model.GetEntityTypes(), + Assert.Collection( + model.GetEntityTypes(), e => { Assert.Equal("FuelTypeMotorArt", e.ShortName()); Assert.Collection(e.GetProperties(), p => Assert.Equal("FuelTypeId", p.Name), p => Assert.Equal("MotorArtId", p.Name)); - Assert.Collection(e.GetKeys(), k =>Assert.Collection(k.Properties, - p => Assert.Equal("FuelTypeId", p.Name), - p => Assert.Equal("MotorArtId", p.Name))); - Assert.Collection(e.GetForeignKeys(), k => - { - Assert.Equal("FuelType", k.PrincipalEntityType.ShortName()); - Assert.Collection(k.Properties, p => Assert.Equal("FuelTypeId", p.Name)); - Assert.Collection(k.PrincipalKey.Properties, p => Assert.Equal("FuelTypeId", p.Name)); - }, k => - { - Assert.Equal("MotorArt", k.PrincipalEntityType.ShortName()); - Assert.Collection(k.Properties, p => Assert.Equal("MotorArtId", p.Name)); - Assert.Collection(k.PrincipalKey.Properties, p => Assert.Equal("MotorArtId", p.Name)); - }); + Assert.Collection( + e.GetKeys(), k => Assert.Collection( + k.Properties, + p => Assert.Equal("FuelTypeId", p.Name), + p => Assert.Equal("MotorArtId", p.Name))); + Assert.Collection( + e.GetForeignKeys(), k => + { + Assert.Equal("FuelType", k.PrincipalEntityType.ShortName()); + Assert.Collection(k.Properties, p => Assert.Equal("FuelTypeId", p.Name)); + Assert.Collection(k.PrincipalKey.Properties, p => Assert.Equal("FuelTypeId", p.Name)); + }, k => + { + Assert.Equal("MotorArt", k.PrincipalEntityType.ShortName()); + Assert.Collection(k.Properties, p => Assert.Equal("MotorArtId", p.Name)); + Assert.Collection(k.PrincipalKey.Properties, p => Assert.Equal("MotorArtId", p.Name)); + }); Assert.Empty(e.GetNavigations()); Assert.Empty(e.GetSkipNavigations()); }, e => { Assert.Equal("FuelType", e.ShortName()); - Assert.Collection(e.GetKeys(), k =>Assert.Collection(k.Properties, p => Assert.Equal("FuelTypeId", p.Name))); + Assert.Collection(e.GetKeys(), k => Assert.Collection(k.Properties, p => Assert.Equal("FuelTypeId", p.Name))); Assert.Collection(e.GetProperties(), p => Assert.Equal("FuelTypeId", p.Name), p => Assert.Equal("Bezeichnung", p.Name)); Assert.Empty(e.GetForeignKeys()); Assert.Empty(e.GetNavigations()); @@ -750,18 +754,19 @@ public virtual void Can_use_ForeignKeyAttribute_with_InversePropertyAttribute() e => { Assert.Equal("MotorArt", e.ShortName()); - Assert.Collection(e.GetKeys(), k =>Assert.Collection(k.Properties, p => Assert.Equal("MotorArtId", p.Name))); + Assert.Collection(e.GetKeys(), k => Assert.Collection(k.Properties, p => Assert.Equal("MotorArtId", p.Name))); Assert.Collection(e.GetProperties(), p => Assert.Equal("MotorArtId", p.Name)); Assert.Empty(e.GetForeignKeys()); Assert.Empty(e.GetNavigations()); - Assert.Collection(e.GetSkipNavigations(), + Assert.Collection( + e.GetSkipNavigations(), n => Assert.Equal("FuelType", n.Name), n => Assert.Equal("MotorBauArt", n.Name)); }, e => { Assert.Equal("MotorBauart", e.ShortName()); - Assert.Collection(e.GetKeys(), k =>Assert.Collection(k.Properties, p => Assert.Equal("MotorBauartId", p.Name))); + Assert.Collection(e.GetKeys(), k => Assert.Collection(k.Properties, p => Assert.Equal("MotorBauartId", p.Name))); Assert.Collection(e.GetProperties(), p => Assert.Equal("MotorBauartId", p.Name)); Assert.Empty(e.GetForeignKeys()); Assert.Empty(e.GetNavigations()); @@ -770,23 +775,27 @@ public virtual void Can_use_ForeignKeyAttribute_with_InversePropertyAttribute() e => { Assert.Equal("MotorArtXMotorBauart", e.ShortName()); - Assert.Collection(e.GetProperties(), + Assert.Collection( + e.GetProperties(), p => Assert.Equal("MotorArtId", p.Name), p => Assert.Equal("MotorBauArtId", p.Name)); - Assert.Collection(e.GetKeys(), k =>Assert.Collection(k.Properties, - p => Assert.Equal("MotorArtId", p.Name), - p => Assert.Equal("MotorBauArtId", p.Name))); - Assert.Collection(e.GetForeignKeys(), k => - { - Assert.Equal("MotorArt", k.PrincipalEntityType.ShortName()); - Assert.Collection(k.Properties, p => Assert.Equal("MotorArtId", p.Name)); - Assert.Collection(k.PrincipalKey.Properties, p => Assert.Equal("MotorArtId", p.Name)); - }, k => - { - Assert.Equal("MotorBauart", k.PrincipalEntityType.ShortName()); - Assert.Collection(k.Properties, p => Assert.Equal("MotorBauArtId", p.Name)); - Assert.Collection(k.PrincipalKey.Properties, p => Assert.Equal("MotorBauartId", p.Name)); - }); + Assert.Collection( + e.GetKeys(), k => Assert.Collection( + k.Properties, + p => Assert.Equal("MotorArtId", p.Name), + p => Assert.Equal("MotorBauArtId", p.Name))); + Assert.Collection( + e.GetForeignKeys(), k => + { + Assert.Equal("MotorArt", k.PrincipalEntityType.ShortName()); + Assert.Collection(k.Properties, p => Assert.Equal("MotorArtId", p.Name)); + Assert.Collection(k.PrincipalKey.Properties, p => Assert.Equal("MotorArtId", p.Name)); + }, k => + { + Assert.Equal("MotorBauart", k.PrincipalEntityType.ShortName()); + Assert.Collection(k.Properties, p => Assert.Equal("MotorBauArtId", p.Name)); + Assert.Collection(k.PrincipalKey.Properties, p => Assert.Equal("MotorBauartId", p.Name)); + }); Assert.Empty(e.GetNavigations()); Assert.Empty(e.GetSkipNavigations()); }); @@ -833,7 +842,6 @@ protected class MotorBauart [InverseProperty("MotorBauArt")] public virtual ICollection MotorArt { get; set; } = new HashSet(); } - } public abstract class RelationalOwnedTypesTestBase(RelationalModelBuilderFixture fixture) : OwnedTypesTestBase(fixture) @@ -1075,7 +1083,6 @@ public virtual void Can_use_sproc_mapping_with_owned_reference() Assert.Null(bookOwnership2.DeclaringEntityType.GetUpdateStoredProcedure()); Assert.Null(bookOwnership2.DeclaringEntityType.GetDeleteStoredProcedure()); } -#nullable disable protected class JsonEntity { @@ -1205,6 +1212,7 @@ static void AssertOwnership(IEntityType owner) owned.GetProperties().Select(p => p.Name)); } } + public override void Can_configure_owned_type_key() { var modelBuilder = CreateModelBuilder(); @@ -1247,7 +1255,8 @@ public abstract TestCheckConstraintBuilder HasCheckConstraint( public abstract TestColumnBuilder Property(Expression> propertyExpression); } - public class GenericTestTableBuilder(TableBuilder tableBuilder) : TestTableBuilder, IInfrastructure> + public class GenericTestTableBuilder(TableBuilder tableBuilder) + : TestTableBuilder, IInfrastructure> where TEntity : class { private TableBuilder TableBuilder { get; } = tableBuilder; @@ -1332,7 +1341,8 @@ public abstract TestCheckConstraintBuilder HasCheckConstraint( public abstract TestColumnBuilder Property(Expression> propertyExpression); } - public class GenericTestOwnedNavigationTableBuilder(OwnedNavigationTableBuilder tableBuilder) : + public class GenericTestOwnedNavigationTableBuilder( + OwnedNavigationTableBuilder tableBuilder) : TestOwnedNavigationTableBuilder, IInfrastructure> where TOwnerEntity : class @@ -1420,7 +1430,8 @@ public abstract TestSplitTableBuilder HasAnnotation( object? value); } - public class GenericTestSplitTableBuilder(SplitTableBuilder tableBuilder) : TestSplitTableBuilder, IInfrastructure> + public class GenericTestSplitTableBuilder(SplitTableBuilder tableBuilder) + : TestSplitTableBuilder, IInfrastructure> where TEntity : class { private SplitTableBuilder TableBuilder { get; } = tableBuilder; @@ -1453,7 +1464,8 @@ public override TestSplitTableBuilder HasAnnotation(string annotation, => Wrap(TableBuilder.HasAnnotation(annotation, value)); } - public class NonGenericTestSplitTableBuilder(SplitTableBuilder tableBuilder) : TestSplitTableBuilder, IInfrastructure + public class NonGenericTestSplitTableBuilder(SplitTableBuilder tableBuilder) + : TestSplitTableBuilder, IInfrastructure where TEntity : class { private SplitTableBuilder TableBuilder { get; } = tableBuilder; @@ -1505,7 +1517,8 @@ public abstract TestOwnedNavigationSplitTableBuilder(OwnedNavigationSplitTableBuilder tableBuilder) : + public class GenericTestOwnedNavigationSplitTableBuilder( + OwnedNavigationSplitTableBuilder tableBuilder) : TestOwnedNavigationSplitTableBuilder, IInfrastructure> where TOwnerEntity : class @@ -1540,7 +1553,8 @@ public override TestOwnedNavigationSplitTableBuilder Wrap(TableBuilder.HasAnnotation(annotation, value)); } - public class NonGenericTestOwnedNavigationSplitTableBuilder(OwnedNavigationSplitTableBuilder tableBuilder) : + public class NonGenericTestOwnedNavigationSplitTableBuilder( + OwnedNavigationSplitTableBuilder tableBuilder) : TestOwnedNavigationSplitTableBuilder, IInfrastructure where TOwnerEntity : class @@ -1583,7 +1597,8 @@ public abstract TestColumnBuilder HasAnnotation( object? value); } - public class GenericTestColumnBuilder(ColumnBuilder columnBuilder) : TestColumnBuilder, IInfrastructure> + public class GenericTestColumnBuilder(ColumnBuilder columnBuilder) + : TestColumnBuilder, IInfrastructure> { private ColumnBuilder ColumnBuilder { get; } = columnBuilder; @@ -1602,7 +1617,8 @@ public override TestColumnBuilder HasAnnotation( => Wrap(ColumnBuilder.HasAnnotation(annotation, value)); } - public class NonGenericTestColumnBuilder(ColumnBuilder tableBuilder) : TestColumnBuilder, IInfrastructure + public class NonGenericTestColumnBuilder(ColumnBuilder tableBuilder) + : TestColumnBuilder, IInfrastructure { private ColumnBuilder ColumnBuilder { get; } = tableBuilder; @@ -1633,7 +1649,8 @@ public abstract class TestViewBuilder public abstract TestViewColumnBuilder Property(Expression> propertyExpression); } - public class GenericTestViewBuilder(ViewBuilder tableBuilder) : TestViewBuilder, IInfrastructure> + public class GenericTestViewBuilder(ViewBuilder tableBuilder) + : TestViewBuilder, IInfrastructure> where TEntity : class { private ViewBuilder ViewBuilder { get; } = tableBuilder; @@ -1695,7 +1712,8 @@ public abstract TestViewColumnBuilder Property( Expression> propertyExpression); } - public class GenericTestOwnedNavigationViewBuilder(OwnedNavigationViewBuilder tableBuilder) : + public class GenericTestOwnedNavigationViewBuilder( + OwnedNavigationViewBuilder tableBuilder) : TestOwnedNavigationViewBuilder, IInfrastructure> where TOwnerEntity : class @@ -1769,7 +1787,8 @@ public abstract TestSplitViewBuilder HasAnnotation( object? value); } - public class GenericTestSplitViewBuilder(SplitViewBuilder tableBuilder) : TestSplitViewBuilder, IInfrastructure> + public class GenericTestSplitViewBuilder(SplitViewBuilder tableBuilder) + : TestSplitViewBuilder, IInfrastructure> where TEntity : class { private SplitViewBuilder ViewBuilder { get; } = tableBuilder; @@ -1796,7 +1815,8 @@ public override TestSplitViewBuilder HasAnnotation(string annotation, o => Wrap(ViewBuilder.HasAnnotation(annotation, value)); } - public class NonGenericTestSplitViewBuilder(SplitViewBuilder tableBuilder) : TestSplitViewBuilder, IInfrastructure + public class NonGenericTestSplitViewBuilder(SplitViewBuilder tableBuilder) + : TestSplitViewBuilder, IInfrastructure where TEntity : class { private SplitViewBuilder ViewBuilder { get; } = tableBuilder; @@ -1841,7 +1861,8 @@ public abstract TestOwnedNavigationSplitViewBuilder(OwnedNavigationSplitViewBuilder tableBuilder) : + public class GenericTestOwnedNavigationSplitViewBuilder( + OwnedNavigationSplitViewBuilder tableBuilder) : TestOwnedNavigationSplitViewBuilder, IInfrastructure> where TOwnerEntity : class @@ -1874,9 +1895,10 @@ public override TestOwnedNavigationSplitViewBuilder Wrap(ViewBuilder.HasAnnotation(annotation, value)); } - public class NonGenericTestOwnedNavigationSplitViewBuilder(OwnedNavigationSplitViewBuilder tableBuilder) : - TestOwnedNavigationSplitViewBuilder, - IInfrastructure + public class NonGenericTestOwnedNavigationSplitViewBuilder(OwnedNavigationSplitViewBuilder tableBuilder) + : + TestOwnedNavigationSplitViewBuilder, + IInfrastructure where TOwnerEntity : class where TDependentEntity : class { @@ -1915,7 +1937,8 @@ public abstract TestViewColumnBuilder HasAnnotation( object? value); } - public class GenericTestViewColumnBuilder(ViewColumnBuilder columnBuilder) : TestViewColumnBuilder, IInfrastructure> + public class GenericTestViewColumnBuilder(ViewColumnBuilder columnBuilder) + : TestViewColumnBuilder, IInfrastructure> { private ViewColumnBuilder ViewColumnBuilder { get; } = columnBuilder; @@ -2366,7 +2389,8 @@ public class GenericTestOwnedNavigationStoredProcedureBuilder StoredProcedureBuilder { get; } = storedProcedureBuilder; + private OwnedNavigationStoredProcedureBuilder StoredProcedureBuilder { get; } = + storedProcedureBuilder; OwnedNavigationStoredProcedureBuilder IInfrastructure>.Instance @@ -2460,7 +2484,8 @@ public override TestOwnedNavigationStoredProcedureBuilder Wrap(StoredProcedureBuilder.HasAnnotation(annotation, value)); } - public class NonGenericTestOwnedNavigationStoredProcedureBuilder(OwnedNavigationStoredProcedureBuilder storedProcedureBuilder) + public class NonGenericTestOwnedNavigationStoredProcedureBuilder( + OwnedNavigationStoredProcedureBuilder storedProcedureBuilder) : TestOwnedNavigationStoredProcedureBuilder, IInfrastructure where TOwnerEntity : class @@ -2561,7 +2586,8 @@ public override TestOwnedNavigationStoredProcedureBuilder Wrap(StoredProcedureBuilder.HasAnnotation(annotation, value)); } - public class TestStoredProcedureParameterBuilder(StoredProcedureParameterBuilder storedProcedureParameterBuilder) : IInfrastructure + public class TestStoredProcedureParameterBuilder(StoredProcedureParameterBuilder storedProcedureParameterBuilder) + : IInfrastructure { private StoredProcedureParameterBuilder StoredProcedureParameterBuilder { get; } = storedProcedureParameterBuilder; @@ -2586,7 +2612,8 @@ public virtual TestStoredProcedureParameterBuilder HasAnnotation( => Wrap(StoredProcedureParameterBuilder.HasAnnotation(annotation, value)); } - public class TestStoredProcedureResultColumnBuilder(StoredProcedureResultColumnBuilder storedProcedureResultColumnBuilder) : IInfrastructure + public class TestStoredProcedureResultColumnBuilder(StoredProcedureResultColumnBuilder storedProcedureResultColumnBuilder) + : IInfrastructure { private StoredProcedureResultColumnBuilder StoredProcedureResultColumnBuilder { get; } = storedProcedureResultColumnBuilder; diff --git a/test/EFCore.Relational.Specification.Tests/Query/AdHocAdvancedMappingsQueryRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/AdHocAdvancedMappingsQueryRelationalTestBase.cs index e33ea578f93..5a5ea258faf 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/AdHocAdvancedMappingsQueryRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/AdHocAdvancedMappingsQueryRelationalTestBase.cs @@ -71,8 +71,7 @@ public virtual async Task Projecting_one_of_two_similar_complex_types_picks_the_ .Select( x => new { - x.B.A.Id, - x.B.Info.Created, + x.B.A.Id, x.B.Info.Created, }).ToList(); Assert.Equal(new DateTime(2000, 1, 1), query[0].Created); @@ -153,14 +152,14 @@ public class Offer : EntityBase public class Variation : EntityBase { - public Payment Payment { get; set; } = new Payment(0, 0); + public Payment Payment { get; set; } = new(0, 0); public NestedEntity Nested { get; set; } } public class NestedEntity : EntityBase { - public Payment Payment { get; set; } = new Payment(0, 0); + public Payment Payment { get; set; } = new(0, 0); } public record Payment(decimal Netto, decimal Brutto); diff --git a/test/EFCore.Relational.Specification.Tests/Query/AdHocJsonQueryTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/AdHocJsonQueryTestBase.cs index d0467f17ecc..d7461ae71fe 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/AdHocJsonQueryTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/AdHocJsonQueryTestBase.cs @@ -10,16 +10,24 @@ public abstract class AdHocJsonQueryTestBase : NonSharedModelTestBase protected override string StoreName => "AdHocJsonQueryTest"; + protected virtual void ConfigureWarnings(WarningsConfigurationBuilder builder) + { + } + #region 32310 [ConditionalTheory] [MemberData(nameof(IsAsyncData))] public virtual async Task Contains_on_nested_collection_with_init_only_navigation(bool async) { - var contextFactory = await InitializeAsync(seed: Seed32310); + var contextFactory = await InitializeAsync( + onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), + onModelCreating: b => b.Entity().OwnsOne(e => e.Visits).ToJson().HasColumnType(JsonColumnType), + seed: Seed32310); + await using var context = contextFactory.CreateContext(); - var query = context.Pubs + var query = context.Set() .Where(u => u.Visits.DaysVisited.Contains(new DateOnly(2023, 1, 1))); var result = async @@ -30,23 +38,17 @@ public virtual async Task Contains_on_nested_collection_with_init_only_navigatio Assert.Equal(new DateOnly(2023, 1, 1), result.Visits.DaysVisited.Single()); } - protected virtual async Task Seed32310(MyContext32310 context) + protected virtual async Task Seed32310(DbContext context) { - var user = new Pub32310 { Name = "FBI", Visits = new Visits32310 { LocationTag = "tag", DaysVisited = [new(2023, 1, 1)] } }; + var user = new Pub32310 + { + Name = "FBI", Visits = new Visits32310 { LocationTag = "tag", DaysVisited = [new DateOnly(2023, 1, 1)] } + }; context.Add(user); await context.SaveChangesAsync(); } - protected class MyContext32310(DbContextOptions options) : DbContext(options) - { - public DbSet Pubs - => Set(); - - protected override void OnModelCreating(ModelBuilder modelBuilder) - => modelBuilder.Entity(b => { b.OwnsOne(e => e.Visits).ToJson(); }); - } - public class Pub32310 { public int Id { get; set; } @@ -68,12 +70,14 @@ public class Visits32310 [MemberData(nameof(IsAsyncData))] public virtual async Task Optional_json_properties_materialized_as_null_when_the_element_in_json_is_not_present(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeAsync( + onModelCreating: BuildModel29219, + onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: Seed29219); using (var context = contextFactory.CreateContext()) { - var query = context.Entities.Where(x => x.Id == 3); + var query = context.Set().Where(x => x.Id == 3); var result = async ? await query.SingleAsync() @@ -89,12 +93,14 @@ public virtual async Task Optional_json_properties_materialized_as_null_when_the [MemberData(nameof(IsAsyncData))] public virtual async Task Can_project_nullable_json_property_when_the_element_in_json_is_not_present(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeAsync( + onModelCreating: BuildModel29219, + onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: Seed29219); using (var context = contextFactory.CreateContext()) { - var query = context.Entities.OrderBy(x => x.Id).Select(x => x.Reference.NullableScalar); + var query = context.Set().OrderBy(x => x.Id).Select(x => x.Reference.NullableScalar); var result = async ? await query.ToListAsync() @@ -107,19 +113,17 @@ public virtual async Task Can_project_nullable_json_property_when_the_element_in } } - protected abstract Task Seed29219(MyContext29219 ctx); + protected void BuildModel29219(ModelBuilder modelBuilder) + => modelBuilder.Entity( + b => + { + b.ToTable("Entities"); + b.Property(x => x.Id).ValueGeneratedNever(); + b.OwnsOne(x => x.Reference).ToJson().HasColumnType(JsonColumnType); + b.OwnsMany(x => x.Collection).ToJson().HasColumnType(JsonColumnType); + }); - protected class MyContext29219(DbContextOptions options) : DbContext(options) - { - public DbSet Entities { get; set; } - - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - modelBuilder.Entity().Property(x => x.Id).ValueGeneratedNever(); - modelBuilder.Entity().OwnsOne(x => x.Reference).ToJson(); - modelBuilder.Entity().OwnsMany(x => x.Collection).ToJson(); - } - } + protected abstract Task Seed29219(DbContext ctx); public class MyEntity29219 { @@ -138,28 +142,24 @@ public class MyJsonEntity29219 #region 30028 - protected abstract Task Seed30028(MyContext30028 ctx); - - protected class MyContext30028(DbContextOptions options) : DbContext(options) - { - public DbSet Entities { get; set; } - - protected override void OnModelCreating(ModelBuilder modelBuilder) - => modelBuilder.Entity( - b => - { - b.Property(x => x.Id).ValueGeneratedNever(); - b.OwnsOne( - x => x.Json, nb => - { - nb.ToJson(); - nb.OwnsMany(x => x.Collection, nnb => nnb.OwnsOne(x => x.Nested)); - nb.OwnsOne(x => x.OptionalReference, nnb => nnb.OwnsOne(x => x.Nested)); - nb.OwnsOne(x => x.RequiredReference, nnb => nnb.OwnsOne(x => x.Nested)); - nb.Navigation(x => x.RequiredReference).IsRequired(); - }); - }); - } + protected abstract Task Seed30028(DbContext ctx); + + protected virtual void BuildModel30028(ModelBuilder modelBuilder) + => modelBuilder.Entity( + b => + { + b.Property(x => x.Id).ValueGeneratedNever(); + b.ToTable("Entities"); + b.OwnsOne( + x => x.Json, nb => + { + nb.ToJson().HasColumnType(JsonColumnType); + nb.OwnsMany(x => x.Collection, nnb => nnb.OwnsOne(x => x.Nested)); + nb.OwnsOne(x => x.OptionalReference, nnb => nnb.OwnsOne(x => x.Nested)); + nb.OwnsOne(x => x.RequiredReference, nnb => nnb.OwnsOne(x => x.Nested)); + nb.Navigation(x => x.RequiredReference).IsRequired(); + }); + }); public class MyEntity30028 { @@ -190,10 +190,14 @@ public class MyJsonLeafEntity30028 [MemberData(nameof(IsAsyncData))] public virtual async Task Accessing_missing_navigation_works(bool async) { - var contextFactory = await InitializeAsync(seed: Seed30028); + var contextFactory = await InitializeAsync( + onModelCreating: BuildModel30028, + onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), + seed: Seed30028); + using (var context = contextFactory.CreateContext()) { - var result = context.Entities.OrderBy(x => x.Id).ToList(); + var result = context.Set().OrderBy(x => x.Id).ToList(); Assert.Equal(4, result.Count); Assert.NotNull(result[0].Json.Collection); Assert.NotNull(result[0].Json.OptionalReference); @@ -217,10 +221,14 @@ public virtual async Task Accessing_missing_navigation_works(bool async) [MemberData(nameof(IsAsyncData))] public virtual async Task Missing_navigation_works_with_deduplication(bool async) { - var contextFactory = await InitializeAsync(seed: Seed30028); + var contextFactory = await InitializeAsync( + onModelCreating: BuildModel30028, + onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), + seed: Seed30028); + using (var context = contextFactory.CreateContext()) { - var result = context.Entities.OrderBy(x => x.Id).Select( + var queryable = context.Set().OrderBy(x => x.Id).Select( x => new { x, @@ -230,7 +238,9 @@ public virtual async Task Missing_navigation_works_with_deduplication(bool async NestedOptional = x.Json.OptionalReference.Nested, NestedRequired = x.Json.RequiredReference.Nested, x.Json.Collection, - }).AsNoTracking().ToList(); + }).AsNoTracking(); + + var result = async ? await queryable.ToListAsync() : queryable.ToList(); Assert.Equal(4, result.Count); Assert.NotNull(result[0].OptionalReference); @@ -266,108 +276,104 @@ public virtual async Task Missing_navigation_works_with_deduplication(bool async [ConditionalFact] public virtual async Task Project_json_with_no_properties() { - var contextFactory = await InitializeAsync(seed: Seed30028); + var contextFactory = await InitializeAsync( + onModelCreating: BuildModel32939, + onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), + seed: Seed32939); + using var context = contextFactory.CreateContext(); - context.Entities.ToList(); + context.Set().ToList(); } - protected Task Seed30028(Context32939 ctx) + protected Task Seed32939(DbContext ctx) { - var entity = new Context32939.Entity32939 - { - Empty = new Context32939.JsonEmpty32939(), - FieldOnly = new Context32939.JsonFieldOnly32939() - }; + var entity = new Entity32939 { Empty = new JsonEmpty32939(), FieldOnly = new JsonFieldOnly32939() }; - ctx.Entities.Add(entity); + ctx.Add(entity); return ctx.SaveChangesAsync(); } - protected class Context32939(DbContextOptions options) : DbContext(options) + protected virtual void BuildModel32939(ModelBuilder modelBuilder) { - public DbSet Entities { get; set; } - - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - modelBuilder.Entity().Property(x => x.Id).ValueGeneratedNever(); - modelBuilder.Entity().OwnsOne(x => x.Empty, b => b.ToJson()); - modelBuilder.Entity().OwnsOne(x => x.FieldOnly, b => b.ToJson()); - } - - public class Entity32939 - { - public int Id { get; set; } - public JsonEmpty32939 Empty { get; set; } - public JsonFieldOnly32939 FieldOnly { get; set; } + modelBuilder.Entity().Property(x => x.Id).ValueGeneratedNever(); + modelBuilder.Entity().OwnsOne(x => x.Empty, b => b.ToJson().HasColumnType(JsonColumnType)); + modelBuilder.Entity().OwnsOne(x => x.FieldOnly, b => b.ToJson().HasColumnType(JsonColumnType)); + } - } + public class Entity32939 + { + public int Id { get; set; } + public JsonEmpty32939 Empty { get; set; } + public JsonFieldOnly32939 FieldOnly { get; set; } + } - public class JsonEmpty32939 - { - } + public class JsonEmpty32939 + { + } - public class JsonFieldOnly32939 - { - public int Field; - } + public class JsonFieldOnly32939 + { + public int Field; } #endregion #region 33046 - protected abstract Task Seed33046(Context33046 ctx); + protected abstract Task Seed33046(DbContext ctx); [ConditionalFact] public virtual async Task Query_with_nested_json_collection_mapped_to_private_field_via_IReadOnlyList() { - var contextFactory = await InitializeAsync(seed: Seed33046); + var contextFactory = await InitializeAsync( + onModelCreating: BuildModel33046, + onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), + seed: Seed33046); + using var context = contextFactory.CreateContext(); - var query = context.Reviews.ToList(); + var query = context.Set().ToList(); Assert.Equal(1, query.Count); } - protected class Context33046(DbContextOptions options) : DbContext(options) + protected virtual void BuildModel33046(ModelBuilder modelBuilder) + => modelBuilder.Entity( + b => + { + b.ToTable("Reviews"); + b.Property(x => x.Id).ValueGeneratedNever(); + b.OwnsMany( + x => x.Rounds, ownedBuilder => + { + ownedBuilder.ToJson().HasColumnType(JsonColumnType); + ownedBuilder.OwnsMany(r => r.SubRounds); + }); + }); + + public class Review { - public DbSet Reviews { get; set; } - - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - modelBuilder.Entity().Property(x => x.Id).ValueGeneratedNever(); - modelBuilder.Entity().OwnsMany( - x => x.Rounds, ownedBuilder => - { - ownedBuilder.ToJson(); - ownedBuilder.OwnsMany(r => r.SubRounds); - }); - } - - public class Review - { - public int Id { get; set; } + public int Id { get; set; } #pragma warning disable IDE0044 // Add readonly modifier - private List _rounds = []; + private List _rounds = []; #pragma warning restore IDE0044 // Add readonly modifier - public IReadOnlyList Rounds - => _rounds.AsReadOnly(); - } + public IReadOnlyList Rounds + => _rounds.AsReadOnly(); + } - public class ReviewRound - { - public int RoundNumber { get; set; } + public class ReviewRound + { + public int RoundNumber { get; set; } #pragma warning disable IDE0044 // Add readonly modifier - private List _subRounds = []; + private readonly List _subRounds = []; #pragma warning restore IDE0044 // Add readonly modifier - public IReadOnlyList SubRounds - => _subRounds.AsReadOnly(); - } + public IReadOnlyList SubRounds + => _subRounds.AsReadOnly(); + } - public class SubRound - { - public int SubRoundNumber { get; set; } - } + public class SubRound + { + public int SubRoundNumber { get; set; } } #endregion @@ -378,12 +384,15 @@ public class SubRound [MemberData(nameof(IsAsyncData))] public virtual async Task Project_json_array_of_primitives_on_reference(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeAsync( + onModelCreating: BuildModelArrayOfPrimitives, + onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedArrayOfPrimitives); using (var context = contextFactory.CreateContext()) { - var query = context.Entities.OrderBy(x => x.Id).Select(x => new { x.Reference.IntArray, x.Reference.ListOfString }); + var query = context.Set().OrderBy(x => x.Id) + .Select(x => new { x.Reference.IntArray, x.Reference.ListOfString }); var result = async ? await query.ToListAsync() @@ -401,12 +410,15 @@ public virtual async Task Project_json_array_of_primitives_on_reference(bool asy [MemberData(nameof(IsAsyncData))] public virtual async Task Project_json_array_of_primitives_on_collection(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeAsync( + onModelCreating: BuildModelArrayOfPrimitives, + onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedArrayOfPrimitives); using (var context = contextFactory.CreateContext()) { - var query = context.Entities.OrderBy(x => x.Id).Select(x => new { x.Collection[0].IntArray, x.Collection[1].ListOfString }); + var query = context.Set().OrderBy(x => x.Id) + .Select(x => new { x.Collection[0].IntArray, x.Collection[1].ListOfString }); var result = async ? await query.ToListAsync() @@ -424,12 +436,14 @@ public virtual async Task Project_json_array_of_primitives_on_collection(bool as [MemberData(nameof(IsAsyncData))] public virtual async Task Project_element_of_json_array_of_primitives(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeAsync( + onModelCreating: BuildModelArrayOfPrimitives, + onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedArrayOfPrimitives); using (var context = contextFactory.CreateContext()) { - var query = context.Entities.OrderBy(x => x.Id).Select( + var query = context.Set().OrderBy(x => x.Id).Select( x => new { ArrayElement = x.Reference.IntArray[0], ListElement = x.Reference.ListOfString[1] }); var result = async @@ -442,12 +456,14 @@ public virtual async Task Project_element_of_json_array_of_primitives(bool async [MemberData(nameof(IsAsyncData))] public virtual async Task Predicate_based_on_element_of_json_array_of_primitives1(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeAsync( + onModelCreating: BuildModelArrayOfPrimitives, + onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedArrayOfPrimitives); using (var context = contextFactory.CreateContext()) { - var query = context.Entities.Where(x => x.Reference.IntArray[0] == 1); + var query = context.Set().Where(x => x.Reference.IntArray[0] == 1); var result = async ? await query.ToListAsync() @@ -462,12 +478,14 @@ public virtual async Task Predicate_based_on_element_of_json_array_of_primitives [MemberData(nameof(IsAsyncData))] public virtual async Task Predicate_based_on_element_of_json_array_of_primitives2(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeAsync( + onModelCreating: BuildModelArrayOfPrimitives, + onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedArrayOfPrimitives); using (var context = contextFactory.CreateContext()) { - var query = context.Entities.Where(x => x.Reference.ListOfString[1] == "Bar"); + var query = context.Set().Where(x => x.Reference.ListOfString[1] == "Bar"); var result = async ? await query.ToListAsync() @@ -482,12 +500,14 @@ public virtual async Task Predicate_based_on_element_of_json_array_of_primitives [MemberData(nameof(IsAsyncData))] public virtual async Task Predicate_based_on_element_of_json_array_of_primitives3(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeAsync( + onModelCreating: BuildModelArrayOfPrimitives, + onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedArrayOfPrimitives); using (var context = contextFactory.CreateContext()) { - var query = context.Entities.Where( + var query = context.Set().Where( x => x.Reference.IntArray.AsQueryable().ElementAt(0) == 1 || x.Reference.ListOfString.AsQueryable().ElementAt(1) == "Bar") .OrderBy(e => e.Id); @@ -502,21 +522,16 @@ public virtual async Task Predicate_based_on_element_of_json_array_of_primitives } } - protected abstract Task SeedArrayOfPrimitives(MyContextArrayOfPrimitives ctx); + protected abstract Task SeedArrayOfPrimitives(DbContext ctx); - protected class MyContextArrayOfPrimitives(DbContextOptions options) : DbContext(options) + protected virtual void BuildModelArrayOfPrimitives(ModelBuilder modelBuilder) { - public DbSet Entities { get; set; } - - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - modelBuilder.Entity().Property(x => x.Id).ValueGeneratedNever(); - modelBuilder.Entity().OwnsOne( - x => x.Reference, b => b.ToJson()); + modelBuilder.Entity().Property(x => x.Id).ValueGeneratedNever(); + modelBuilder.Entity().OwnsOne( + x => x.Reference, b => b.ToJson().HasColumnType(JsonColumnType)); - modelBuilder.Entity().OwnsMany( - x => x.Collection, b => b.ToJson()); - } + modelBuilder.Entity().OwnsMany( + x => x.Collection, b => b.ToJson().HasColumnType(JsonColumnType)); } public class MyEntityArrayOfPrimitives @@ -540,12 +555,14 @@ public class MyJsonEntityArrayOfPrimitives [MemberData(nameof(IsAsyncData))] public virtual async Task Junk_in_json_basic_tracking(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeAsync( + onModelCreating: BuildModelJunkInJson, + onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedJunkInJson); using (var context = contextFactory.CreateContext()) { - var query = context.Entities; + var query = context.Set(); var result = async ? await query.ToListAsync() @@ -565,12 +582,14 @@ public virtual async Task Junk_in_json_basic_tracking(bool async) [MemberData(nameof(IsAsyncData))] public virtual async Task Junk_in_json_basic_no_tracking(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeAsync( + onModelCreating: BuildModelJunkInJson, + onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedJunkInJson); using (var context = contextFactory.CreateContext()) { - var query = context.Entities.AsNoTracking(); + var query = context.Set().AsNoTracking(); var result = async ? await query.ToListAsync() @@ -586,45 +605,47 @@ public virtual async Task Junk_in_json_basic_no_tracking(bool async) } } - protected abstract Task SeedJunkInJson(MyContextJunkInJson ctx); - - protected class MyContextJunkInJson(DbContextOptions options) : DbContext(options) - { - public DbSet Entities { get; set; } - - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - modelBuilder.Entity().Property(x => x.Id).ValueGeneratedNever(); - modelBuilder.Entity().OwnsOne( - x => x.Reference, b => - { - b.ToJson(); - b.OwnsOne(x => x.NestedReference); - b.OwnsMany(x => x.NestedCollection); - }); - modelBuilder.Entity().OwnsOne( - x => x.ReferenceWithCtor, b => - { - b.ToJson(); - b.OwnsOne(x => x.NestedReference); - b.OwnsMany(x => x.NestedCollection); - }); - modelBuilder.Entity().OwnsMany( - x => x.Collection, b => - { - b.ToJson(); - b.OwnsOne(x => x.NestedReference); - b.OwnsMany(x => x.NestedCollection); - }); - modelBuilder.Entity().OwnsMany( - x => x.CollectionWithCtor, b => - { - b.ToJson(); - b.OwnsOne(x => x.NestedReference); - b.OwnsMany(x => x.NestedCollection); - }); - } - } + protected abstract Task SeedJunkInJson(DbContext ctx); + + protected virtual void BuildModelJunkInJson(ModelBuilder modelBuilder) + => modelBuilder.Entity( + b => + { + b.ToTable("Entities"); + b.Property(x => x.Id).ValueGeneratedNever(); + + b.OwnsOne( + x => x.Reference, b => + { + b.ToJson().HasColumnType(JsonColumnType); + b.OwnsOne(x => x.NestedReference); + b.OwnsMany(x => x.NestedCollection); + }); + + b.OwnsOne( + x => x.ReferenceWithCtor, b => + { + b.ToJson().HasColumnType(JsonColumnType); + b.OwnsOne(x => x.NestedReference); + b.OwnsMany(x => x.NestedCollection); + }); + + b.OwnsMany( + x => x.Collection, b => + { + b.ToJson().HasColumnType(JsonColumnType); + b.OwnsOne(x => x.NestedReference); + b.OwnsMany(x => x.NestedCollection); + }); + + b.OwnsMany( + x => x.CollectionWithCtor, b => + { + b.ToJson().HasColumnType(JsonColumnType); + b.OwnsOne(x => x.NestedReference); + b.OwnsMany(x => x.NestedCollection); + }); + }); public class MyEntityJunkInJson { @@ -671,12 +692,14 @@ public class MyJsonEntityJunkInJsonWithCtorNested(DateTime doB) [MemberData(nameof(IsAsyncData))] public virtual async Task Tricky_buffering_basic(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeAsync( + onModelCreating: BuildModelTrickyBuffering, + onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedTrickyBuffering); using (var context = contextFactory.CreateContext()) { - var query = context.Entities; + var query = context.Set(); var result = async ? await query.ToListAsync() @@ -690,24 +713,22 @@ public virtual async Task Tricky_buffering_basic(bool async) } } - protected abstract Task SeedTrickyBuffering(MyContextTrickyBuffering ctx); - - protected class MyContextTrickyBuffering(DbContextOptions options) : DbContext(options) - { - public DbSet Entities { get; set; } - - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - modelBuilder.Entity().Property(x => x.Id).ValueGeneratedNever(); - modelBuilder.Entity().OwnsOne( - x => x.Reference, b => - { - b.ToJson(); - b.OwnsOne(x => x.NestedReference); - b.OwnsMany(x => x.NestedCollection); - }); - } - } + protected abstract Task SeedTrickyBuffering(DbContext ctx); + + protected virtual void BuildModelTrickyBuffering(ModelBuilder modelBuilder) + => modelBuilder.Entity( + b => + { + b.ToTable("Entities"); + b.Property(x => x.Id).ValueGeneratedNever(); + b.OwnsOne( + x => x.Reference, b => + { + b.ToJson().HasColumnType(JsonColumnType); + b.OwnsOne(x => x.NestedReference); + b.OwnsMany(x => x.NestedCollection); + }); + }); public class MyEntityTrickyBuffering { @@ -736,12 +757,14 @@ public class MyJsonEntityTrickyBufferingNested [MemberData(nameof(IsAsyncData))] public virtual async Task Shadow_properties_basic_tracking(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeAsync( + onModelCreating: BuildModelShadowProperties, + onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedShadowProperties); using (var context = contextFactory.CreateContext()) { - var query = context.Entities; + var query = context.Set(); var result = async ? await query.ToListAsync() @@ -775,12 +798,14 @@ public virtual async Task Shadow_properties_basic_tracking(bool async) [MemberData(nameof(IsAsyncData))] public virtual async Task Shadow_properties_basic_no_tracking(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeAsync( + onModelCreating: BuildModelShadowProperties, + onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedShadowProperties); using (var context = contextFactory.CreateContext()) { - var query = context.Entities.AsNoTracking(); + var query = context.Set().AsNoTracking(); var result = async ? await query.ToListAsync() @@ -798,12 +823,14 @@ public virtual async Task Shadow_properties_basic_no_tracking(bool async) [MemberData(nameof(IsAsyncData))] public virtual async Task Project_shadow_properties_from_json_entity(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeAsync( + onModelCreating: BuildModelShadowProperties, + onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedShadowProperties); using (var context = contextFactory.CreateContext()) { - var query = context.Entities.Select( + var query = context.Set().Select( x => new { ShadowString = EF.Property(x.Reference, "ShadowString"), @@ -820,41 +847,43 @@ public virtual async Task Project_shadow_properties_from_json_entity(bool async) } } - protected abstract Task SeedShadowProperties(MyContextShadowProperties ctx); - - protected class MyContextShadowProperties(DbContextOptions options) : DbContext(options) - { - public DbSet Entities { get; set; } - - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - modelBuilder.Entity().Property(x => x.Id).ValueGeneratedNever(); - modelBuilder.Entity().OwnsOne( - x => x.Reference, b => - { - b.ToJson(); - b.Property("ShadowString"); - }); - modelBuilder.Entity().OwnsOne( - x => x.ReferenceWithCtor, b => - { - b.ToJson(); - b.Property("Shadow_Int").HasJsonPropertyName("ShadowInt"); - }); - modelBuilder.Entity().OwnsMany( - x => x.Collection, b => - { - b.ToJson(); - b.Property("ShadowDouble"); - }); - modelBuilder.Entity().OwnsMany( - x => x.CollectionWithCtor, b => - { - b.ToJson(); - b.Property("ShadowNullableByte"); - }); - } - } + protected abstract Task SeedShadowProperties(DbContext ctx); + + protected virtual void BuildModelShadowProperties(ModelBuilder modelBuilder) + => modelBuilder.Entity( + b => + { + b.ToTable("Entities"); + b.Property(x => x.Id).ValueGeneratedNever(); + + b.OwnsOne( + x => x.Reference, b => + { + b.ToJson().HasColumnType(JsonColumnType); + b.Property("ShadowString"); + }); + + b.OwnsOne( + x => x.ReferenceWithCtor, b => + { + b.ToJson().HasColumnType(JsonColumnType); + b.Property("Shadow_Int").HasJsonPropertyName("ShadowInt"); + }); + + b.OwnsMany( + x => x.Collection, b => + { + b.ToJson().HasColumnType(JsonColumnType); + b.Property("ShadowDouble"); + }); + + b.OwnsMany( + x => x.CollectionWithCtor, b => + { + b.ToJson().HasColumnType(JsonColumnType); + b.Property("ShadowNullableByte"); + }); + }); public class MyEntityShadowProperties { @@ -885,14 +914,19 @@ public class MyJsonEntityShadowPropertiesWithCtor(string name) [MemberData(nameof(IsAsyncData))] public virtual async Task Project_proxies_entity_with_json(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeAsync( + onModelCreating: BuildModelLazyLoadingProxies, seed: SeedLazyLoadingProxies, - onConfiguring: OnConfiguringLazyLoadingProxies, + onConfiguring: b => + { + b = b.ConfigureWarnings(ConfigureWarnings); + OnConfiguringLazyLoadingProxies(b); + }, addServices: AddServicesLazyLoadingProxies); using (var context = contextFactory.CreateContext()) { - var query = context.Entities; + var query = context.Set(); var result = async ? await query.ToListAsync() @@ -908,7 +942,7 @@ protected void OnConfiguringLazyLoadingProxies(DbContextOptionsBuilder optionsBu protected IServiceCollection AddServicesLazyLoadingProxies(IServiceCollection addServices) => addServices.AddEntityFrameworkProxies(); - private Task SeedLazyLoadingProxies(MyContextLazyLoadingProxies ctx) + private Task SeedLazyLoadingProxies(DbContext ctx) { var r1 = new MyJsonEntityLazyLoadingProxiesWithCtor("r1", 1); var c11 = new MyJsonEntityLazyLoadingProxies { Name = "c11", Number = 11 }; @@ -940,20 +974,15 @@ private Task SeedLazyLoadingProxies(MyContextLazyLoadingProxies ctx) Collection = [c21, c22] }; - ctx.Entities.AddRange(e1, e2); + ctx.Set().AddRange(e1, e2); return ctx.SaveChangesAsync(); } - protected class MyContextLazyLoadingProxies(DbContextOptions options) : DbContext(options) + protected virtual void BuildModelLazyLoadingProxies(ModelBuilder modelBuilder) { - public DbSet Entities { get; set; } - - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - modelBuilder.Entity().Property(x => x.Id).ValueGeneratedNever(); - modelBuilder.Entity().OwnsOne(x => x.Reference, b => b.ToJson()); - modelBuilder.Entity().OwnsMany(x => x.Collection, b => b.ToJson()); - } + modelBuilder.Entity().Property(x => x.Id).ValueGeneratedNever(); + modelBuilder.Entity().OwnsOne(x => x.Reference, b => b.ToJson().HasColumnType(JsonColumnType)); + modelBuilder.Entity().OwnsMany(x => x.Collection, b => b.ToJson().HasColumnType(JsonColumnType)); } public class MyEntityLazyLoadingProxies @@ -985,12 +1014,14 @@ public class MyJsonEntityLazyLoadingProxies [MemberData(nameof(IsAsyncData))] public virtual async Task Not_ICollection_basic_projection(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeAsync( + onModelCreating: BuildModelNotICollection, + onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedNotICollection); using (var context = contextFactory.CreateContext()) { - var query = context.Entities; + var query = context.Set(); var result = async ? await query.ToListAsync() @@ -1000,7 +1031,7 @@ public virtual async Task Not_ICollection_basic_projection(bool async) } } - protected abstract Task SeedNotICollection(MyContextNotICollection ctx); + protected abstract Task SeedNotICollection(DbContext ctx); public class MyEntityNotICollection { @@ -1023,24 +1054,25 @@ public class MyJsonNestedEntityNotICollection public int Bar { get; set; } } - public class MyContextNotICollection(DbContextOptions options) : DbContext(options) - { - public DbSet Entities { get; set; } - - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - modelBuilder.Entity().Property(x => x.Id).ValueGeneratedNever(); - modelBuilder.Entity().OwnsOne( - cr => cr.Json, nb => - { - nb.ToJson(); - nb.OwnsMany(x => x.Collection); - }); - } - } + protected virtual void BuildModelNotICollection(ModelBuilder modelBuilder) + => modelBuilder.Entity( + b => + { + b.ToTable("Entities"); + b.Property(x => x.Id).ValueGeneratedNever(); + b.OwnsOne( + cr => cr.Json, nb => + { + nb.ToJson().HasColumnType(JsonColumnType); + nb.OwnsMany(x => x.Collection); + }); + }); #endregion protected TestSqlLoggerFactory TestSqlLoggerFactory => (TestSqlLoggerFactory)ListLoggerFactory; + + protected virtual string JsonColumnType + => null; } diff --git a/test/EFCore.Relational.Specification.Tests/Query/AdHocMiscellaneousQueryRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/AdHocMiscellaneousQueryRelationalTestBase.cs index d27d4c9d37c..6f58c2da809 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/AdHocMiscellaneousQueryRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/AdHocMiscellaneousQueryRelationalTestBase.cs @@ -1,11 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable disable + using System.ComponentModel.DataAnnotations.Schema; using NameSpace1; -#nullable disable - namespace Microsoft.EntityFrameworkCore.Query { public abstract class AdHocMiscellaneousQueryRelationalTestBase : AdHocMiscellaneousQueryTestBase diff --git a/test/EFCore.Relational.Specification.Tests/Query/AdHocNavigationsQueryRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/AdHocNavigationsQueryRelationalTestBase.cs index 31fa22cdf6c..d4da75680e7 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/AdHocNavigationsQueryRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/AdHocNavigationsQueryRelationalTestBase.cs @@ -44,7 +44,8 @@ public virtual async Task Select_enumerable_navigation_backed_by_collection(bool } } - private class Context21803(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context21803(DbContextOptions options) : DbContext(options) { public DbSet Entities { get; set; } diff --git a/test/EFCore.Relational.Specification.Tests/Query/AdHocPrecompiledQueryRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/AdHocPrecompiledQueryRelationalTestBase.cs index 2984bc2895a..9c7fc1a7bd2 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/AdHocPrecompiledQueryRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/AdHocPrecompiledQueryRelationalTestBase.cs @@ -7,6 +7,7 @@ namespace Microsoft.EntityFrameworkCore.Query; +[Collection("PrecompiledQuery")] public abstract class AdHocPrecompiledQueryRelationalTestBase(ITestOutputHelper testOutputHelper) : NonSharedModelTestBase { [ConditionalFact] @@ -22,8 +23,8 @@ await Test( var blogs = context.JsonEntities.Where(b => b.IntList[b.Id] == 2).ToList(); """, - typeof(JsonContext), - options); + typeof(JsonContext), + options); } [ConditionalFact] @@ -117,7 +118,8 @@ await Test( Assert.Contains("var instance = UnsafeAccessor_Microsoft_EntityFrameworkCore_Query_NonPublicEntity_Ctor();", code); Assert.Contains("UnsafeAccessor_Microsoft_EntityFrameworkCore_Query_NonPublicEntity_Id_Set(instance) =", code); - Assert.Contains("UnsafeAccessor_Microsoft_EntityFrameworkCore_Query_NonPublicEntity_PrivateAutoProperty_Set(instance) =", code); + Assert.Contains( + "UnsafeAccessor_Microsoft_EntityFrameworkCore_Query_NonPublicEntity_PrivateAutoProperty_Set(instance) =", code); Assert.Contains("UnsafeAccessor_Microsoft_EntityFrameworkCore_Query_NonPublicEntity_set_PrivateProperty(instance,", code); Assert.Contains("UnsafeAccessor_Microsoft_EntityFrameworkCore_Query_NonPublicEntity__privateField_Set(instance) =", code); }); @@ -158,6 +160,7 @@ private int? PrivateProperty get => _privatePropertyBackingField; set => _privatePropertyBackingField = value; } + private int? _privatePropertyBackingField; private int? PrivateAutoProperty { get; set; } diff --git a/test/EFCore.Relational.Specification.Tests/Query/AdHocQuerySplittingQueryTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/AdHocQuerySplittingQueryTestBase.cs index db6a201e52f..94e3b92137e 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/AdHocQuerySplittingQueryTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/AdHocQuerySplittingQueryTestBase.cs @@ -148,7 +148,7 @@ protected class Context21355(DbContextOptions options) : DbContext(options) public async Task SeedAsync() { - Add(new Parent { Id = "Parent1", Children1 = [new(), new()] }); + Add(new Parent { Id = "Parent1", Children1 = [new Child(), new Child()] }); await SaveChangesAsync(); } @@ -249,8 +249,7 @@ protected virtual Task CreateTestStore25225() .Select( c => new Context25225.CollectionViewModel { - Id = c.Id, - ParentId = c.ParentId, + Id = c.Id, ParentId = c.ParentId, }) .ToArray() }); @@ -330,7 +329,8 @@ public virtual async Task NoTracking_split_query_creates_only_required_instances Assert.Equal(1, Context25400.Test.ConstructorCallCount); } - private class Context25400(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context25400(DbContextOptions options) : DbContext(options) { public DbSet Tests { get; set; } @@ -349,14 +349,10 @@ public class Test public static int ConstructorCallCount; public Test() - { - ++ConstructorCallCount; - } + => ++ConstructorCallCount; public Test(int value) - { - Value = value; - } + => Value = value; public int Id { get; set; } public int Value { get; set; } @@ -364,4 +360,104 @@ public Test(int value) } #endregion + + #region 34728 + + [ConditionalTheory] + [InlineData(true)] + [InlineData(false)] + public virtual async Task NoTrackingWithIdentityResolution_split_query_basic(bool async) + { + var contextFactory = await InitializeAsync( + onConfiguring: o => SetQuerySplittingBehavior(o, QuerySplittingBehavior.SplitQuery)); + + using var context = contextFactory.CreateContext(); + var query = context.Set() + .AsNoTrackingWithIdentityResolution() + .Select( + blog => new + { + blog.Id, + Posts = blog.Posts.Select( + blogPost => new + { + blogPost.Id, + blogPost.Author + }).ToList() + }); + + var test = async + ? await query.ToListAsync() + : query.ToList(); + } + + [ConditionalTheory] + [InlineData(true)] + [InlineData(false)] + public virtual async Task NoTrackingWithIdentityResolution_split_query_complex(bool async) + { + var contextFactory = await InitializeAsync( + onConfiguring: o => SetQuerySplittingBehavior(o, QuerySplittingBehavior.SplitQuery)); + + using var context = contextFactory.CreateContext(); + var query = context.Set() + .AsNoTrackingWithIdentityResolution() + .Select( + blog => new + { + blog.Id, + Posts = blog.Posts.Select( + blogPost => new + { + blogPost.Id, + blogPost.Author + }).ToList(), + Posts2 = blog.Posts.Select(x => new + { + x.Id, + Tags = x.Tags.Select(xx => new + { + xx.Id, + xx.Name, + xx.Name.Length + }).ToList() + }).ToList() + }); + + var test = async + ? await query.ToListAsync() + : query.ToList(); + } + + protected class Context34728(DbContextOptions options) : DbContext(options) + { + public DbSet Tests { get; set; } + + public sealed class Blog + { + public long Id { get; set; } + public string Name { get; set; } + public ISet Posts { get; set; } = new HashSet(); + } + + public sealed class BlogPost + { + public long Id { get; set; } + public WebAccount Author { get; set; } + public List Tags { get; set; } + } + + public sealed class WebAccount + { + public long Id { get; set; } + } + + public sealed class Tag + { + public int Id { get; set; } + public string Name { get; set; } + } + } + + #endregion } diff --git a/test/EFCore.Relational.Specification.Tests/Query/ComplexNavigationsSharedTypeQueryRelationalFixtureBase.cs b/test/EFCore.Relational.Specification.Tests/Query/ComplexNavigationsSharedTypeQueryRelationalFixtureBase.cs index 6a74dee8c8e..298481c9d8d 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/ComplexNavigationsSharedTypeQueryRelationalFixtureBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/ComplexNavigationsSharedTypeQueryRelationalFixtureBase.cs @@ -7,7 +7,8 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public abstract class ComplexNavigationsSharedTypeQueryRelationalFixtureBase : ComplexNavigationsSharedTypeQueryFixtureBase, ITestSqlLoggerFactory +public abstract class ComplexNavigationsSharedTypeQueryRelationalFixtureBase : ComplexNavigationsSharedTypeQueryFixtureBase, + ITestSqlLoggerFactory { public TestSqlLoggerFactory TestSqlLoggerFactory => (TestSqlLoggerFactory)ListLoggerFactory; diff --git a/test/EFCore.Relational.Specification.Tests/Query/EntitySplittingQueryTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/EntitySplittingQueryTestBase.cs index c30158fe590..19bfbbb4a6d 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/EntitySplittingQueryTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/EntitySplittingQueryTestBase.cs @@ -11,9 +11,7 @@ namespace Microsoft.EntityFrameworkCore.Query; public abstract class EntitySplittingQueryTestBase : NonSharedModelTestBase { protected EntitySplittingQueryTestBase() - { - _setSourceCreator = GetSetSourceCreator(); - } + => _setSourceCreator = GetSetSourceCreator(); [ConditionalTheory] [MemberData(nameof(IsAsyncData))] @@ -2920,11 +2918,26 @@ protected async Task InitializeContextFactoryAsync(Action onModelC { wc.Log(RelationalEventId.ForeignKeyTpcPrincipalWarning); }), - shouldLogCategory: _ => true, seed: c => SeedAsync(c)); + shouldLogCategory: _ => true); protected virtual EntitySplittingContext CreateContext() => ContextFactory.CreateContext(); + protected override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) + => base.AddOptions(builder) + .UseSeeding( + (c, _) => + { + EntitySplittingData.Instance.AddSeedData((EntitySplittingContext)c); + c.SaveChanges(); + }) + .UseAsyncSeeding( + (c, _, t) => + { + EntitySplittingData.Instance.AddSeedData((EntitySplittingContext)c); + return c.SaveChangesAsync(t); + }); + public void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction) => facade.UseTransaction(transaction.GetDbTransaction()); @@ -2947,9 +2960,6 @@ protected virtual void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(); } - protected virtual Task SeedAsync(EntitySplittingContext context) - => EntitySplittingData.Instance.Seed(context); - public override async Task DisposeAsync() { await base.DisposeAsync(); diff --git a/test/EFCore.Relational.Specification.Tests/Query/FromSqlQueryTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/FromSqlQueryTestBase.cs index 116bc23ab3e..851e0f44191 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/FromSqlQueryTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/FromSqlQueryTestBase.cs @@ -18,9 +18,7 @@ public abstract class FromSqlQueryTestBase : QueryTestBase protected FromSqlQueryTestBase(TFixture fixture) : base(fixture) - { - Fixture.TestSqlLoggerFactory.Clear(); - } + => Fixture.TestSqlLoggerFactory.Clear(); [ConditionalTheory] [MemberData(nameof(IsAsyncData))] @@ -207,7 +205,6 @@ public virtual async Task FromSqlRaw_queryable_simple_different_cased_columns_an : Assert.Throws(() => query.ToList())).Message); } - [ConditionalTheory] [MemberData(nameof(IsAsyncData))] public virtual Task FromSqlRaw_queryable_composed(bool async) diff --git a/test/EFCore.Relational.Specification.Tests/Query/InheritanceRelationshipsQueryRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/InheritanceRelationshipsQueryRelationalTestBase.cs index e9a1787947d..ae4d9996606 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/InheritanceRelationshipsQueryRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/InheritanceRelationshipsQueryRelationalTestBase.cs @@ -7,7 +7,8 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public abstract class InheritanceRelationshipsQueryRelationalTestBase(TFixture fixture) : InheritanceRelationshipsQueryTestBase(fixture) +public abstract class InheritanceRelationshipsQueryRelationalTestBase(TFixture fixture) + : InheritanceRelationshipsQueryTestBase(fixture) where TFixture : InheritanceRelationshipsQueryRelationalFixture, new() { [ConditionalTheory] diff --git a/test/EFCore.Relational.Specification.Tests/Query/JsonQueryRelationalFixture.cs b/test/EFCore.Relational.Specification.Tests/Query/JsonQueryRelationalFixture.cs index 7004dac0a80..8a054c59f57 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/JsonQueryRelationalFixture.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/JsonQueryRelationalFixture.cs @@ -7,7 +7,7 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public abstract class JsonQueryRelationalFixture: JsonQueryFixtureBase, ITestSqlLoggerFactory +public abstract class JsonQueryRelationalFixture : JsonQueryFixtureBase, ITestSqlLoggerFactory { public new RelationalTestStore TestStore => (RelationalTestStore)base.TestStore; @@ -21,12 +21,25 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con modelBuilder.Entity().OwnsOne(x => x.OwnedReferenceRoot).ToJson(); modelBuilder.Entity().OwnsMany(x => x.OwnedCollectionRoot).ToJson(); - - modelBuilder.Entity().OwnsOne(x => x.OwnedReferenceRoot).ToJson("json_reference_custom_naming"); - modelBuilder.Entity().OwnsMany(x => x.OwnedCollectionRoot).ToJson("json_collection_custom_naming"); - + + modelBuilder.Entity().OwnsOne( + x => x.OwnedReferenceRoot, b => + { + b.ToJson("json_reference_custom_naming"); + b.OwnsOne(x => x.OwnedReferenceBranch); + b.OwnsMany(x => x.OwnedCollectionBranch); + }); + + modelBuilder.Entity().OwnsMany( + x => x.OwnedCollectionRoot, b => + { + b.ToJson("json_collection_custom_naming"); + b.OwnsOne(x => x.OwnedReferenceBranch); + b.OwnsMany(x => x.OwnedCollectionBranch); + }); + modelBuilder.Entity().OwnsMany(x => x.OwnedCollection).ToJson(); - + modelBuilder.Entity( b => { diff --git a/test/EFCore.Relational.Specification.Tests/Query/JsonQueryRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/JsonQueryRelationalTestBase.cs index b698d82eb3d..c24220e6add 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/JsonQueryRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/JsonQueryRelationalTestBase.cs @@ -4,6 +4,7 @@ using Microsoft.EntityFrameworkCore.TestModels.JsonQuery; namespace Microsoft.EntityFrameworkCore.Query; + public abstract class JsonQueryRelationalTestBase(TFixture fixture) : JsonQueryTestBase(fixture) where TFixture : JsonQueryRelationalFixture, new() { @@ -122,28 +123,31 @@ public virtual Task FromSql_on_entity_with_json_inheritance_project_reference_on [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Json_projection_using_queryable_methods_on_top_of_JSON_collection_AsNoTrackingWithIdentityResolution(bool async) + public virtual async Task Json_projection_using_queryable_methods_on_top_of_JSON_collection_AsNoTrackingWithIdentityResolution( + bool async) { - var message = (await Assert.ThrowsAsync(() => - AssertQuery( - async, - ss => ss.Set().Select( - x => new - { - x.Id, - Skip = x.OwnedCollectionRoot.Skip(1).ToList(), - Take = x.OwnedCollectionRoot.Take(2).ToList(), - }).AsNoTrackingWithIdentityResolution(), - elementSorter: e => e.Id, - elementAsserter: (e, a) => - { - AssertEqual(e.Id, a.Id); - AssertCollection(e.Skip, a.Skip); - AssertCollection(e.Take, a.Take); - }))).Message; + var message = (await Assert.ThrowsAsync( + () => + AssertQuery( + async, + ss => ss.Set().Select( + x => new + { + x.Id, + Skip = x.OwnedCollectionRoot.Skip(1).ToList(), + Take = x.OwnedCollectionRoot.Take(2).ToList(), + }).AsNoTrackingWithIdentityResolution(), + elementSorter: e => e.Id, + elementAsserter: (e, a) => + { + AssertEqual(e.Id, a.Id); + AssertCollection(e.Skip, a.Skip); + AssertCollection(e.Take, a.Take); + }))).Message; Assert.Equal( - RelationalStrings.JsonProjectingQueryableOperationNoTrackingWithIdentityResolution(nameof(QueryTrackingBehavior.NoTrackingWithIdentityResolution)), + RelationalStrings.JsonProjectingQueryableOperationNoTrackingWithIdentityResolution( + nameof(QueryTrackingBehavior.NoTrackingWithIdentityResolution)), message); } @@ -151,40 +155,42 @@ public virtual async Task Json_projection_using_queryable_methods_on_top_of_JSON [MemberData(nameof(IsAsyncData))] public virtual async Task Json_nested_collection_anonymous_projection_in_projection_NoTrackingWithIdentityResolution(bool async) { - var message = (await Assert.ThrowsAsync(() => - AssertQuery( - async, - ss => ss.Set() - .OrderBy(x => x.Id) - .Select( - x => x.OwnedCollectionRoot - .Select( - xx => xx.OwnedCollectionBranch.Select( - xxx => new - { - xxx.Date, - xxx.Enum, - xxx.Enums, - xxx.Fraction, - xxx.OwnedReferenceLeaf, - xxx.OwnedCollectionLeaf - }).ToList())) - .AsNoTrackingWithIdentityResolution(), - assertOrder: true, - elementAsserter: (e, a) => AssertCollection( - e, a, ordered: true, elementAsserter: (ee, aa) => AssertCollection( - ee, aa, ordered: true, elementAsserter: (eee, aaa) => - { - AssertEqual(eee.Date, aaa.Date); - AssertEqual(eee.Enum, aaa.Enum); - AssertCollection(eee.Enums, aaa.Enums, ordered: true); - AssertEqual(eee.Fraction, aaa.Fraction); - AssertEqual(eee.OwnedReferenceLeaf, aaa.OwnedReferenceLeaf); - AssertCollection(eee.OwnedCollectionLeaf, aaa.OwnedCollectionLeaf, ordered: true); - }))))).Message; + var message = (await Assert.ThrowsAsync( + () => + AssertQuery( + async, + ss => ss.Set() + .OrderBy(x => x.Id) + .Select( + x => x.OwnedCollectionRoot + .Select( + xx => xx.OwnedCollectionBranch.Select( + xxx => new + { + xxx.Date, + xxx.Enum, + xxx.Enums, + xxx.Fraction, + xxx.OwnedReferenceLeaf, + xxx.OwnedCollectionLeaf + }).ToList())) + .AsNoTrackingWithIdentityResolution(), + assertOrder: true, + elementAsserter: (e, a) => AssertCollection( + e, a, ordered: true, elementAsserter: (ee, aa) => AssertCollection( + ee, aa, ordered: true, elementAsserter: (eee, aaa) => + { + AssertEqual(eee.Date, aaa.Date); + AssertEqual(eee.Enum, aaa.Enum); + AssertCollection(eee.Enums, aaa.Enums, ordered: true); + AssertEqual(eee.Fraction, aaa.Fraction); + AssertEqual(eee.OwnedReferenceLeaf, aaa.OwnedReferenceLeaf); + AssertCollection(eee.OwnedCollectionLeaf, aaa.OwnedCollectionLeaf, ordered: true); + }))))).Message; Assert.Equal( - RelationalStrings.JsonProjectingQueryableOperationNoTrackingWithIdentityResolution(nameof(QueryTrackingBehavior.NoTrackingWithIdentityResolution)), + RelationalStrings.JsonProjectingQueryableOperationNoTrackingWithIdentityResolution( + nameof(QueryTrackingBehavior.NoTrackingWithIdentityResolution)), message); } @@ -193,23 +199,24 @@ public virtual async Task Json_nested_collection_anonymous_projection_in_project public virtual async Task Json_projection_nested_collection_and_element_using_parameter_AsNoTrackingWithIdentityResolution(bool async) { var prm = 0; - var message = (await Assert.ThrowsAsync(() => - AssertQuery( - async, - ss => ss.Set().Select( - x => new + var message = (await Assert.ThrowsAsync( + () => + AssertQuery( + async, + ss => ss.Set().Select( + x => new + { + x.Id, + Original = x.OwnedReferenceRoot.OwnedCollectionBranch[prm].OwnedCollectionLeaf, + Duplicate = x.OwnedReferenceRoot.OwnedCollectionBranch[prm].OwnedCollectionLeaf[1], + }).AsNoTrackingWithIdentityResolution(), + elementSorter: e => e.Id, + elementAsserter: (e, a) => { - x.Id, - Original = x.OwnedReferenceRoot.OwnedCollectionBranch[prm].OwnedCollectionLeaf, - Duplicate = x.OwnedReferenceRoot.OwnedCollectionBranch[prm].OwnedCollectionLeaf[1], - }).AsNoTrackingWithIdentityResolution(), - elementSorter: e => e.Id, - elementAsserter: (e, a) => - { - AssertEqual(e.Id, a.Id); - AssertEqual(e.Duplicate, a.Duplicate); - AssertCollection(e.Original, a.Original, ordered: true); - }))).Message; + AssertEqual(e.Id, a.Id); + AssertEqual(e.Duplicate, a.Duplicate); + AssertCollection(e.Original, a.Original, ordered: true); + }))).Message; Assert.Equal( RelationalStrings.JsonProjectingCollectionElementAccessedUsingParmeterNoTrackingWithIdentityResolution( @@ -224,23 +231,24 @@ public virtual async Task Json_projection_nested_collection_and_element_using_pa { var prm1 = 0; var prm2 = 0; - var message = (await Assert.ThrowsAsync(() => - AssertQuery( - async, - ss => ss.Set().Select( - x => new + var message = (await Assert.ThrowsAsync( + () => + AssertQuery( + async, + ss => ss.Set().Select( + x => new + { + x.Id, + Duplicate = x.OwnedReferenceRoot.OwnedCollectionBranch[prm1].OwnedCollectionLeaf[1], + Original = x.OwnedReferenceRoot.OwnedCollectionBranch[prm2].OwnedCollectionLeaf, + }).AsNoTrackingWithIdentityResolution(), + elementSorter: e => e.Id, + elementAsserter: (e, a) => { - x.Id, - Duplicate = x.OwnedReferenceRoot.OwnedCollectionBranch[prm1].OwnedCollectionLeaf[1], - Original = x.OwnedReferenceRoot.OwnedCollectionBranch[prm2].OwnedCollectionLeaf, - }).AsNoTrackingWithIdentityResolution(), - elementSorter: e => e.Id, - elementAsserter: (e, a) => - { - AssertEqual(e.Id, a.Id); - AssertEqual(e.Duplicate, a.Duplicate); - AssertCollection(e.Original, a.Original, ordered: true); - }))).Message; + AssertEqual(e.Id, a.Id); + AssertEqual(e.Duplicate, a.Duplicate); + AssertCollection(e.Original, a.Original, ordered: true); + }))).Message; Assert.Equal( RelationalStrings.JsonProjectingCollectionElementAccessedUsingParmeterNoTrackingWithIdentityResolution( @@ -251,28 +259,31 @@ public virtual async Task Json_projection_nested_collection_and_element_using_pa [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Json_projection_second_element_through_collection_element_parameter_different_values_projected_before_owner_nested_AsNoTrackingWithIdentityResolution(bool async) + public virtual async Task + Json_projection_second_element_through_collection_element_parameter_different_values_projected_before_owner_nested_AsNoTrackingWithIdentityResolution( + bool async) { var prm1 = 0; var prm2 = 1; - var message = (await Assert.ThrowsAsync(() => - AssertQuery( - async, - ss => ss.Set().Select( - x => new + var message = (await Assert.ThrowsAsync( + () => + AssertQuery( + async, + ss => ss.Set().Select( + x => new + { + x.Id, + Duplicate = x.OwnedReferenceRoot.OwnedCollectionBranch[prm1].OwnedCollectionLeaf[1], + Original = x.OwnedReferenceRoot.OwnedCollectionBranch[prm2].OwnedCollectionLeaf, + }).AsNoTrackingWithIdentityResolution(), + elementSorter: e => e.Id, + elementAsserter: (e, a) => { - x.Id, - Duplicate = x.OwnedReferenceRoot.OwnedCollectionBranch[prm1].OwnedCollectionLeaf[1], - Original = x.OwnedReferenceRoot.OwnedCollectionBranch[prm2].OwnedCollectionLeaf, - }).AsNoTrackingWithIdentityResolution(), - elementSorter: e => e.Id, - elementAsserter: (e, a) => - { - AssertEqual(e.Id, a.Id); - AssertCollection(e.Original, a.Original, ordered: true); - AssertEqual(e.Duplicate, a.Duplicate); - }))).Message; + AssertEqual(e.Id, a.Id); + AssertCollection(e.Original, a.Original, ordered: true); + AssertEqual(e.Duplicate, a.Duplicate); + }))).Message; Assert.Equal( RelationalStrings.JsonProjectingCollectionElementAccessedUsingParmeterNoTrackingWithIdentityResolution( @@ -283,27 +294,30 @@ public virtual async Task Json_projection_second_element_through_collection_elem [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Json_projection_second_element_through_collection_element_parameter_projected_before_owner_nested_AsNoTrackingWithIdentityResolution(bool async) + public virtual async Task + Json_projection_second_element_through_collection_element_parameter_projected_before_owner_nested_AsNoTrackingWithIdentityResolution( + bool async) { var prm = 0; - var message = (await Assert.ThrowsAsync(() => - AssertQuery( - async, - ss => ss.Set().Select( - x => new + var message = (await Assert.ThrowsAsync( + () => + AssertQuery( + async, + ss => ss.Set().Select( + x => new + { + x.Id, + Duplicate = x.OwnedReferenceRoot.OwnedCollectionBranch[prm].OwnedCollectionLeaf[1], + Original = x.OwnedReferenceRoot.OwnedCollectionBranch[prm].OwnedCollectionLeaf, + }).AsNoTrackingWithIdentityResolution(), + elementSorter: e => e.Id, + elementAsserter: (e, a) => { - x.Id, - Duplicate = x.OwnedReferenceRoot.OwnedCollectionBranch[prm].OwnedCollectionLeaf[1], - Original = x.OwnedReferenceRoot.OwnedCollectionBranch[prm].OwnedCollectionLeaf, - }).AsNoTrackingWithIdentityResolution(), - elementSorter: e => e.Id, - elementAsserter: (e, a) => - { - AssertEqual(e.Id, a.Id); - AssertCollection(e.Original, a.Original, ordered: true); - AssertEqual(e.Duplicate, a.Duplicate); - }))).Message; + AssertEqual(e.Id, a.Id); + AssertCollection(e.Original, a.Original, ordered: true); + AssertEqual(e.Duplicate, a.Duplicate); + }))).Message; Assert.Equal( RelationalStrings.JsonProjectingCollectionElementAccessedUsingParmeterNoTrackingWithIdentityResolution( @@ -314,28 +328,31 @@ public virtual async Task Json_projection_second_element_through_collection_elem [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Json_projection_second_element_through_collection_element_parameter_projected_before_owner_nested_AsNoTrackingWithIdentityResolution2(bool async) + public virtual async Task + Json_projection_second_element_through_collection_element_parameter_projected_before_owner_nested_AsNoTrackingWithIdentityResolution2( + bool async) { var prm1 = 0; var prm2 = 0; - var message = (await Assert.ThrowsAsync(() => - AssertQuery( - async, - ss => ss.Set().Select( - x => new + var message = (await Assert.ThrowsAsync( + () => + AssertQuery( + async, + ss => ss.Set().Select( + x => new + { + x.Id, + Duplicate = x.OwnedReferenceRoot.OwnedCollectionBranch[prm1].OwnedCollectionLeaf[1], + Original = x.OwnedReferenceRoot.OwnedCollectionBranch[prm2].OwnedCollectionLeaf, + }).AsNoTrackingWithIdentityResolution(), + elementSorter: e => e.Id, + elementAsserter: (e, a) => { - x.Id, - Duplicate = x.OwnedReferenceRoot.OwnedCollectionBranch[prm1].OwnedCollectionLeaf[1], - Original = x.OwnedReferenceRoot.OwnedCollectionBranch[prm2].OwnedCollectionLeaf, - }).AsNoTrackingWithIdentityResolution(), - elementSorter: e => e.Id, - elementAsserter: (e, a) => - { - AssertEqual(e.Id, a.Id); - AssertEqual(e.Original, a.Original); - AssertEqual(e.Duplicate, a.Duplicate); - }))).Message; + AssertEqual(e.Id, a.Id); + AssertEqual(e.Original, a.Original); + AssertEqual(e.Duplicate, a.Duplicate); + }))).Message; Assert.Equal( RelationalStrings.JsonProjectingCollectionElementAccessedUsingParmeterNoTrackingWithIdentityResolution( @@ -346,27 +363,30 @@ public virtual async Task Json_projection_second_element_through_collection_elem [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Json_projection_second_element_through_collection_element_parameter_projected_after_owner_nested_AsNoTrackingWithIdentityResolution(bool async) + public virtual async Task + Json_projection_second_element_through_collection_element_parameter_projected_after_owner_nested_AsNoTrackingWithIdentityResolution( + bool async) { var prm = 0; - var message = (await Assert.ThrowsAsync(() => - AssertQuery( - async, - ss => ss.Set().Select( - x => new + var message = (await Assert.ThrowsAsync( + () => + AssertQuery( + async, + ss => ss.Set().Select( + x => new + { + x.Id, + Original = x.OwnedReferenceRoot.OwnedCollectionBranch[prm].OwnedCollectionLeaf, + Duplicate = x.OwnedReferenceRoot.OwnedCollectionBranch[prm].OwnedCollectionLeaf[1], + }).AsNoTrackingWithIdentityResolution(), + elementSorter: e => e.Id, + elementAsserter: (e, a) => { - x.Id, - Original = x.OwnedReferenceRoot.OwnedCollectionBranch[prm].OwnedCollectionLeaf, - Duplicate = x.OwnedReferenceRoot.OwnedCollectionBranch[prm].OwnedCollectionLeaf[1], - }).AsNoTrackingWithIdentityResolution(), - elementSorter: e => e.Id, - elementAsserter: (e, a) => - { - AssertEqual(e.Id, a.Id); - AssertCollection(e.Original, a.Original, ordered: true); - AssertEqual(e.Duplicate, a.Duplicate); - }))).Message; + AssertEqual(e.Id, a.Id); + AssertCollection(e.Original, a.Original, ordered: true); + AssertEqual(e.Duplicate, a.Duplicate); + }))).Message; Assert.Equal( RelationalStrings.JsonProjectingCollectionElementAccessedUsingParmeterNoTrackingWithIdentityResolution( @@ -377,25 +397,28 @@ public virtual async Task Json_projection_second_element_through_collection_elem [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Json_projection_second_element_through_collection_element_constant_projected_before_owner_nested_AsNoTrackingWithIdentityResolution(bool async) + public virtual async Task + Json_projection_second_element_through_collection_element_constant_projected_before_owner_nested_AsNoTrackingWithIdentityResolution( + bool async) { - var message = (await Assert.ThrowsAsync(() => - AssertQuery( - async, - ss => ss.Set().Select( - x => new - { - x.Id, - Duplicate = x.OwnedReferenceRoot.OwnedCollectionBranch[0].OwnedCollectionLeaf[1], - Original = x.OwnedReferenceRoot.OwnedCollectionBranch[0].OwnedCollectionLeaf, - }).AsNoTrackingWithIdentityResolution(), - elementSorter: e => e.Id, - elementAsserter: (e, a) => - { - AssertEqual(e.Id, a.Id); - AssertEqual(e.Original, a.Original); - AssertEqual(e.Duplicate, a.Duplicate); - }))).Message; + var message = (await Assert.ThrowsAsync( + () => + AssertQuery( + async, + ss => ss.Set().Select( + x => new + { + x.Id, + Duplicate = x.OwnedReferenceRoot.OwnedCollectionBranch[0].OwnedCollectionLeaf[1], + Original = x.OwnedReferenceRoot.OwnedCollectionBranch[0].OwnedCollectionLeaf, + }).AsNoTrackingWithIdentityResolution(), + elementSorter: e => e.Id, + elementAsserter: (e, a) => + { + AssertEqual(e.Id, a.Id); + AssertEqual(e.Original, a.Original); + AssertEqual(e.Duplicate, a.Duplicate); + }))).Message; Assert.Equal( RelationalStrings.JsonProjectingEntitiesIncorrectOrderNoTrackingWithIdentityResolution( @@ -408,27 +431,29 @@ public virtual async Task Json_projection_second_element_through_collection_elem [MemberData(nameof(IsAsyncData))] public virtual async Task Json_branch_collection_distinct_and_other_collection_AsNoTrackingWithIdentityResolution(bool async) { - var message = (await Assert.ThrowsAsync(() => - AssertQuery( - async, - ss => ss.Set() - .OrderBy(x => x.Id) - .Select( - x => new - { - First = x.EntityCollection.ToList(), - Second = x.OwnedReferenceRoot.OwnedCollectionBranch.Distinct().ToList() - }) - .AsNoTrackingWithIdentityResolution(), - assertOrder: true, - elementAsserter: (e, a) => - { - AssertCollection(e.First, a.First, ordered: true); - AssertCollection(e.Second, a.Second, elementSorter: ee => ee.Fraction); - }))).Message; + var message = (await Assert.ThrowsAsync( + () => + AssertQuery( + async, + ss => ss.Set() + .OrderBy(x => x.Id) + .Select( + x => new + { + First = x.EntityCollection.ToList(), + Second = x.OwnedReferenceRoot.OwnedCollectionBranch.Distinct().ToList() + }) + .AsNoTrackingWithIdentityResolution(), + assertOrder: true, + elementAsserter: (e, a) => + { + AssertCollection(e.First, a.First, ordered: true); + AssertCollection(e.Second, a.Second, elementSorter: ee => ee.Fraction); + }))).Message; Assert.Equal( - RelationalStrings.JsonProjectingQueryableOperationNoTrackingWithIdentityResolution(nameof(QueryTrackingBehavior.NoTrackingWithIdentityResolution)), + RelationalStrings.JsonProjectingQueryableOperationNoTrackingWithIdentityResolution( + nameof(QueryTrackingBehavior.NoTrackingWithIdentityResolution)), message); } @@ -436,8 +461,9 @@ public virtual async Task Json_branch_collection_distinct_and_other_collection_A [MemberData(nameof(IsAsyncData))] public virtual async Task Json_collection_SelectMany_AsNoTrackingWithIdentityResolution(bool async) { - var message = (await Assert.ThrowsAsync(() => - AssertQuery( + var message = (await Assert.ThrowsAsync( + () => + AssertQuery( async, ss => ss.Set() .SelectMany(x => x.OwnedCollectionRoot) @@ -445,7 +471,8 @@ public virtual async Task Json_collection_SelectMany_AsNoTrackingWithIdentityRes elementSorter: e => (e.Number, e.Name)))).Message; Assert.Equal( - RelationalStrings.JsonProjectingQueryableOperationNoTrackingWithIdentityResolution(nameof(QueryTrackingBehavior.NoTrackingWithIdentityResolution)), + RelationalStrings.JsonProjectingQueryableOperationNoTrackingWithIdentityResolution( + nameof(QueryTrackingBehavior.NoTrackingWithIdentityResolution)), message); } @@ -454,25 +481,26 @@ public virtual async Task Json_collection_SelectMany_AsNoTrackingWithIdentityRes public virtual async Task Json_projection_deduplication_with_collection_indexer_in_target_AsNoTrackingWithIdentityResolution(bool async) { var prm = 1; - var message = (await Assert.ThrowsAsync(() => - AssertQuery( - async, - ss => ss.Set().Select( - x => new + var message = (await Assert.ThrowsAsync( + () => + AssertQuery( + async, + ss => ss.Set().Select( + x => new + { + x.Id, + Duplicate1 = x.OwnedReferenceRoot.OwnedCollectionBranch[1], + Original = x.OwnedReferenceRoot, + Duplicate2 = x.OwnedReferenceRoot.OwnedReferenceBranch.OwnedCollectionLeaf[prm] + }).AsNoTrackingWithIdentityResolution(), + elementSorter: e => e.Id, + elementAsserter: (e, a) => { - x.Id, - Duplicate1 = x.OwnedReferenceRoot.OwnedCollectionBranch[1], - Original = x.OwnedReferenceRoot, - Duplicate2 = x.OwnedReferenceRoot.OwnedReferenceBranch.OwnedCollectionLeaf[prm] - }).AsNoTrackingWithIdentityResolution(), - elementSorter: e => e.Id, - elementAsserter: (e, a) => - { - AssertEqual(e.Id, a.Id); - AssertEqual(e.Original, a.Original); - AssertEqual(e.Duplicate1, a.Duplicate1); - AssertEqual(e.Duplicate2, a.Duplicate2); - }))).Message; + AssertEqual(e.Id, a.Id); + AssertEqual(e.Original, a.Original); + AssertEqual(e.Duplicate1, a.Duplicate1); + AssertEqual(e.Duplicate2, a.Duplicate2); + }))).Message; Assert.Equal( RelationalStrings.JsonProjectingEntitiesIncorrectOrderNoTrackingWithIdentityResolution( @@ -485,23 +513,24 @@ public virtual async Task Json_projection_deduplication_with_collection_indexer_ [MemberData(nameof(IsAsyncData))] public virtual async Task Json_projection_nested_collection_and_element_wrong_order_AsNoTrackingWithIdentityResolution(bool async) { - var message = (await Assert.ThrowsAsync(() => - AssertQuery( - async, - ss => ss.Set().Select( - x => new + var message = (await Assert.ThrowsAsync( + () => + AssertQuery( + async, + ss => ss.Set().Select( + x => new + { + x.Id, + Duplicate = x.OwnedReferenceRoot.OwnedCollectionBranch[0].OwnedCollectionLeaf[1], + Original = x.OwnedReferenceRoot.OwnedCollectionBranch[0].OwnedCollectionLeaf, + }).AsNoTrackingWithIdentityResolution(), + elementSorter: e => e.Id, + elementAsserter: (e, a) => { - x.Id, - Duplicate = x.OwnedReferenceRoot.OwnedCollectionBranch[0].OwnedCollectionLeaf[1], - Original = x.OwnedReferenceRoot.OwnedCollectionBranch[0].OwnedCollectionLeaf, - }).AsNoTrackingWithIdentityResolution(), - elementSorter: e => e.Id, - elementAsserter: (e, a) => - { - AssertEqual(e.Id, a.Id); - AssertEqual(e.Duplicate, a.Duplicate); - AssertCollection(e.Original, a.Original, ordered: true); - }))).Message; + AssertEqual(e.Id, a.Id); + AssertEqual(e.Duplicate, a.Duplicate); + AssertCollection(e.Original, a.Original, ordered: true); + }))).Message; Assert.Equal( RelationalStrings.JsonProjectingEntitiesIncorrectOrderNoTrackingWithIdentityResolution( @@ -512,25 +541,27 @@ public virtual async Task Json_projection_nested_collection_and_element_wrong_or [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Json_projection_second_element_projected_before_entire_collection_AsNoTrackingWithIdentityResolution(bool async) + public virtual async Task Json_projection_second_element_projected_before_entire_collection_AsNoTrackingWithIdentityResolution( + bool async) { - var message = (await Assert.ThrowsAsync(() => - AssertQuery( - async, - ss => ss.Set().Select( - x => new + var message = (await Assert.ThrowsAsync( + () => + AssertQuery( + async, + ss => ss.Set().Select( + x => new + { + x.Id, + Duplicate = x.OwnedReferenceRoot.OwnedCollectionBranch[1], + Original = x.OwnedReferenceRoot.OwnedCollectionBranch, + }).AsNoTrackingWithIdentityResolution(), + elementSorter: e => e.Id, + elementAsserter: (e, a) => { - x.Id, - Duplicate = x.OwnedReferenceRoot.OwnedCollectionBranch[1], - Original = x.OwnedReferenceRoot.OwnedCollectionBranch, - }).AsNoTrackingWithIdentityResolution(), - elementSorter: e => e.Id, - elementAsserter: (e, a) => - { - AssertEqual(e.Id, a.Id); - AssertEqual(e.Original, a.Original); - AssertEqual(e.Duplicate, a.Duplicate); - }))).Message; + AssertEqual(e.Id, a.Id); + AssertEqual(e.Original, a.Original); + AssertEqual(e.Duplicate, a.Duplicate); + }))).Message; Assert.Equal( RelationalStrings.JsonProjectingEntitiesIncorrectOrderNoTrackingWithIdentityResolution( @@ -543,23 +574,24 @@ public virtual async Task Json_projection_second_element_projected_before_entire [MemberData(nameof(IsAsyncData))] public virtual async Task Json_projection_second_element_projected_before_owner_AsNoTrackingWithIdentityResolution(bool async) { - var message = (await Assert.ThrowsAsync(() => - AssertQuery( - async, - ss => ss.Set().Select( - x => new + var message = (await Assert.ThrowsAsync( + () => + AssertQuery( + async, + ss => ss.Set().Select( + x => new + { + x.Id, + Duplicate = x.OwnedReferenceRoot.OwnedCollectionBranch[1], + Original = x.OwnedReferenceRoot, + }).AsNoTrackingWithIdentityResolution(), + elementSorter: e => e.Id, + elementAsserter: (e, a) => { - x.Id, - Duplicate = x.OwnedReferenceRoot.OwnedCollectionBranch[1], - Original = x.OwnedReferenceRoot, - }).AsNoTrackingWithIdentityResolution(), - elementSorter: e => e.Id, - elementAsserter: (e, a) => - { - AssertEqual(e.Id, a.Id); - AssertEqual(e.Original, a.Original); - AssertEqual(e.Duplicate, a.Duplicate); - }))).Message; + AssertEqual(e.Id, a.Id); + AssertEqual(e.Original, a.Original); + AssertEqual(e.Duplicate, a.Duplicate); + }))).Message; Assert.Equal( RelationalStrings.JsonProjectingEntitiesIncorrectOrderNoTrackingWithIdentityResolution( @@ -572,24 +604,25 @@ public virtual async Task Json_projection_second_element_projected_before_owner_ [MemberData(nameof(IsAsyncData))] public virtual async Task Json_projection_second_element_projected_before_owner_nested_AsNoTrackingWithIdentityResolution(bool async) { - var message = (await Assert.ThrowsAsync(() => - AssertQuery( - async, - ss => ss.Set().Select( - x => new + var message = (await Assert.ThrowsAsync( + () => + AssertQuery( + async, + ss => ss.Set().Select( + x => new + { + x.Id, + Duplicate = x.OwnedReferenceRoot.OwnedReferenceBranch.OwnedCollectionLeaf[1], + Original = x.OwnedReferenceRoot.OwnedReferenceBranch.OwnedCollectionLeaf, + Parent = x.OwnedReferenceRoot.OwnedReferenceBranch, + }).AsNoTrackingWithIdentityResolution(), + elementSorter: e => e.Id, + elementAsserter: (e, a) => { - x.Id, - Duplicate = x.OwnedReferenceRoot.OwnedReferenceBranch.OwnedCollectionLeaf[1], - Original = x.OwnedReferenceRoot.OwnedReferenceBranch.OwnedCollectionLeaf, - Parent = x.OwnedReferenceRoot.OwnedReferenceBranch, - }).AsNoTrackingWithIdentityResolution(), - elementSorter: e => e.Id, - elementAsserter: (e, a) => - { - AssertEqual(e.Id, a.Id); - AssertEqual(e.Original, a.Original); - AssertEqual(e.Duplicate, a.Duplicate); - }))).Message; + AssertEqual(e.Id, a.Id); + AssertEqual(e.Original, a.Original); + AssertEqual(e.Duplicate, a.Duplicate); + }))).Message; Assert.Equal( RelationalStrings.JsonProjectingEntitiesIncorrectOrderNoTrackingWithIdentityResolution( diff --git a/test/EFCore.Relational.Specification.Tests/Query/NonSharedPrimitiveCollectionsQueryRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/NonSharedPrimitiveCollectionsQueryRelationalTestBase.cs index 83de7279aa4..e08f86ad249 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/NonSharedPrimitiveCollectionsQueryRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/NonSharedPrimitiveCollectionsQueryRelationalTestBase.cs @@ -12,6 +12,10 @@ public abstract class NonSharedPrimitiveCollectionsQueryRelationalTestBase : Non public override Task Array_of_byte() => AssertTranslationFailed(() => TestArray((byte)1, (byte)2)); + protected abstract DbContextOptionsBuilder SetTranslateParameterizedCollectionsToConstants(DbContextOptionsBuilder optionsBuilder); + + protected abstract DbContextOptionsBuilder SetTranslateParameterizedCollectionsToParameters(DbContextOptionsBuilder optionsBuilder); + [ConditionalFact] public virtual async Task Column_collection_inside_json_owned_entity() { @@ -34,6 +38,171 @@ public virtual async Task Column_collection_inside_json_owned_entity() Assert.Equivalent(new[] { "foo", "bar" }, result.Owned.Strings); } + [ConditionalFact] + public virtual async Task Parameter_collection_Count_with_column_predicate_with_default_constants() + { + var contextFactory = await InitializeAsync( + onConfiguring: b => SetTranslateParameterizedCollectionsToConstants(b), + seed: context => + { + context.AddRange( + new TestEntity { Id = 1 }, + new TestEntity { Id = 100 }); + return context.SaveChangesAsync(); + }); + + await using var context = contextFactory.CreateContext(); + + var ids = new[] { 2, 999 }; + var result = await context.Set().Where(c => ids.Count(i => i > c.Id) == 1).Select(x => x.Id).ToListAsync(); + Assert.Equivalent(new[] { 100 }, result); + } + + [ConditionalFact] + public virtual async Task Parameter_collection_of_ints_Contains_int_with_default_constants() + { + var contextFactory = await InitializeAsync( + onConfiguring: b => SetTranslateParameterizedCollectionsToConstants(b), + seed: context => + { + context.AddRange( + new TestEntity { Id = 1 }, + new TestEntity { Id = 2 }, + new TestEntity { Id = 100 }); + return context.SaveChangesAsync(); + }); + + await using var context = contextFactory.CreateContext(); + + var ints = new[] { 2, 999 }; + var result = await context.Set().Where(c => ints.Contains(c.Id)).Select(x => x.Id).ToListAsync(); + Assert.Equivalent(new[] { 2 }, result); + } + + [ConditionalFact] + public virtual async Task Parameter_collection_Count_with_column_predicate_with_default_constants_EF_Parameter() + { + var contextFactory = await InitializeAsync( + onConfiguring: b => SetTranslateParameterizedCollectionsToConstants(b), + seed: context => + { + context.AddRange( + new TestEntity { Id = 1 }, + new TestEntity { Id = 100 }); + return context.SaveChangesAsync(); + }); + + await using var context = contextFactory.CreateContext(); + + var ids = new[] { 2, 999 }; + var result = await context.Set().Where(c => EF.Parameter(ids).Count(i => i > c.Id) == 1).Select(x => x.Id) + .ToListAsync(); + Assert.Equivalent(new[] { 100 }, result); + } + + [ConditionalFact] + public virtual async Task Parameter_collection_of_ints_Contains_int_with_default_constants_EF_Parameter() + { + var contextFactory = await InitializeAsync( + onConfiguring: b => SetTranslateParameterizedCollectionsToConstants(b), + seed: context => + { + context.AddRange( + new TestEntity { Id = 1 }, + new TestEntity { Id = 2 }, + new TestEntity { Id = 100 }); + return context.SaveChangesAsync(); + }); + + await using var context = contextFactory.CreateContext(); + + var ints = new[] { 2, 999 }; + var result = await context.Set().Where(c => EF.Parameter(ints).Contains(c.Id)).Select(x => x.Id).ToListAsync(); + Assert.Equivalent(new[] { 2 }, result); + } + + [ConditionalFact] + public virtual async Task Parameter_collection_Count_with_column_predicate_with_default_parameters() + { + var contextFactory = await InitializeAsync( + onConfiguring: b => SetTranslateParameterizedCollectionsToParameters(b), + seed: context => + { + context.AddRange( + new TestEntity { Id = 1 }, + new TestEntity { Id = 100 }); + return context.SaveChangesAsync(); + }); + + await using var context = contextFactory.CreateContext(); + + var ids = new[] { 2, 999 }; + var result = await context.Set().Where(c => ids.Count(i => i > c.Id) == 1).Select(x => x.Id).ToListAsync(); + Assert.Equivalent(new[] { 100 }, result); + } + + [ConditionalFact] + public virtual async Task Parameter_collection_of_ints_Contains_int_with_default_parameters() + { + var contextFactory = await InitializeAsync( + onConfiguring: b => SetTranslateParameterizedCollectionsToParameters(b), + seed: context => + { + context.AddRange( + new TestEntity { Id = 1 }, + new TestEntity { Id = 2 }, + new TestEntity { Id = 100 }); + return context.SaveChangesAsync(); + }); + + await using var context = contextFactory.CreateContext(); + + var ints = new[] { 2, 999 }; + var result = await context.Set().Where(c => ints.Contains(c.Id)).Select(x => x.Id).ToListAsync(); + Assert.Equivalent(new[] { 2 }, result); + } + + [ConditionalFact] + public virtual async Task Parameter_collection_Count_with_column_predicate_with_default_parameters_EF_Constant() + { + var contextFactory = await InitializeAsync( + onConfiguring: b => SetTranslateParameterizedCollectionsToParameters(b), + seed: context => + { + context.AddRange( + new TestEntity { Id = 1 }, + new TestEntity { Id = 100 }); + return context.SaveChangesAsync(); + }); + + await using var context = contextFactory.CreateContext(); + + var ids = new[] { 2, 999 }; + var result = await context.Set().Where(c => EF.Constant(ids).Count(i => i > c.Id) == 1).Select(x => x.Id).ToListAsync(); + Assert.Equivalent(new[] { 100 }, result); + } + + [ConditionalFact] + public virtual async Task Parameter_collection_of_ints_Contains_int_with_default_parameters_EF_Constant() + { + var contextFactory = await InitializeAsync( + onConfiguring: b => SetTranslateParameterizedCollectionsToParameters(b), + seed: context => + { + context.AddRange( + new TestEntity { Id = 1 }, + new TestEntity { Id = 2 }, + new TestEntity { Id = 100 }); + return context.SaveChangesAsync(); + }); + + await using var context = contextFactory.CreateContext(); + + var ints = new[] { 2, 999 }; + var result = await context.Set().Where(c => EF.Constant(ints).Contains(c.Id)).Select(x => x.Id).ToListAsync(); + Assert.Equivalent(new[] { 2 }, result); + } + protected class TestOwner { public int Id { get; set; } diff --git a/test/EFCore.Relational.Specification.Tests/Query/NorthwindFunctionsQueryRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/NorthwindFunctionsQueryRelationalTestBase.cs index b0fdd042b38..1d702595038 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/NorthwindFunctionsQueryRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/NorthwindFunctionsQueryRelationalTestBase.cs @@ -1,8 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.EntityFrameworkCore.TestModels.Northwind; - namespace Microsoft.EntityFrameworkCore.Query; #nullable disable diff --git a/test/EFCore.Relational.Specification.Tests/Query/NullSemanticsQueryFixtureBase.cs b/test/EFCore.Relational.Specification.Tests/Query/NullSemanticsQueryFixtureBase.cs index 8cc44b96471..e820bc253e1 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/NullSemanticsQueryFixtureBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/NullSemanticsQueryFixtureBase.cs @@ -122,35 +122,32 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con modelBuilder.Entity().Property(e => e.StringC).IsRequired(); modelBuilder.HasDbFunction( - typeof(NullSemanticsQueryFixtureBase).GetMethod(nameof(Cases)), - b => b.HasTranslation(args => new CaseExpression([ - new CaseWhenClause(args[0], args[1]), - new CaseWhenClause(args[2], args[3]), - new CaseWhenClause(args[4], args[5]), - ])) - ); + typeof(NullSemanticsQueryFixtureBase).GetMethod(nameof(Cases))!, + b => b.HasTranslation( + args => new CaseExpression( + [ + new CaseWhenClause(args[0], args[1]), + new CaseWhenClause(args[2], args[3]), + new CaseWhenClause(args[4], args[5]) + ]))); modelBuilder.HasDbFunction( - typeof(NullSemanticsQueryFixtureBase).GetMethod(nameof(BoolSwitch)), - b => b.HasTranslation(args => new CaseExpression( - operand: args[0], - [ - new CaseWhenClause(new SqlConstantExpression(true, typeMapping: BoolTypeMapping.Default), args[1]), - new CaseWhenClause(new SqlConstantExpression(false, typeMapping: BoolTypeMapping.Default), args[2]), - ])) - ); + typeof(NullSemanticsQueryFixtureBase).GetMethod(nameof(BoolSwitch))!, + b => b.HasTranslation( + args => new CaseExpression( + operand: args[0], + [ + new CaseWhenClause(new SqlConstantExpression(true, typeMapping: BoolTypeMapping.Default), args[1]), + new CaseWhenClause(new SqlConstantExpression(false, typeMapping: BoolTypeMapping.Default), args[2]) + ]))); } - public static int? Cases(bool c1, int v1, bool c2, int v2, bool c3, int v3) => - c1 ? v1 : - c2 ? v2 : - c3 ? v3 : - null; + public static int? Cases(bool c1, int v1, bool c2, int v2, bool c3, int v3) + => c1 ? v1 : + c2 ? v2 : + c3 ? v3 : + null; - public static int BoolSwitch(bool x, int whenTrue, int whenFalse) => - x switch - { - true => whenTrue, - false => whenFalse, - }; + public static int BoolSwitch(bool x, int whenTrue, int whenFalse) + => x ? whenTrue : whenFalse; } diff --git a/test/EFCore.Relational.Specification.Tests/Query/NullSemanticsQueryTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/NullSemanticsQueryTestBase.cs index d0b6f8dec32..6ce93abfd78 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/NullSemanticsQueryTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/NullSemanticsQueryTestBase.cs @@ -24,7 +24,7 @@ public abstract class NullSemanticsQueryTestBase(TFixture fixture) : Q [MemberData(nameof(IsAsyncData))] public virtual async Task Rewrite_compare_int_with_int(bool async) { - var bools = new bool[] { false, true }; + var bools = new[] { false, true }; foreach (var neq in bools) { @@ -37,12 +37,38 @@ public virtual async Task Rewrite_compare_int_with_int(bool async) var queryBuilder = (ISetSource ss) => { var data = nullableA - ? ss.Set().Select(e => new { e.Id, A = e.NullableIntA, e.IntB, e.NullableIntB }) - : ss.Set().Select(e => new { e.Id, A = (int?)e.IntA, e.IntB, e.NullableIntB }); + ? ss.Set().Select( + e => new + { + e.Id, + A = e.NullableIntA, + e.IntB, + e.NullableIntB + }) + : ss.Set().Select( + e => new + { + e.Id, + A = (int?)e.IntA, + e.IntB, + e.NullableIntB + }); var query = nullableB - ? data.Select(e => new { e.Id, e.A, B = e.NullableIntB }) - : data.Select(e => new { e.Id, e.A, B = (int?)e.IntB }); + ? data.Select( + e => new + { + e.Id, + e.A, + B = e.NullableIntB + }) + : data.Select( + e => new + { + e.Id, + e.A, + B = (int?)e.IntB + }); var result = neq ? query.Select(e => new { e.Id, X = e.A != e.B }) @@ -65,7 +91,7 @@ public virtual async Task Rewrite_compare_int_with_int(bool async) [MemberData(nameof(IsAsyncData))] public virtual async Task Rewrite_compare_bool_with_bool(bool async) { - var bools = new bool[] { false, true }; + var bools = new[] { false, true }; foreach (var neq in bools) { @@ -82,15 +108,57 @@ public virtual async Task Rewrite_compare_bool_with_bool(bool async) var queryBuilder = (ISetSource ss) => { var data = nullableA - ? ss.Set().Select(e => new { e.Id, A = e.NullableBoolA, e.BoolB, e.NullableBoolB }) - : ss.Set().Select(e => new { e.Id, A = (bool?)e.BoolA, e.BoolB, e.NullableBoolB }); + ? ss.Set().Select( + e => new + { + e.Id, + A = e.NullableBoolA, + e.BoolB, + e.NullableBoolB + }) + : ss.Set().Select( + e => new + { + e.Id, + A = (bool?)e.BoolA, + e.BoolB, + e.NullableBoolB + }); var query = nullableB - ? data.Select(e => new { e.Id, e.A, B = e.NullableBoolB }) - : data.Select(e => new { e.Id, e.A, B = (bool?)e.BoolB }); - - query = negateA ? query.Select(e => new { e.Id, A = !e.A, e.B }) : query; - query = negateB ? query.Select(e => new { e.Id, e.A, B = !e.B }) : query; + ? data.Select( + e => new + { + e.Id, + e.A, + B = e.NullableBoolB + }) + : data.Select( + e => new + { + e.Id, + e.A, + B = (bool?)e.BoolB + }); + + query = negateA + ? query.Select( + e => new + { + e.Id, + A = !e.A, + e.B + }) + : query; + query = negateB + ? query.Select( + e => new + { + e.Id, + e.A, + B = !e.B + }) + : query; var result = neq ? query.Select(e => new { e.Id, X = e.A != e.B }) @@ -495,7 +563,7 @@ public virtual Task Join_uses_csharp_semantics_for_anon_objects(bool async) async, ss => from e1 in ss.Set() join e2 in ss.Set() on - new { NullInt = e1.NullableIntA } equals new { NullInt = e2.NullableIntB } + new { NullInt = e1.NullableIntA } equals new { NullInt = e2.NullableIntB } select new { Id1 = e1.Id, @@ -615,14 +683,17 @@ public virtual Task Where_coalesce(bool async) [ConditionalTheory] [MemberData(nameof(IsAsyncData))] public virtual Task Where_coalesce_shortcircuit(bool async) - => AssertQueryScalar(async, ss => ss.Set().Where(e => (bool?)(e.BoolA | e.BoolB) ?? e.NullableBoolA ?? true) - .Select(e => e.Id)); + => AssertQueryScalar( + async, ss => ss.Set().Where(e => (bool?)(e.BoolA | e.BoolB) ?? e.NullableBoolA ?? true) + .Select(e => e.Id)); [ConditionalTheory] [MemberData(nameof(IsAsyncData))] public virtual Task Where_coalesce_shortcircuit_many(bool async) - => AssertQueryScalar(async, ss => ss.Set().Where(e => e.NullableBoolA ?? (bool?)(e.BoolA | e.BoolB) ?? e.NullableBoolB ?? e.BoolB) - .Select(e => e.Id)); + => AssertQueryScalar( + async, ss => ss.Set() + .Where(e => e.NullableBoolA ?? (bool?)(e.BoolA | e.BoolB) ?? e.NullableBoolB ?? e.BoolB) + .Select(e => e.Id)); [ConditionalTheory] [MemberData(nameof(IsAsyncData))] @@ -1061,7 +1132,8 @@ public virtual Task Where_IndexOf_empty(bool async) => AssertQueryScalar( async, ss => ss.Set().Where(e => e.NullableStringA.IndexOf("") == e.NullableIntA).Select(e => e.Id), - ss => ss.Set().Where(e => 0 == e.NullableIntA || (e.NullableStringA == null && e.NullableIntA == null)).Select(e => e.Id)); + ss => ss.Set().Where(e => 0 == e.NullableIntA || (e.NullableStringA == null && e.NullableIntA == null)) + .Select(e => e.Id)); [ConditionalTheory] [MemberData(nameof(IsAsyncData))] @@ -1543,11 +1615,13 @@ public virtual async Task Null_semantics_contains_non_nullable_item_with_values( await AssertQueryScalar(async, ss => ss.Set().Where(e => !ids2.Contains(e.IntA)).Select(e => e.Id)); var ids3 = new List(); - await AssertQueryScalar(async, ss => ss.Set().Where(e => ids3.Contains(e.IntA)).Select(e => e.Id), assertEmpty: true); + await AssertQueryScalar( + async, ss => ss.Set().Where(e => ids3.Contains(e.IntA)).Select(e => e.Id), assertEmpty: true); await AssertQueryScalar(async, ss => ss.Set().Where(e => !ids3.Contains(e.IntA)).Select(e => e.Id)); var ids4 = new List { null }; - await AssertQueryScalar(async, ss => ss.Set().Where(e => ids4.Contains(e.IntA)).Select(e => e.Id), assertEmpty: true); + await AssertQueryScalar( + async, ss => ss.Set().Where(e => ids4.Contains(e.IntA)).Select(e => e.Id), assertEmpty: true); await AssertQueryScalar(async, ss => ss.Set().Where(e => !ids4.Contains(e.IntA)).Select(e => e.Id)); } @@ -1844,11 +1918,13 @@ public virtual Task CaseWhen_equal_to_second_filter(bool async) => AssertQuery( async, ss => ss.Set() - .Where(x => NullSemanticsQueryFixtureBase.Cases( - x.StringA == "Foo", 3, - x.StringB == "Foo", 2, - x.StringC == "Foo", 3 - ) == 2) + .Where( + x => NullSemanticsQueryFixtureBase.Cases( + x.StringA == "Foo", 3, + x.StringB == "Foo", 2, + x.StringC == "Foo", 3 + ) + == 2) ); [ConditionalTheory] @@ -1857,11 +1933,13 @@ public virtual Task CaseWhen_equal_to_first_or_third_filter(bool async) => AssertQuery( async, ss => ss.Set() - .Where(x => NullSemanticsQueryFixtureBase.Cases( - x.StringA == "Foo", 3, - x.StringB == "Foo", 2, - x.StringC == "Foo", 3 - ) == 3) + .Where( + x => NullSemanticsQueryFixtureBase.Cases( + x.StringA == "Foo", 3, + x.StringB == "Foo", 2, + x.StringC == "Foo", 3 + ) + == 3) ); [ConditionalTheory] @@ -1871,11 +1949,13 @@ public virtual Task CaseWhen_equal_to_second_select(bool async) async, ss => ss.Set() .OrderBy(x => x.Id) - .Select(x => NullSemanticsQueryFixtureBase.Cases( - x.StringA == "Foo", 3, - x.StringB == "Foo", 2, - x.StringC == "Foo", 3 - ) == 2), + .Select( + x => NullSemanticsQueryFixtureBase.Cases( + x.StringA == "Foo", 3, + x.StringB == "Foo", 2, + x.StringC == "Foo", 3 + ) + == 2), assertOrder: true ); @@ -1886,13 +1966,14 @@ public virtual Task CaseWhen_equal_to_first_or_third_select(bool async) async, ss => ss.Set() .OrderBy(x => x.Id) - .Select(x => NullSemanticsQueryFixtureBase.Cases( - x.StringA == "Foo", 3, - x.StringB == "Foo", 2, - x.StringC == "Foo", 3 - ) == 3), - assertOrder: true - ); + .Select( + x => NullSemanticsQueryFixtureBase.Cases( + x.StringA == "Foo", 3, + x.StringB == "Foo", 2, + x.StringC == "Foo", 3 + ) + == 3), + assertOrder: true); [ConditionalTheory] [MemberData(nameof(IsAsyncData))] @@ -1901,11 +1982,10 @@ public virtual Task CaseOpWhen_projection(bool async) async, ss => ss.Set() .OrderBy(x => x.Id) - .Select(x => NullSemanticsQueryFixtureBase.BoolSwitch( - x.StringA == "Foo", 3, 2 - )), - assertOrder: true - ); + .Select( + x => NullSemanticsQueryFixtureBase.BoolSwitch( + x.StringA == "Foo", 3, 2)), + assertOrder: true); [ConditionalTheory] [MemberData(nameof(IsAsyncData))] @@ -1913,9 +1993,11 @@ public virtual Task CaseOpWhen_predicate(bool async) => AssertQuery( async, ss => ss.Set() - .Where(x => NullSemanticsQueryFixtureBase.BoolSwitch( - x.StringA == "Foo", 3, 2 - ) == 2), + .Where( + x => NullSemanticsQueryFixtureBase.BoolSwitch( + x.StringA == "Foo", 3, 2 + ) + == 2), assertOrder: true ); diff --git a/test/EFCore.Relational.Specification.Tests/Query/OperatorsProceduralQueryTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/OperatorsProceduralQueryTestBase.cs index f9529d0c361..f44b4ec2392 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/OperatorsProceduralQueryTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/OperatorsProceduralQueryTestBase.cs @@ -1280,7 +1280,7 @@ private class RootEntityExpressionInfo(Expression expression) { public Expression Expression { get; } = expression; - public bool Used { get; set; } = false; + public bool Used { get; set; } } private class ActualSetSource(DbContext context) : ISetSource diff --git a/test/EFCore.Relational.Specification.Tests/Query/OptionalDependentQueryFixtureBase.cs b/test/EFCore.Relational.Specification.Tests/Query/OptionalDependentQueryFixtureBase.cs index c4366a6ce5e..2185c3ce8f4 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/OptionalDependentQueryFixtureBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/OptionalDependentQueryFixtureBase.cs @@ -93,7 +93,6 @@ public static void AssertOptionalDependentJsonSomeRequired( Assert.Equal(expected.OpProp2, actual.OpProp2); Assert.Equal(expected.ReqProp, actual.ReqProp); - if (expected.OpNav1 is not null || actual.OpNav1 is not null) { AssertOptionalDependentNestedJsonAllOptional(expected.OpNav1, actual.OpNav1); diff --git a/test/EFCore.Relational.Specification.Tests/Query/OwnedEntityQueryRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/OwnedEntityQueryRelationalTestBase.cs index 12f1b63c13d..bfee9bfd966 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/OwnedEntityQueryRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/OwnedEntityQueryRelationalTestBase.cs @@ -28,7 +28,8 @@ public virtual async Task An_optional_dependent_without_any_columns_and_nested_d message); } - private class Context23198(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context23198(DbContextOptions options) : DbContext(options) { protected override void OnModelCreating(ModelBuilder modelBuilder) => modelBuilder.Entity().OwnsOne( @@ -81,7 +82,8 @@ public virtual async Task Multiple_owned_reference_mapped_to_own_table_containin Assert.Equal(2, root3.ModdleA.Leaves.Count); } - private class Context24777(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context24777(DbContextOptions options) : DbContext(options) { public DbSet Roots { get; set; } @@ -155,7 +157,7 @@ public class ModdleA { public int Id { get; init; } public int RootId { get; init; } - public List Leaves { get; init; } + public List Leaves { get; } } public class MiddleB @@ -422,7 +424,8 @@ public virtual async Task Owned_entity_with_all_null_properties_property_access_ }); } - private class Context28247(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context28247(DbContextOptions options) : DbContext(options) { public DbSet RotRutCases { get; set; } @@ -505,7 +508,8 @@ join magus in context.Magi.Where(x => x.Name.Contains("Bayaz")) on monarch.Ruler Assert.Equal("The Divider", result[0].magus.ToolUsed.Name); } - private class Context30358(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context30358(DbContextOptions options) : DbContext(options) { public DbSet Monarchs { get; set; } public DbSet Magi { get; set; } @@ -518,15 +522,13 @@ public Task SeedAsync() Add( new Monarch { - Name = "His August Majesty Guslav the Fifth", - RulerOf = "The Union", + Name = "His August Majesty Guslav the Fifth", RulerOf = "The Union", }); Add( new Monarch { - Name = "Emperor Uthman-ul-Dosht", - RulerOf = "The Gurkish Empire", + Name = "Emperor Uthman-ul-Dosht", RulerOf = "The Gurkish Empire", }); Add( @@ -581,7 +583,8 @@ public async Task Can_have_required_owned_type_on_derived_type() context.Set().ToList(); } - private class Context31107(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context31107(DbContextOptions options) : DbContext(options) { protected override void OnModelCreating(ModelBuilder modelBuilder) { diff --git a/test/EFCore.Relational.Specification.Tests/Query/OwnedQueryRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/OwnedQueryRelationalTestBase.cs index b6ed890e077..ecbe47b3c9f 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/OwnedQueryRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/OwnedQueryRelationalTestBase.cs @@ -1,8 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.EntityFrameworkCore.Diagnostics.Internal; - namespace Microsoft.EntityFrameworkCore.Query; #nullable disable diff --git a/test/EFCore.Relational.Specification.Tests/Query/PrecompiledQueryRelationalFixture.cs b/test/EFCore.Relational.Specification.Tests/Query/PrecompiledQueryRelationalFixture.cs index 74c4c745a9f..a557ec7a11d 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/PrecompiledQueryRelationalFixture.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/PrecompiledQueryRelationalFixture.cs @@ -7,6 +7,7 @@ using Post = Microsoft.EntityFrameworkCore.Query.PrecompiledQueryRelationalTestBase.Post; using JsonRoot = Microsoft.EntityFrameworkCore.Query.PrecompiledQueryRelationalTestBase.JsonRoot; using JsonBranch = Microsoft.EntityFrameworkCore.Query.PrecompiledQueryRelationalTestBase.JsonBranch; + namespace Microsoft.EntityFrameworkCore.Query; public abstract class PrecompiledQueryRelationalFixture @@ -30,24 +31,65 @@ protected override IServiceCollection AddServices(IServiceCollection serviceColl protected override async Task SeedAsync(PrecompiledQueryRelationalTestBase.PrecompiledQueryContext context) { - var blog1 = new Blog { Id = 8, Name = "Blog1", Json = [] }; + var blog1 = new Blog + { + Id = 8, + Name = "Blog1", + Json = [] + }; var blog2 = new Blog { Id = 9, Name = "Blog2", Json = [ - new JsonRoot { Number = 1, Text = "One", Inner = new JsonBranch { Date = new DateTime(2001, 1, 1) } }, - new JsonRoot { Number = 2, Text = "Two", Inner = new JsonBranch { Date = new DateTime(2002, 2, 2) } }, - ]}; + new JsonRoot + { + Number = 1, + Text = "One", + Inner = new JsonBranch { Date = new DateTime(2001, 1, 1) } + }, + new JsonRoot + { + Number = 2, + Text = "Two", + Inner = new JsonBranch { Date = new DateTime(2002, 2, 2) } + }, + ] + }; context.Blogs.AddRange(blog1, blog2); - var post11 = new Post { Id = 11, Title = "Post11", Blog = blog1 }; - var post12 = new Post { Id = 12, Title = "Post12", Blog = blog1 }; - var post21 = new Post { Id = 21, Title = "Post21", Blog = blog2 }; - var post22 = new Post { Id = 22, Title = "Post22", Blog = blog2 }; - var post23 = new Post { Id = 23, Title = "Post23", Blog = blog2 }; + var post11 = new Post + { + Id = 11, + Title = "Post11", + Blog = blog1 + }; + var post12 = new Post + { + Id = 12, + Title = "Post12", + Blog = blog1 + }; + var post21 = new Post + { + Id = 21, + Title = "Post21", + Blog = blog2 + }; + var post22 = new Post + { + Id = 22, + Title = "Post22", + Blog = blog2 + }; + var post23 = new Post + { + Id = 23, + Title = "Post23", + Blog = blog2 + }; context.Posts.AddRange(post11, post12, post21, post22, post23); await context.SaveChangesAsync(); diff --git a/test/EFCore.Relational.Specification.Tests/Query/PrecompiledQueryRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/PrecompiledQueryRelationalTestBase.cs index 6a7642767f6..939018fc4de 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/PrecompiledQueryRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/PrecompiledQueryRelationalTestBase.cs @@ -12,11 +12,11 @@ namespace Microsoft.EntityFrameworkCore.Query; // ReSharper disable InconsistentNaming - /// /// General tests for precompiled queries. /// See also for tests specifically related to SQL pregeneration. /// +[Collection("PrecompiledQuery")] public class PrecompiledQueryRelationalTestBase { public PrecompiledQueryRelationalTestBase(PrecompiledQueryRelationalFixture fixture, ITestOutputHelper testOutputHelper) @@ -32,7 +32,8 @@ public PrecompiledQueryRelationalTestBase(PrecompiledQueryRelationalFixture fixt [ConditionalFact] public virtual Task BinaryExpression() - => Test(""" + => Test( + """ var id = 3; var blogs = await context.Blogs.Where(b => b.Id > id).ToListAsync(); @@ -60,14 +61,16 @@ public virtual Task BinaryExpression() [ConditionalFact] public virtual Task Conditional_no_evaluatable() - => Test(""" + => Test( + """ var id = 3; var blogs = await context.Blogs.Select(b => b.Id == 2 ? "yes" : "no").ToListAsync(); """); [ConditionalFact] public virtual Task Conditional_contains_captured_variable() - => Test(""" + => Test( + """ var yes = "yes"; var blogs = await context.Blogs.Select(b => b.Id == 2 ? yes : "no").ToListAsync(); """); @@ -87,14 +90,14 @@ public virtual Task Invoke_no_evaluatability_is_not_supported() """, errorAsserter: errors => Assert.IsType(errors.Single().Exception)); - [ConditionalFact] - public virtual Task ListInit_no_evaluatability() - => Test("_ = await context.Blogs.Select(b => new List { b.Id, b.Id + 1 }).ToListAsync();"); + [ConditionalFact] + public virtual Task ListInit_no_evaluatability() + => Test("_ = await context.Blogs.Select(b => new List { b.Id, b.Id + 1 }).ToListAsync();"); - [ConditionalFact] - public virtual Task ListInit_with_evaluatable_with_captured_variable() - => Test( - """ + [ConditionalFact] + public virtual Task ListInit_with_evaluatable_with_captured_variable() + => Test( + """ var i = 1; _ = await context.Blogs.Select(b => new List { b.Id, i }).ToListAsync(); """); @@ -102,25 +105,27 @@ public virtual Task ListInit_with_evaluatable_with_captured_variable() [ConditionalFact] public virtual Task ListInit_with_evaluatable_without_captured_variable() => Test( - """ + """ var i = 1; _ = await context.Blogs.Select(b => new List { b.Id, 8 }).ToListAsync(); """); [ConditionalFact] public virtual Task ListInit_fully_evaluatable() - => Test(""" + => Test( + """ var blog = await context.Blogs.Where(b => new List { 7, 8 }.Contains(b.Id)).SingleAsync(); Assert.Equal("Blog1", blog.Name); """); - [ConditionalFact] - public virtual Task MethodCallExpression_no_evaluatability() - => Test("_ = await context.Blogs.Where(b => b.Name.StartsWith(b.Name)).ToListAsync();"); + [ConditionalFact] + public virtual Task MethodCallExpression_no_evaluatability() + => Test("_ = await context.Blogs.Where(b => b.Name.StartsWith(b.Name)).ToListAsync();"); [ConditionalFact] public virtual Task MethodCallExpression_with_evaluatable_with_captured_variable() - => Test(""" + => Test( + """ var pattern = "foo"; _ = await context.Blogs.Where(b => b.Name.StartsWith(pattern)).ToListAsync(); """); @@ -201,7 +206,8 @@ public virtual Task Unary() [ConditionalFact] public virtual Task Terminating_AsEnumerable() - => Test(""" + => Test( + """ var blogs = context.Blogs.AsEnumerable().ToList(); Assert.Collection( blogs.OrderBy(b => b.Id), @@ -211,7 +217,8 @@ public virtual Task Terminating_AsEnumerable() [ConditionalFact] public virtual Task Terminating_AsAsyncEnumerable_on_DbSet() - => Test(""" + => Test( + """ var sum = 0; await foreach (var blog in context.Blogs.AsAsyncEnumerable()) { @@ -222,7 +229,8 @@ public virtual Task Terminating_AsAsyncEnumerable_on_DbSet() [ConditionalFact] public virtual Task Terminating_AsAsyncEnumerable_on_IQueryable() - => Test(""" + => Test( + """ var sum = 0; await foreach (var blog in context.Blogs.Where(b => b.Id > 8).AsAsyncEnumerable()) { @@ -1083,7 +1091,8 @@ public virtual Task Project_anonymous_object() [ConditionalFact] public virtual Task Two_captured_variables_in_same_lambda() - => Test(""" + => Test( + """ var yes = "yes"; var no = "no"; var blogs = await context.Blogs.Select(b => b.Id == 3 ? yes : no).ToListAsync(); @@ -1091,8 +1100,9 @@ public virtual Task Two_captured_variables_in_same_lambda() [ConditionalFact] public virtual Task Two_captured_variables_in_different_lambdas() - => Test(""" -var starts = "blog"; + => Test( + """ +var starts = "Blog"; var ends = "2"; var blog = await context.Blogs.Where(b => b.Name.StartsWith(starts)).Where(b => b.Name.EndsWith(ends)).SingleAsync(); Assert.Equal(9, blog.Id); @@ -1100,14 +1110,16 @@ public virtual Task Two_captured_variables_in_different_lambdas() [ConditionalFact] public virtual Task Same_captured_variable_twice_in_same_lambda() - => Test(""" + => Test( + """ var foo = "X"; var blogs = await context.Blogs.Where(b => b.Name.StartsWith(foo) && b.Name.EndsWith(foo)).ToListAsync(); """); [ConditionalFact] public virtual Task Same_captured_variable_twice_in_different_lambdas() - => Test(""" + => Test( + """ var foo = "X"; var blogs = await context.Blogs.Where(b => b.Name.StartsWith(foo)).Where(b => b.Name.EndsWith(foo)).ToListAsync(); """); @@ -1126,7 +1138,8 @@ public virtual Task Final_GroupBy() [ConditionalFact] public virtual Task Multiple_queries_with_captured_variables() - => Test(""" + => Test( + """ var id1 = 8; var id2 = 9; var blogs = await context.Blogs.Where(b => b.Id == id1 || b.Id == id2).ToListAsync(); @@ -1140,11 +1153,13 @@ public virtual Task Multiple_queries_with_captured_variables() [ConditionalFact] public virtual Task Unsafe_accessor_gets_generated_once_for_multiple_queries() - => Test(""" + => Test( + """ var blogs1 = await context.Blogs.ToListAsync(); var blogs2 = await context.Blogs.ToListAsync(); """, - interceptorCodeAsserter: code => Assert.Equal(2, code.Split("private static extern ref int UnsafeAccessor_Microsoft_EntityFrameworkCore_Query_Blog_Id_Set").Length)); + interceptorCodeAsserter: code => Assert.Equal( + 2, code.Split("private static extern ref int UnsafeAccessor_Microsoft_EntityFrameworkCore_Query_Blog_Id_Set").Length)); public class PrecompiledQueryContext(DbContextOptions options) : DbContext(options) { @@ -1181,7 +1196,8 @@ protected virtual Task Test( """ await using var context = new PrecompiledQueryContext(dbContextOptions); -""" + sourceCode, +""" + + sourceCode, Fixture.ServiceProvider.GetRequiredService(), typeof(PrecompiledQueryContext), interceptorCodeAsserter, @@ -1225,6 +1241,7 @@ public Blog(int id, string name) [DatabaseGenerated(DatabaseGeneratedOption.None)] public int Id { get; set; } + public string? Name { get; set; } public List Posts { get; set; } = new(); public List Json { get; set; } = new(); diff --git a/test/EFCore.Relational.Specification.Tests/Query/PrecompiledSqlPregenerationQueryRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/PrecompiledSqlPregenerationQueryRelationalTestBase.cs index 77ffb7c372e..72f66bc2866 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/PrecompiledSqlPregenerationQueryRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/PrecompiledSqlPregenerationQueryRelationalTestBase.cs @@ -13,9 +13,12 @@ namespace Microsoft.EntityFrameworkCore.Query; /// See for general precompiled query tests not related to /// SQL pregeneration. /// +[Collection("PrecompiledQuery")] public class PrecompiledSqlPregenerationQueryRelationalTestBase { - public PrecompiledSqlPregenerationQueryRelationalTestBase(PrecompiledSqlPregenerationQueryRelationalFixture fixture, ITestOutputHelper testOutputHelper) + public PrecompiledSqlPregenerationQueryRelationalTestBase( + PrecompiledSqlPregenerationQueryRelationalFixture fixture, + ITestOutputHelper testOutputHelper) { Fixture = fixture; TestOutputHelper = testOutputHelper; @@ -301,6 +304,7 @@ public Blog(int id, string name) [DatabaseGenerated(DatabaseGeneratedOption.None)] public int Id { get; set; } + public string? Name { get; set; } public List Posts { get; set; } = new(); diff --git a/test/EFCore.Relational.Specification.Tests/Query/SqlExecutorTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/SqlExecutorTestBase.cs index 89b17be23d5..863c60d3147 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/SqlExecutorTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/SqlExecutorTestBase.cs @@ -324,9 +324,7 @@ protected NorthwindContext CreateContext() public class SqlExecutorModelCustomizer : NoopModelCustomizer { public override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder) - { - configurationBuilder.DefaultTypeMapping().HasConversion(); - } + => configurationBuilder.DefaultTypeMapping().HasConversion(); private sealed class CityToStringConverter() : ValueConverter(value => value.Name, value => new City { Name = value }); } diff --git a/test/EFCore.Relational.Specification.Tests/Query/SqlQueryTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/SqlQueryTestBase.cs index 9af9bb1a2df..ef897e5014e 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/SqlQueryTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/SqlQueryTestBase.cs @@ -19,9 +19,7 @@ public abstract class SqlQueryTestBase : QueryTestBase protected SqlQueryTestBase(TFixture fixture) : base(fixture) - { - Fixture.TestSqlLoggerFactory.Clear(); - } + => Fixture.TestSqlLoggerFactory.Clear(); [ConditionalTheory] [MemberData(nameof(IsAsyncData))] @@ -818,7 +816,8 @@ public virtual Task SqlQueryRaw_composed_with_predicate(bool async) _ => Fixture.CreateContext().Database.SqlQueryRaw( NormalizeDelimitersInRawString("SELECT * FROM [Customers]")) .Where(c => c.ContactName.Substring(0, 1) == c.CompanyName.Substring(0, 1)), - ss => ss.Set().Where(c => c.ContactName.Substring(0, 1) == c.CompanyName.Substring(0, 1)).Select(e => UnmappedCustomer.FromCustomer(e)), + ss => ss.Set().Where(c => c.ContactName.Substring(0, 1) == c.CompanyName.Substring(0, 1)) + .Select(e => UnmappedCustomer.FromCustomer(e)), elementSorter: e => e.CustomerID, elementAsserter: AssertUnmappedCustomers); diff --git a/test/EFCore.Relational.Specification.Tests/Query/UdfDbFunctionTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/UdfDbFunctionTestBase.cs index e7a8bd7b4a1..5b9204a952f 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/UdfDbFunctionTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/UdfDbFunctionTestBase.cs @@ -388,7 +388,7 @@ protected override async Task SeedAsync(DbContext context) { Name = "Order11", OrderDate = new DateTime(2000, 1, 20), - Items = [new() { Quantity = 5, Product = product1 }, new() { Quantity = 15, Product = product3 }] + Items = [new LineItem { Quantity = 5, Product = product1 }, new LineItem { Quantity = 15, Product = product3 }] }; var order12 = new Order @@ -397,9 +397,9 @@ protected override async Task SeedAsync(DbContext context) OrderDate = new DateTime(2000, 2, 21), Items = [ - new() { Quantity = 1, Product = product1 }, - new() { Quantity = 6, Product = product2 }, - new() { Quantity = 200, Product = product3 } + new LineItem { Quantity = 1, Product = product1 }, + new LineItem { Quantity = 6, Product = product2 }, + new LineItem { Quantity = 200, Product = product3 } ] }; @@ -407,7 +407,7 @@ protected override async Task SeedAsync(DbContext context) { Name = "Order13", OrderDate = new DateTime(2001, 3, 20), - Items = [new() { Quantity = 50, Product = product4 }] + Items = [new LineItem { Quantity = 50, Product = product4 }] }; var order21 = new Order @@ -416,9 +416,9 @@ protected override async Task SeedAsync(DbContext context) OrderDate = new DateTime(2000, 4, 21), Items = [ - new() { Quantity = 1, Product = product1 }, - new() { Quantity = 34, Product = product4 }, - new() { Quantity = 100, Product = product5 } + new LineItem { Quantity = 1, Product = product1 }, + new LineItem { Quantity = 34, Product = product4 }, + new LineItem { Quantity = 100, Product = product5 } ] }; @@ -426,14 +426,14 @@ protected override async Task SeedAsync(DbContext context) { Name = "Order22", OrderDate = new DateTime(2000, 5, 20), - Items = [new() { Quantity = 34, Product = product3 }, new() { Quantity = 100, Product = product4 }] + Items = [new LineItem { Quantity = 34, Product = product3 }, new LineItem { Quantity = 100, Product = product4 }] }; var order31 = new Order { Name = "Order31", OrderDate = new DateTime(2001, 6, 21), - Items = [new() { Quantity = 5, Product = product5 }] + Items = [new LineItem { Quantity = 5, Product = product5 }] }; var address11 = new Address @@ -1153,8 +1153,7 @@ public virtual void Scalar_Function_Anonymous_Type_Select_Nested_Instance() where c.Id == customerId select new { - c.LastName, - OrderCount = context.StarValueInstance(starCount, context.CustomerOrderCountInstance(customerId)) + c.LastName, OrderCount = context.StarValueInstance(starCount, context.CustomerOrderCountInstance(customerId)) }).Single(); Assert.Equal("Three", cust.LastName); @@ -1588,8 +1587,7 @@ public virtual void QF_Select_Direct_In_Anonymous() () => (from c in context.Customers select new { - c.Id, - Prods = context.GetTopTwoSellingProducts().ToList(), + c.Id, Prods = context.GetTopTwoSellingProducts().ToList(), }).ToList()).Message; Assert.Equal(RelationalStrings.InsufficientInformationToIdentifyElementOfCollectionJoin, message); @@ -1604,8 +1602,7 @@ public virtual void QF_Select_Direct_In_Anonymous_distinct() var query = (from c in context.Customers select new { - c.Id, - Prods = context.GetTopTwoSellingProducts().Distinct().ToList(), + c.Id, Prods = context.GetTopTwoSellingProducts().Distinct().ToList(), }).ToList(); } } @@ -1732,8 +1729,7 @@ public virtual void QF_Select_NonCorrelated_Subquery_In_Anonymous() () => (from c in context.Customers select new { - c.Id, - Prods = context.GetTopTwoSellingProducts().Select(p => p.ProductId).ToList(), + c.Id, Prods = context.GetTopTwoSellingProducts().Select(p => p.ProductId).ToList(), }).ToList()).Message; Assert.Equal(RelationalStrings.InsufficientInformationToIdentifyElementOfCollectionJoin, message); diff --git a/test/EFCore.Relational.Specification.Tests/RelationalComplianceTestBase.cs b/test/EFCore.Relational.Specification.Tests/RelationalComplianceTestBase.cs index cedb1c82835..641018ea791 100644 --- a/test/EFCore.Relational.Specification.Tests/RelationalComplianceTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/RelationalComplianceTestBase.cs @@ -25,6 +25,7 @@ public virtual void All_query_test_fixtures_must_implement_ITestSqlLoggerFactory Assert.False( queryFixturesWithoutTestSqlLogger.Count > 0, - "\r\n-- Missing ITestSqlLoggerFactory implementation for relational QueryFixtures --\r\n" + string.Join(Environment.NewLine, queryFixturesWithoutTestSqlLogger)); + "\r\n-- Missing ITestSqlLoggerFactory implementation for relational QueryFixtures --\r\n" + + string.Join(Environment.NewLine, queryFixturesWithoutTestSqlLogger)); } } diff --git a/test/EFCore.Relational.Specification.Tests/Scaffolding/CompiledModelRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Scaffolding/CompiledModelRelationalTestBase.cs index b2c8bcbee36..789bf20c5e1 100644 --- a/test/EFCore.Relational.Specification.Tests/Scaffolding/CompiledModelRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Scaffolding/CompiledModelRelationalTestBase.cs @@ -32,7 +32,7 @@ public virtual Task BigModel_with_JSON_columns() var dependent = c.Set>>().Include(p => p.Dependent).Single().Dependent!; Assert.Equal("one", ((DependentDerived)dependent).GetData()); }, - options: new CompiledModelCodeGenerationOptions { UseNullableReferenceTypes = true }); + options: new CompiledModelCodeGenerationOptions { UseNullableReferenceTypes = true, ForNativeAot = true }); protected override void BuildBigModel(ModelBuilder modelBuilder, bool jsonColumns) { @@ -430,6 +430,29 @@ protected override void BuildComplexTypesModel(ModelBuilder modelBuilder) }); } + [ConditionalFact] + public override Task ComplexTypes() + => Test( + BuildComplexTypesModel, + AssertComplexTypes, + c => + { + // Sprocs not supported with complex types + //c.Set>>().Add( + // new PrincipalDerived> + // { + // Id = 1, + // AlternateId = new Guid(), + // Dependent = new DependentBase(1), + // Owned = new OwnedType(c) { Principal = new PrincipalBase() } + // }); + + //c.SaveChanges(); + + return Task.CompletedTask; + }, + options: new CompiledModelCodeGenerationOptions { UseNullableReferenceTypes = true, ForNativeAot = true }); + protected override void AssertComplexTypes(IModel model) { base.AssertComplexTypes(model); @@ -500,7 +523,7 @@ public virtual Task Tpc_Sprocs() => Test( BuildTpcSprocsModel, AssertTpcSprocs, - options: new CompiledModelCodeGenerationOptions { UseNullableReferenceTypes = true }); + options: new CompiledModelCodeGenerationOptions { UseNullableReferenceTypes = true, ForNativeAot = true }); protected virtual void BuildTpcSprocsModel(ModelBuilder modelBuilder) { @@ -1267,7 +1290,8 @@ public virtual Task Dynamic_schema() }, additionalSourceFiles: [ - new("DbContextModelCustomizer.cs", + new ScaffoldedFile( + "DbContextModelCustomizer.cs", """ using Microsoft.EntityFrameworkCore.Metadata; diff --git a/test/EFCore.Relational.Specification.Tests/TestModels/EntitySplitting/EntitySplittingData.cs b/test/EFCore.Relational.Specification.Tests/TestModels/EntitySplitting/EntitySplittingData.cs index c92256cf0a3..8028248a056 100644 --- a/test/EFCore.Relational.Specification.Tests/TestModels/EntitySplitting/EntitySplittingData.cs +++ b/test/EFCore.Relational.Specification.Tests/TestModels/EntitySplitting/EntitySplittingData.cs @@ -68,7 +68,7 @@ public IQueryable Set() private static EntityOne[] CreateEntityOnes() => [ - new() + new EntityOne { Id = 1, IntValue1 = 11, @@ -80,7 +80,7 @@ private static EntityOne[] CreateEntityOnes() StringValue3 = "V13", StringValue4 = "V14" }, - new() + new EntityOne { Id = 2, IntValue1 = 21, @@ -92,7 +92,7 @@ private static EntityOne[] CreateEntityOnes() StringValue3 = "V23", StringValue4 = "V24" }, - new() + new EntityOne { Id = 3, IntValue1 = 31, @@ -104,7 +104,7 @@ private static EntityOne[] CreateEntityOnes() StringValue3 = "V33", StringValue4 = "V34" }, - new() + new EntityOne { Id = 4, IntValue1 = 41, @@ -116,7 +116,7 @@ private static EntityOne[] CreateEntityOnes() StringValue3 = "V43", StringValue4 = "V44" }, - new() + new EntityOne { Id = 5, IntValue1 = 51, @@ -133,27 +133,27 @@ private static EntityOne[] CreateEntityOnes() private static EntityTwo[] CreateEntityTwos() => [ - new() { Id = 1, Name = "Two1" }, - new() { Id = 2, Name = "Two2" }, - new() { Id = 3, Name = "Two3" }, - new() { Id = 4, Name = "Two4" }, - new() { Id = 5, Name = "Two5" } + new EntityTwo { Id = 1, Name = "Two1" }, + new EntityTwo { Id = 2, Name = "Two2" }, + new EntityTwo { Id = 3, Name = "Two3" }, + new EntityTwo { Id = 4, Name = "Two4" }, + new EntityTwo { Id = 5, Name = "Two5" } ]; private static EntityThree[] CreateEntityThrees() => [ - new() { Id = 1, Name = "Three1" }, - new() { Id = 2, Name = "Three2" }, - new() { Id = 3, Name = "Three3" }, - new() { Id = 4, Name = "Three4" }, - new() { Id = 5, Name = "Three5" } + new EntityThree { Id = 1, Name = "Three1" }, + new EntityThree { Id = 2, Name = "Three2" }, + new EntityThree { Id = 3, Name = "Three3" }, + new EntityThree { Id = 4, Name = "Three4" }, + new EntityThree { Id = 5, Name = "Three5" } ]; private static BaseEntity[] CreateHierarchyEntities() => [ - new() { Id = 1, BaseValue = 1 }, + new BaseEntity { Id = 1, BaseValue = 1 }, new MiddleEntity { Id = 2, @@ -276,15 +276,25 @@ private void WireUp() } } - public Task Seed(EntitySplittingContext context) + public void AddSeedData(EntitySplittingContext context) { + try + { + if (context.Set().AsNoTracking().Any()) + { + return; + } + } + catch + { + return; + } + // Seed data cannot contain any store generated value, // or recreate instances when calling AddRange context.AddRange(_entityOnes); context.AddRange(_entityTwos); context.AddRange(_entityThrees); context.AddRange(_baseEntities); - - return context.SaveChangesAsync(); } } diff --git a/test/EFCore.Relational.Specification.Tests/TestModels/Operators/OperatorEntityBase.cs b/test/EFCore.Relational.Specification.Tests/TestModels/Operators/OperatorEntityBase.cs index 7355e11a290..74f0240cf6f 100644 --- a/test/EFCore.Relational.Specification.Tests/TestModels/Operators/OperatorEntityBase.cs +++ b/test/EFCore.Relational.Specification.Tests/TestModels/Operators/OperatorEntityBase.cs @@ -3,8 +3,6 @@ namespace Microsoft.EntityFrameworkCore.TestModels.Operators; -#nullable disable - public abstract class OperatorEntityBase { public int Id { get; set; } diff --git a/test/EFCore.Relational.Specification.Tests/TestModels/Operators/OperatorEntityBool.cs b/test/EFCore.Relational.Specification.Tests/TestModels/Operators/OperatorEntityBool.cs index a3b95c6fea6..09fb32b1ddf 100644 --- a/test/EFCore.Relational.Specification.Tests/TestModels/Operators/OperatorEntityBool.cs +++ b/test/EFCore.Relational.Specification.Tests/TestModels/Operators/OperatorEntityBool.cs @@ -3,8 +3,6 @@ namespace Microsoft.EntityFrameworkCore.TestModels.Operators; -#nullable disable - public class OperatorEntityBool : OperatorEntityBase { public bool Value { get; set; } diff --git a/test/EFCore.Relational.Specification.Tests/TestModels/Operators/OperatorEntityInt.cs b/test/EFCore.Relational.Specification.Tests/TestModels/Operators/OperatorEntityInt.cs index 1be70a9c8af..f55285e8835 100644 --- a/test/EFCore.Relational.Specification.Tests/TestModels/Operators/OperatorEntityInt.cs +++ b/test/EFCore.Relational.Specification.Tests/TestModels/Operators/OperatorEntityInt.cs @@ -3,8 +3,6 @@ namespace Microsoft.EntityFrameworkCore.TestModels.Operators; -#nullable disable - public class OperatorEntityInt : OperatorEntityBase { public int Value { get; set; } diff --git a/test/EFCore.Relational.Specification.Tests/TestModels/Operators/OperatorEntityLong.cs b/test/EFCore.Relational.Specification.Tests/TestModels/Operators/OperatorEntityLong.cs index eb7ab473efc..f8cc75b9a6a 100644 --- a/test/EFCore.Relational.Specification.Tests/TestModels/Operators/OperatorEntityLong.cs +++ b/test/EFCore.Relational.Specification.Tests/TestModels/Operators/OperatorEntityLong.cs @@ -3,8 +3,6 @@ namespace Microsoft.EntityFrameworkCore.TestModels.Operators; -#nullable disable - public class OperatorEntityLong : OperatorEntityBase { public long Value { get; set; } diff --git a/test/EFCore.Relational.Specification.Tests/TestModels/Operators/OperatorEntityNullableBool.cs b/test/EFCore.Relational.Specification.Tests/TestModels/Operators/OperatorEntityNullableBool.cs index f9e861b0694..34de2843f8a 100644 --- a/test/EFCore.Relational.Specification.Tests/TestModels/Operators/OperatorEntityNullableBool.cs +++ b/test/EFCore.Relational.Specification.Tests/TestModels/Operators/OperatorEntityNullableBool.cs @@ -3,8 +3,6 @@ namespace Microsoft.EntityFrameworkCore.TestModels.Operators; -#nullable disable - public class OperatorEntityNullableBool : OperatorEntityBase { public bool? Value { get; set; } diff --git a/test/EFCore.Relational.Specification.Tests/TestModels/Operators/OperatorEntityNullableInt.cs b/test/EFCore.Relational.Specification.Tests/TestModels/Operators/OperatorEntityNullableInt.cs index 0f873721670..2496af6310c 100644 --- a/test/EFCore.Relational.Specification.Tests/TestModels/Operators/OperatorEntityNullableInt.cs +++ b/test/EFCore.Relational.Specification.Tests/TestModels/Operators/OperatorEntityNullableInt.cs @@ -3,8 +3,6 @@ namespace Microsoft.EntityFrameworkCore.TestModels.Operators; -#nullable disable - public class OperatorEntityNullableInt : OperatorEntityBase { public int? Value { get; set; } diff --git a/test/EFCore.Relational.Specification.Tests/TestModels/Operators/OperatorsData.cs b/test/EFCore.Relational.Specification.Tests/TestModels/Operators/OperatorsData.cs index 5a898e2442d..d74349f97b2 100644 --- a/test/EFCore.Relational.Specification.Tests/TestModels/Operators/OperatorsData.cs +++ b/test/EFCore.Relational.Specification.Tests/TestModels/Operators/OperatorsData.cs @@ -56,7 +56,7 @@ public class OperatorsData : ISetSource () => new DateTimeOffset(new DateTime(2000, 1, 1, 9, 0, 0), new TimeSpan(13, 0, 0)) ]; - private readonly List>> _nullableDateTimeOffsetValues = + private readonly List>> _nullableDateTimeOffsetValues = [ () => null, () => new DateTimeOffset(new DateTime(2000, 1, 1, 10, 0, 0), new TimeSpan(-8, 0, 0)), @@ -168,6 +168,7 @@ public IReadOnlyList CreateDateTimeOffsets() .Select((x, i) => new OperatorEntityDateTimeOffset { Id = i + 1, Value = _dateTimeOffsetValues[i].Compile()() }).ToList(); public IReadOnlyList CreateNullableDateTimeOffsets() - => _nullableDateTimeOffsetValues.Select((x, i) => new OperatorEntityNullableDateTimeOffset { Id = i + 1, Value = _nullableDateTimeOffsetValues[i].Compile()() }) + => _nullableDateTimeOffsetValues.Select( + (x, i) => new OperatorEntityNullableDateTimeOffset { Id = i + 1, Value = _nullableDateTimeOffsetValues[i].Compile()() }) .ToList(); } diff --git a/test/EFCore.Relational.Specification.Tests/TestModels/OptionalDependent/OptionalDependentData.cs b/test/EFCore.Relational.Specification.Tests/TestModels/OptionalDependent/OptionalDependentData.cs index b3c20d391fb..dbb0f3fc553 100644 --- a/test/EFCore.Relational.Specification.Tests/TestModels/OptionalDependent/OptionalDependentData.cs +++ b/test/EFCore.Relational.Specification.Tests/TestModels/OptionalDependent/OptionalDependentData.cs @@ -21,7 +21,13 @@ public static IReadOnlyList CreateEntitiesAl OpProp1 = "1", OpProp2 = 1, OpNav1 = new OptionalDependentNestedJsonAllOptional { OpNested1 = "11", OpNested2 = 11 }, - OpNav2 = new OptionalDependentNestedJsonSomeRequired { ReqNested1 = true, ReqNested2 = new DateTime(2001, 1, 1), OpNested1 = "1001", OpNested2 = 1001 } + OpNav2 = new OptionalDependentNestedJsonSomeRequired + { + ReqNested1 = true, + ReqNested2 = new DateTime(2001, 1, 1), + OpNested1 = "1001", + OpNested2 = 1001 + } } }; @@ -34,7 +40,13 @@ public static IReadOnlyList CreateEntitiesAl OpProp1 = "2", OpProp2 = 2, OpNav1 = new OptionalDependentNestedJsonAllOptional { OpNested1 = null, OpNested2 = 21 }, - OpNav2 = new OptionalDependentNestedJsonSomeRequired { ReqNested1 = true, ReqNested2 = new DateTime(2002, 1, 1), OpNested1 = "2001", OpNested2 = 2001 } + OpNav2 = new OptionalDependentNestedJsonSomeRequired + { + ReqNested1 = true, + ReqNested2 = new DateTime(2002, 1, 1), + OpNested1 = "2001", + OpNested2 = 2001 + } } }; @@ -47,7 +59,13 @@ public static IReadOnlyList CreateEntitiesAl OpProp1 = "3", OpProp2 = 3, OpNav1 = new OptionalDependentNestedJsonAllOptional { OpNested1 = null, OpNested2 = null }, - OpNav2 = new OptionalDependentNestedJsonSomeRequired { ReqNested1 = true, ReqNested2 = new DateTime(2003, 1, 1), OpNested1 = "3001", OpNested2 = 3001 } + OpNav2 = new OptionalDependentNestedJsonSomeRequired + { + ReqNested1 = true, + ReqNested2 = new DateTime(2003, 1, 1), + OpNested1 = "3001", + OpNested2 = 3001 + } } }; @@ -60,7 +78,13 @@ public static IReadOnlyList CreateEntitiesAl OpProp1 = "4", OpProp2 = 4, OpNav1 = new OptionalDependentNestedJsonAllOptional { OpNested1 = null, OpNested2 = 41 }, - OpNav2 = new OptionalDependentNestedJsonSomeRequired { ReqNested1 = true, ReqNested2 = new DateTime(2004, 1, 1), OpNested1 = null, OpNested2 = 4001 } + OpNav2 = new OptionalDependentNestedJsonSomeRequired + { + ReqNested1 = true, + ReqNested2 = new DateTime(2004, 1, 1), + OpNested1 = null, + OpNested2 = 4001 + } } }; @@ -73,7 +97,13 @@ public static IReadOnlyList CreateEntitiesAl OpProp1 = "5", OpProp2 = 5, OpNav1 = new OptionalDependentNestedJsonAllOptional { OpNested1 = null, OpNested2 = 51 }, - OpNav2 = new OptionalDependentNestedJsonSomeRequired { ReqNested1 = true, ReqNested2 = new DateTime(2005, 1, 1), OpNested1 = null, OpNested2 = null } + OpNav2 = new OptionalDependentNestedJsonSomeRequired + { + ReqNested1 = true, + ReqNested2 = new DateTime(2005, 1, 1), + OpNested1 = null, + OpNested2 = null + } } }; @@ -86,7 +116,13 @@ public static IReadOnlyList CreateEntitiesAl OpProp1 = "6", OpProp2 = 6, OpNav1 = null, - OpNav2 = new OptionalDependentNestedJsonSomeRequired { ReqNested1 = true, ReqNested2 = new DateTime(2005, 1, 1), OpNested1 = null, OpNested2 = 6001 } + OpNav2 = new OptionalDependentNestedJsonSomeRequired + { + ReqNested1 = true, + ReqNested2 = new DateTime(2005, 1, 1), + OpNested1 = null, + OpNested2 = 6001 + } } }; @@ -162,7 +198,21 @@ public static IReadOnlyList CreateEntitiesAl Json = null }; - return new List { e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12 }; + return new List + { + e1, + e2, + e3, + e4, + e5, + e6, + e7, + e8, + e9, + e10, + e11, + e12 + }; } public static IReadOnlyList CreateEntitiesSomeRequired() @@ -176,12 +226,22 @@ public static IReadOnlyList CreateEntitiesS ReqProp = 1.5, OpProp1 = "1", OpProp2 = 1, - ReqNav1 = new OptionalDependentNestedJsonAllOptional { OpNested1 = "11", OpNested2 = 11 }, - ReqNav2 = new OptionalDependentNestedJsonSomeRequired { ReqNested1 = true, ReqNested2 = new DateTime(4001, 1, 1), OpNested1 = "12", OpNested2 = 12 }, - + ReqNav2 = new OptionalDependentNestedJsonSomeRequired + { + ReqNested1 = true, + ReqNested2 = new DateTime(4001, 1, 1), + OpNested1 = "12", + OpNested2 = 12 + }, OpNav1 = new OptionalDependentNestedJsonAllOptional { OpNested1 = "13", OpNested2 = 13 }, - OpNav2 = new OptionalDependentNestedJsonSomeRequired { ReqNested1 = false, ReqNested2 = new DateTime(5001, 1, 1), OpNested1 = "14", OpNested2 = 14 } + OpNav2 = new OptionalDependentNestedJsonSomeRequired + { + ReqNested1 = false, + ReqNested2 = new DateTime(5001, 1, 1), + OpNested1 = "14", + OpNested2 = 14 + } } }; @@ -194,12 +254,22 @@ public static IReadOnlyList CreateEntitiesS ReqProp = 2.5, OpProp1 = "2", OpProp2 = 2, - ReqNav1 = new OptionalDependentNestedJsonAllOptional { OpNested1 = null, OpNested2 = 21 }, - ReqNav2 = new OptionalDependentNestedJsonSomeRequired { ReqNested1 = true, ReqNested2 = new DateTime(4002, 1, 1), OpNested1 = "22", OpNested2 = 22 }, - + ReqNav2 = new OptionalDependentNestedJsonSomeRequired + { + ReqNested1 = true, + ReqNested2 = new DateTime(4002, 1, 1), + OpNested1 = "22", + OpNested2 = 22 + }, OpNav1 = new OptionalDependentNestedJsonAllOptional { OpNested1 = "23", OpNested2 = 23 }, - OpNav2 = new OptionalDependentNestedJsonSomeRequired { ReqNested1 = false, ReqNested2 = new DateTime(5002, 1, 1), OpNested1 = "24", OpNested2 = 24 } + OpNav2 = new OptionalDependentNestedJsonSomeRequired + { + ReqNested1 = false, + ReqNested2 = new DateTime(5002, 1, 1), + OpNested1 = "24", + OpNested2 = 24 + } } }; @@ -212,12 +282,22 @@ public static IReadOnlyList CreateEntitiesS ReqProp = 3.5, OpProp1 = "3", OpProp2 = 3, - ReqNav1 = new OptionalDependentNestedJsonAllOptional { OpNested1 = null, OpNested2 = null }, - ReqNav2 = new OptionalDependentNestedJsonSomeRequired { ReqNested1 = true, ReqNested2 = new DateTime(4003, 1, 1), OpNested1 = "32", OpNested2 = 32 }, - + ReqNav2 = new OptionalDependentNestedJsonSomeRequired + { + ReqNested1 = true, + ReqNested2 = new DateTime(4003, 1, 1), + OpNested1 = "32", + OpNested2 = 32 + }, OpNav1 = new OptionalDependentNestedJsonAllOptional { OpNested1 = "33", OpNested2 = 33 }, - OpNav2 = new OptionalDependentNestedJsonSomeRequired { ReqNested1 = false, ReqNested2 = new DateTime(5003, 1, 1), OpNested1 = "34", OpNested2 = 34 } + OpNav2 = new OptionalDependentNestedJsonSomeRequired + { + ReqNested1 = false, + ReqNested2 = new DateTime(5003, 1, 1), + OpNested1 = "34", + OpNested2 = 34 + } } }; @@ -230,12 +310,22 @@ public static IReadOnlyList CreateEntitiesS ReqProp = 4.5, OpProp1 = "4", OpProp2 = 4, - ReqNav1 = new OptionalDependentNestedJsonAllOptional { OpNested1 = "41", OpNested2 = 41 }, - ReqNav2 = new OptionalDependentNestedJsonSomeRequired { ReqNested1 = true, ReqNested2 = new DateTime(4004, 1, 1), OpNested1 = null, OpNested2 = null }, - + ReqNav2 = new OptionalDependentNestedJsonSomeRequired + { + ReqNested1 = true, + ReqNested2 = new DateTime(4004, 1, 1), + OpNested1 = null, + OpNested2 = null + }, OpNav1 = new OptionalDependentNestedJsonAllOptional { OpNested1 = "43", OpNested2 = 43 }, - OpNav2 = new OptionalDependentNestedJsonSomeRequired { ReqNested1 = false, ReqNested2 = new DateTime(5004, 1, 1), OpNested1 = "44", OpNested2 = 44 } + OpNav2 = new OptionalDependentNestedJsonSomeRequired + { + ReqNested1 = false, + ReqNested2 = new DateTime(5004, 1, 1), + OpNested1 = "44", + OpNested2 = 44 + } } }; @@ -248,12 +338,22 @@ public static IReadOnlyList CreateEntitiesS ReqProp = 5.5, OpProp1 = "5", OpProp2 = 5, - ReqNav1 = new OptionalDependentNestedJsonAllOptional { OpNested1 = "51", OpNested2 = 51 }, - ReqNav2 = new OptionalDependentNestedJsonSomeRequired { ReqNested1 = true, ReqNested2 = new DateTime(4005, 1, 1), OpNested1 = "52", OpNested2 = 52 }, - + ReqNav2 = new OptionalDependentNestedJsonSomeRequired + { + ReqNested1 = true, + ReqNested2 = new DateTime(4005, 1, 1), + OpNested1 = "52", + OpNested2 = 52 + }, OpNav1 = new OptionalDependentNestedJsonAllOptional { OpNested1 = null, OpNested2 = null }, - OpNav2 = new OptionalDependentNestedJsonSomeRequired { ReqNested1 = false, ReqNested2 = new DateTime(5005, 1, 1), OpNested1 = "54", OpNested2 = 54 } + OpNav2 = new OptionalDependentNestedJsonSomeRequired + { + ReqNested1 = false, + ReqNested2 = new DateTime(5005, 1, 1), + OpNested1 = "54", + OpNested2 = 54 + } } }; @@ -266,12 +366,22 @@ public static IReadOnlyList CreateEntitiesS ReqProp = 6.5, OpProp1 = "6", OpProp2 = 6, - ReqNav1 = new OptionalDependentNestedJsonAllOptional { OpNested1 = "61", OpNested2 = 61 }, - ReqNav2 = new OptionalDependentNestedJsonSomeRequired { ReqNested1 = true, ReqNested2 = new DateTime(4006, 1, 1), OpNested1 = "62", OpNested2 = 62 }, - + ReqNav2 = new OptionalDependentNestedJsonSomeRequired + { + ReqNested1 = true, + ReqNested2 = new DateTime(4006, 1, 1), + OpNested1 = "62", + OpNested2 = 62 + }, OpNav1 = new OptionalDependentNestedJsonAllOptional { OpNested1 = "63", OpNested2 = 63 }, - OpNav2 = new OptionalDependentNestedJsonSomeRequired { ReqNested1 = false, ReqNested2 = new DateTime(5006, 1, 1), OpNested1 = null, OpNested2 = null } + OpNav2 = new OptionalDependentNestedJsonSomeRequired + { + ReqNested1 = false, + ReqNested2 = new DateTime(5006, 1, 1), + OpNested1 = null, + OpNested2 = null + } } }; @@ -284,12 +394,22 @@ public static IReadOnlyList CreateEntitiesS ReqProp = 7.5, OpProp1 = "7", OpProp2 = 7, - ReqNav1 = new OptionalDependentNestedJsonAllOptional { OpNested1 = "71", OpNested2 = 71 }, - ReqNav2 = new OptionalDependentNestedJsonSomeRequired { ReqNested1 = true, ReqNested2 = new DateTime(4007, 1, 1), OpNested1 = "72", OpNested2 = 72 }, - + ReqNav2 = new OptionalDependentNestedJsonSomeRequired + { + ReqNested1 = true, + ReqNested2 = new DateTime(4007, 1, 1), + OpNested1 = "72", + OpNested2 = 72 + }, OpNav1 = null, - OpNav2 = new OptionalDependentNestedJsonSomeRequired { ReqNested1 = false, ReqNested2 = new DateTime(5007, 1, 1), OpNested1 = "74", OpNested2 = 74 } + OpNav2 = new OptionalDependentNestedJsonSomeRequired + { + ReqNested1 = false, + ReqNested2 = new DateTime(5007, 1, 1), + OpNested1 = "74", + OpNested2 = 74 + } } }; @@ -302,10 +422,14 @@ public static IReadOnlyList CreateEntitiesS ReqProp = 8.5, OpProp1 = "8", OpProp2 = 8, - ReqNav1 = new OptionalDependentNestedJsonAllOptional { OpNested1 = "81", OpNested2 = 81 }, - ReqNav2 = new OptionalDependentNestedJsonSomeRequired { ReqNested1 = true, ReqNested2 = new DateTime(4008, 1, 1), OpNested1 = "82", OpNested2 = 82 }, - + ReqNav2 = new OptionalDependentNestedJsonSomeRequired + { + ReqNested1 = true, + ReqNested2 = new DateTime(4008, 1, 1), + OpNested1 = "82", + OpNested2 = 82 + }, OpNav1 = new OptionalDependentNestedJsonAllOptional { OpNested1 = "83", OpNested2 = 83 }, OpNav2 = null } @@ -320,10 +444,14 @@ public static IReadOnlyList CreateEntitiesS ReqProp = 9.5, OpProp1 = "9", OpProp2 = 9, - ReqNav1 = new OptionalDependentNestedJsonAllOptional { OpNested1 = "91", OpNested2 = 91 }, - ReqNav2 = new OptionalDependentNestedJsonSomeRequired { ReqNested1 = true, ReqNested2 = new DateTime(4009, 1, 1), OpNested1 = "92", OpNested2 = 92 }, - + ReqNav2 = new OptionalDependentNestedJsonSomeRequired + { + ReqNested1 = true, + ReqNested2 = new DateTime(4009, 1, 1), + OpNested1 = "92", + OpNested2 = 92 + }, OpNav1 = new OptionalDependentNestedJsonAllOptional { OpNested1 = null, OpNested2 = null }, OpNav2 = null } @@ -338,10 +466,14 @@ public static IReadOnlyList CreateEntitiesS ReqProp = 10.5, OpProp1 = "10", OpProp2 = 10, - ReqNav1 = new OptionalDependentNestedJsonAllOptional { OpNested1 = "101", OpNested2 = 101 }, - ReqNav2 = new OptionalDependentNestedJsonSomeRequired { ReqNested1 = true, ReqNested2 = new DateTime(4010, 1, 1), OpNested1 = "102", OpNested2 = 102 }, - + ReqNav2 = new OptionalDependentNestedJsonSomeRequired + { + ReqNested1 = true, + ReqNested2 = new DateTime(4010, 1, 1), + OpNested1 = "102", + OpNested2 = 102 + }, OpNav1 = null, OpNav2 = null } @@ -356,10 +488,14 @@ public static IReadOnlyList CreateEntitiesS ReqProp = 11.5, OpProp1 = null, OpProp2 = null, - ReqNav1 = new OptionalDependentNestedJsonAllOptional { OpNested1 = "111", OpNested2 = 111 }, - ReqNav2 = new OptionalDependentNestedJsonSomeRequired { ReqNested1 = true, ReqNested2 = new DateTime(4011, 1, 1), OpNested1 = "112", OpNested2 = 112 }, - + ReqNav2 = new OptionalDependentNestedJsonSomeRequired + { + ReqNested1 = true, + ReqNested2 = new DateTime(4011, 1, 1), + OpNested1 = "112", + OpNested2 = 112 + }, OpNav1 = null, OpNav2 = null } @@ -372,7 +508,21 @@ public static IReadOnlyList CreateEntitiesS Json = null }; - return new List { e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12 }; + return new List + { + e1, + e2, + e3, + e4, + e5, + e6, + e7, + e8, + e9, + e10, + e11, + e12 + }; } public IQueryable Set() diff --git a/test/EFCore.Relational.Specification.Tests/TestUtilities/PrecompiledQueryTestHelpers.cs b/test/EFCore.Relational.Specification.Tests/TestUtilities/PrecompiledQueryTestHelpers.cs index 2e8c217efe7..fdb1044e622 100644 --- a/test/EFCore.Relational.Specification.Tests/TestUtilities/PrecompiledQueryTestHelpers.cs +++ b/test/EFCore.Relational.Specification.Tests/TestUtilities/PrecompiledQueryTestHelpers.cs @@ -82,9 +82,9 @@ public async Task FullSourceTest( // This turns on the interceptors feature for the designated namespace(s). var parseOptions = new CSharpParseOptions().WithFeatures( - [ - new KeyValuePair("InterceptorsPreviewNamespaces", "Microsoft.EntityFrameworkCore.GeneratedInterceptors") - ]); + [ + new KeyValuePair("InterceptorsPreviewNamespaces", "Microsoft.EntityFrameworkCore.GeneratedInterceptors") + ]); var syntaxTree = CSharpSyntaxTree.ParseText(source, parseOptions, path: "Test.cs"); @@ -113,7 +113,8 @@ public async Task FullSourceTest( // Perform precompilation var precompilationErrors = new List(); generatedFiles = precompiledQueryCodeGenerator.GeneratePrecompiledQueries( - compilation, syntaxGenerator, dbContext, memberAccessReplacements: new Dictionary(), precompilationErrors, new HashSet(), additionalAssembly: assembly); + compilation, syntaxGenerator, dbContext, memberAccessReplacements: new Dictionary(), + precompilationErrors, new HashSet(), additionalAssembly: assembly); if (errorAsserter is null) { @@ -277,7 +278,8 @@ public class NonCompilingQueryCompiler( ICurrentDbContext currentContext, IEvaluatableExpressionFilter evaluatableExpressionFilter, IModel model) - : QueryCompiler(queryContextFactory, compiledQueryCache, compiledQueryCacheKeyGenerator, database, logger, + : QueryCompiler( + queryContextFactory, compiledQueryCache, compiledQueryCacheKeyGenerator, database, logger, currentContext, evaluatableExpressionFilter, model) { public const string ErrorMessage = diff --git a/test/EFCore.Relational.Specification.Tests/TestUtilities/RelationalModelAsserter.cs b/test/EFCore.Relational.Specification.Tests/TestUtilities/RelationalModelAsserter.cs index e76efee1a10..92f20aac4f6 100644 --- a/test/EFCore.Relational.Specification.Tests/TestUtilities/RelationalModelAsserter.cs +++ b/test/EFCore.Relational.Specification.Tests/TestUtilities/RelationalModelAsserter.cs @@ -9,7 +9,7 @@ namespace Microsoft.EntityFrameworkCore.TestUtilities; public class RelationalModelAsserter : ModelAsserter { - public new static RelationalModelAsserter Instance { get; } = new(); + public static new RelationalModelAsserter Instance { get; } = new(); public override void AssertEqual( IReadOnlyModel expected, @@ -38,7 +38,8 @@ public override void AssertEqual( Assert.Equal(expected.GetCollation(), actual.GetCollation()); } }, - () => Assert.Equal(expected.GetDbFunctions().Select(x => x), + () => Assert.Equal( + expected.GetDbFunctions().Select(x => x), actual.GetDbFunctions(), (expected, actual) => AssertEqual( @@ -47,7 +48,8 @@ public override void AssertEqual( compareMemberAnnotations ? expected.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations ? actual.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations)), - () => Assert.Equal(expected.GetSequences().Select(x => x), + () => Assert.Equal( + expected.GetSequences().Select(x => x), actual.GetSequences(), (expected, actual) => AssertEqual( @@ -95,7 +97,8 @@ public virtual bool AssertEqual( () => Assert.Equal(expected.MethodInfo, actual.MethodInfo), () => Assert.Equal(expected.Translation, actual.Translation), () => Assert.Equal(expected.TypeMapping?.StoreType, actual.TypeMapping?.StoreType), - () => Assert.Equal(expected.Parameters.Select(x => x), + () => Assert.Equal( + expected.Parameters.Select(x => x), actual.Parameters, (expected, actual) => AssertEqual( @@ -108,8 +111,9 @@ public virtual bool AssertEqual( { if (isFinalized) { - Assert.Equal(((IRuntimeDbFunction)expected).StoreFunction.SchemaQualifiedName, - ((IRuntimeDbFunction)actual).StoreFunction.SchemaQualifiedName); + Assert.Equal( + ((IRuntimeDbFunction)expected).StoreFunction.SchemaQualifiedName, + ((IRuntimeDbFunction)actual).StoreFunction.SchemaQualifiedName); } }, () => Assert.Equal(expectedAnnotations, actualAnnotations, TestAnnotationComparer.Instance)); @@ -143,8 +147,9 @@ public virtual bool AssertEqual( { if (isFinalized) { - Assert.Equal(((IRuntimeDbFunctionParameter)expected).StoreFunctionParameter.Name, - ((IRuntimeDbFunctionParameter)actual).StoreFunctionParameter.Name); + Assert.Equal( + ((IRuntimeDbFunctionParameter)expected).StoreFunctionParameter.Name, + ((IRuntimeDbFunctionParameter)actual).StoreFunctionParameter.Name); } }, () => Assert.Equal(expectedAnnotations, actualAnnotations, TestAnnotationComparer.Instance)); @@ -205,6 +210,7 @@ public override bool AssertEqual( Assert.Multiple( () => Assert.Equal(expected.GetDbSetName(), actual.GetDbSetName()), () => Assert.Equal(expected.GetContainerColumnName(), actual.GetContainerColumnName()), + () => Assert.Equal(expected.GetContainerColumnType(), actual.GetContainerColumnType()), () => Assert.Equal(expected.GetJsonPropertyName(), actual.GetJsonPropertyName()), () => { @@ -239,7 +245,8 @@ public override bool AssertEqual( actual.GetDeleteStoredProcedure(), compareBackreferences: false, compareMemberAnnotations), - () => Assert.Equal(expected.GetMappingFragments().Select(x => x), + () => Assert.Equal( + expected.GetMappingFragments().Select(x => x), actual.GetMappingFragments(), (expected, actual) => AssertEqual( @@ -252,7 +259,8 @@ public override bool AssertEqual( { if (designTime) { - Assert.Equal(expected.GetCheckConstraints().Select(x => x), + Assert.Equal( + expected.GetCheckConstraints().Select(x => x), actual.GetCheckConstraints(), (expected, actual) => AssertEqual( @@ -267,46 +275,54 @@ public override bool AssertEqual( { if (isFinalized) { - Assert.Equal(expectedStructuralType.GetDefaultMappings().Select(x => x), + Assert.Equal( + expectedStructuralType.GetDefaultMappings().Select(x => x), actualStructuralType.GetDefaultMappings(), (expected, actual) => - { - Assert.Equal(expected.Table.SchemaQualifiedName, actual.Table.SchemaQualifiedName); return true; - }); + { + Assert.Equal(expected.Table.SchemaQualifiedName, actual.Table.SchemaQualifiedName); + return true; + }); } }, () => { if (isFinalized) { - Assert.Equal(expectedStructuralType.GetTableMappings().Select(x => x), + Assert.Equal( + expectedStructuralType.GetTableMappings().Select(x => x), actualStructuralType.GetTableMappings(), (expected, actual) => - { - Assert.Equal(expected.Table.SchemaQualifiedName, actual.Table.SchemaQualifiedName); return true; - }); + { + Assert.Equal(expected.Table.SchemaQualifiedName, actual.Table.SchemaQualifiedName); + return true; + }); } }, () => { if (isFinalized) { - Assert.Equal(expectedStructuralType.GetViewMappings().Select(x => x), + Assert.Equal( + expectedStructuralType.GetViewMappings().Select(x => x), actualStructuralType.GetViewMappings(), (expected, actual) => - { - Assert.Equal(expected.Table.SchemaQualifiedName, actual.Table.SchemaQualifiedName); return true; - }); + { + Assert.Equal(expected.Table.SchemaQualifiedName, actual.Table.SchemaQualifiedName); + return true; + }); } }, () => { if (isFinalized) { - Assert.Equal(expectedStructuralType.GetSqlQueryMappings().Select(x => x), + Assert.Equal( + expectedStructuralType.GetSqlQueryMappings().Select(x => x), actualStructuralType.GetSqlQueryMappings(), (expected, actual) => { - Assert.Equal(expected.Table.SchemaQualifiedName, actual.Table.SchemaQualifiedName); return true; + Assert.Equal(expected.Table.SchemaQualifiedName, actual.Table.SchemaQualifiedName); + return true; }); } }, @@ -314,10 +330,12 @@ public override bool AssertEqual( { if (isFinalized) { - Assert.Equal(expectedStructuralType.GetFunctionMappings().Select(x => x), + Assert.Equal( + expectedStructuralType.GetFunctionMappings().Select(x => x), actualStructuralType.GetFunctionMappings(), (expected, actual) => { - Assert.Equal(expected.Table.SchemaQualifiedName, actual.Table.SchemaQualifiedName); return true; + Assert.Equal(expected.Table.SchemaQualifiedName, actual.Table.SchemaQualifiedName); + return true; }); } }, @@ -325,10 +343,12 @@ public override bool AssertEqual( { if (isFinalized) { - Assert.Equal(expectedStructuralType.GetInsertStoredProcedureMappings().Select(x => x), + Assert.Equal( + expectedStructuralType.GetInsertStoredProcedureMappings().Select(x => x), actualStructuralType.GetInsertStoredProcedureMappings(), (expected, actual) => { - Assert.Equal(expected.Table.SchemaQualifiedName, actual.Table.SchemaQualifiedName); return true; + Assert.Equal(expected.Table.SchemaQualifiedName, actual.Table.SchemaQualifiedName); + return true; }); } }, @@ -336,11 +356,13 @@ public override bool AssertEqual( { if (isFinalized) { - Assert.Equal(expectedStructuralType.GetUpdateStoredProcedureMappings().Select(x => x), + Assert.Equal( + expectedStructuralType.GetUpdateStoredProcedureMappings().Select(x => x), actualStructuralType.GetUpdateStoredProcedureMappings(), (expected, actual) => { - Assert.Equal(expected.Table.SchemaQualifiedName, actual.Table.SchemaQualifiedName); return true; + Assert.Equal(expected.Table.SchemaQualifiedName, actual.Table.SchemaQualifiedName); + return true; }); } }, @@ -348,11 +370,13 @@ public override bool AssertEqual( { if (isFinalized) { - Assert.Equal(expectedStructuralType.GetDeleteStoredProcedureMappings().Select(x => x), + Assert.Equal( + expectedStructuralType.GetDeleteStoredProcedureMappings().Select(x => x), actualStructuralType.GetDeleteStoredProcedureMappings(), (expected, actual) => { - Assert.Equal(expected.Table.SchemaQualifiedName, actual.Table.SchemaQualifiedName); return true; + Assert.Equal(expected.Table.SchemaQualifiedName, actual.Table.SchemaQualifiedName); + return true; }); } }); @@ -411,7 +435,8 @@ public virtual bool AssertEqual( Assert.Equal(expected.EntityType, actual.EntityType, EntityTypeFullNameComparer.Instance); } }, - () => Assert.Equal(expected.Parameters.Select(x => x), actual.Parameters, + () => Assert.Equal( + expected.Parameters.Select(x => x), actual.Parameters, (expected, actual) => AssertEqual( expected, @@ -420,7 +445,8 @@ public virtual bool AssertEqual( compareAnnotations ? actual.GetAnnotations() : Enumerable.Empty(), compareBackreferences: false, compareAnnotations)), - () => Assert.Equal(expected.ResultColumns.Select(x => x), actual.ResultColumns, + () => Assert.Equal( + expected.ResultColumns.Select(x => x), actual.ResultColumns, (expected, actual) => AssertEqual( expected, @@ -429,7 +455,8 @@ public virtual bool AssertEqual( compareAnnotations ? actual.GetAnnotations() : Enumerable.Empty(), compareBackreferences: false, compareAnnotations)), - () => Assert.Equal(((IRuntimeStoredProcedure)expected).StoreStoredProcedure.SchemaQualifiedName, + () => Assert.Equal( + ((IRuntimeStoredProcedure)expected).StoreStoredProcedure.SchemaQualifiedName, ((IRuntimeStoredProcedure)actual).StoreStoredProcedure.SchemaQualifiedName), () => Assert.Equal(expectedAnnotations, actualAnnotations, TestAnnotationComparer.Instance)); @@ -457,7 +484,8 @@ public virtual bool AssertEqual( Assert.Equal(expected.StoredProcedure.Name, actual.StoredProcedure.Name); } }, - () => Assert.Equal(((IRuntimeStoredProcedureParameter)expected).StoreParameter.Name, + () => Assert.Equal( + ((IRuntimeStoredProcedureParameter)expected).StoreParameter.Name, ((IRuntimeStoredProcedureParameter)actual).StoreParameter.Name), () => Assert.Equal(expectedAnnotations, actualAnnotations, TestAnnotationComparer.Instance)); @@ -483,11 +511,11 @@ public virtual bool AssertEqual( Assert.Equal(expected.StoredProcedure.Name, actual.StoredProcedure.Name); } }, - () => Assert.Equal(((IRuntimeStoredProcedureResultColumn)expected).StoreResultColumn.Name, + () => Assert.Equal( + ((IRuntimeStoredProcedureResultColumn)expected).StoreResultColumn.Name, ((IRuntimeStoredProcedureResultColumn)actual).StoreResultColumn.Name), () => Assert.Equal(expectedAnnotations, actualAnnotations, TestAnnotationComparer.Instance)); - return true; } @@ -543,6 +571,7 @@ public override bool AssertEqual( Assert.Multiple( () => Assert.Equal(expected.GetContainerColumnName(), actual.GetContainerColumnName()), + () => Assert.Equal(expected.GetContainerColumnType(), actual.GetContainerColumnType()), () => Assert.Equal(expectedStructuralType.GetJsonPropertyName(), actualStructuralType.GetJsonPropertyName()), () => Assert.Equal(expectedStructuralType.GetTableName(), actualStructuralType.GetTableName()), () => Assert.Equal(expectedStructuralType.GetViewName(), actualStructuralType.GetViewName()), @@ -563,7 +592,8 @@ public override bool AssertEqual( actualStructuralType.GetDeleteStoredProcedure(), compareBackreferences: false, compareMemberAnnotations), - () => Assert.Equal(expectedStructuralType.GetMappingFragments().Select(x => x), + () => Assert.Equal( + expectedStructuralType.GetMappingFragments().Select(x => x), actualStructuralType.GetMappingFragments(), (expected, actual) => AssertEqual( @@ -576,7 +606,8 @@ public override bool AssertEqual( { if (isFinalized) { - Assert.Equal(expectedStructuralType.GetDefaultMappings().Select(x => x), + Assert.Equal( + expectedStructuralType.GetDefaultMappings().Select(x => x), actualStructuralType.GetDefaultMappings(), (expected, actual) => { @@ -589,7 +620,8 @@ public override bool AssertEqual( { if (isFinalized) { - Assert.Equal(expectedStructuralType.GetTableMappings().Select(x => x), + Assert.Equal( + expectedStructuralType.GetTableMappings().Select(x => x), actualStructuralType.GetTableMappings().Select(x => x), (expected, actual) => { @@ -602,11 +634,13 @@ public override bool AssertEqual( { if (isFinalized) { - Assert.Equal(expectedStructuralType.GetViewMappings().Select(x => x), + Assert.Equal( + expectedStructuralType.GetViewMappings().Select(x => x), actualStructuralType.GetViewMappings(), (expected, actual) => { - Assert.Equal(expected.Table.SchemaQualifiedName, actual.Table.SchemaQualifiedName); return true; + Assert.Equal(expected.Table.SchemaQualifiedName, actual.Table.SchemaQualifiedName); + return true; }); } }, @@ -614,11 +648,13 @@ public override bool AssertEqual( { if (isFinalized) { - Assert.Equal(expectedStructuralType.GetSqlQueryMappings().Select(x => x), + Assert.Equal( + expectedStructuralType.GetSqlQueryMappings().Select(x => x), actualStructuralType.GetSqlQueryMappings(), (expected, actual) => { - Assert.Equal(expected.Table.SchemaQualifiedName, actual.Table.SchemaQualifiedName); return true; + Assert.Equal(expected.Table.SchemaQualifiedName, actual.Table.SchemaQualifiedName); + return true; }); } }, @@ -626,11 +662,13 @@ public override bool AssertEqual( { if (isFinalized) { - Assert.Equal(expectedStructuralType.GetFunctionMappings().Select(x => x), + Assert.Equal( + expectedStructuralType.GetFunctionMappings().Select(x => x), actualStructuralType.GetFunctionMappings(), (expected, actual) => { - Assert.Equal(expected.Table.SchemaQualifiedName, actual.Table.SchemaQualifiedName); return true; + Assert.Equal(expected.Table.SchemaQualifiedName, actual.Table.SchemaQualifiedName); + return true; }); } }, @@ -638,10 +676,13 @@ public override bool AssertEqual( { if (isFinalized) { - Assert.Equal(expectedStructuralType.GetInsertStoredProcedureMappings().Select(x => x), actualStructuralType.GetInsertStoredProcedureMappings(), + Assert.Equal( + expectedStructuralType.GetInsertStoredProcedureMappings().Select(x => x), + actualStructuralType.GetInsertStoredProcedureMappings(), (expected, actual) => { - Assert.Equal(expected.Table.SchemaQualifiedName, actual.Table.SchemaQualifiedName); return true; + Assert.Equal(expected.Table.SchemaQualifiedName, actual.Table.SchemaQualifiedName); + return true; }); } }, @@ -649,11 +690,13 @@ public override bool AssertEqual( { if (isFinalized) { - Assert.Equal(expectedStructuralType.GetUpdateStoredProcedureMappings().Select(x => x), + Assert.Equal( + expectedStructuralType.GetUpdateStoredProcedureMappings().Select(x => x), actualStructuralType.GetUpdateStoredProcedureMappings(), (expected, actual) => { - Assert.Equal(expected.Table.SchemaQualifiedName, actual.Table.SchemaQualifiedName); return true; + Assert.Equal(expected.Table.SchemaQualifiedName, actual.Table.SchemaQualifiedName); + return true; }); } }, @@ -661,11 +704,13 @@ public override bool AssertEqual( { if (isFinalized) { - Assert.Equal(expectedStructuralType.GetDeleteStoredProcedureMappings().Select(x => x), + Assert.Equal( + expectedStructuralType.GetDeleteStoredProcedureMappings().Select(x => x), actualStructuralType.GetDeleteStoredProcedureMappings(), (expected, actual) => { - Assert.Equal(expected.Table.SchemaQualifiedName, actual.Table.SchemaQualifiedName); return true; + Assert.Equal(expected.Table.SchemaQualifiedName, actual.Table.SchemaQualifiedName); + return true; }); } }); @@ -733,7 +778,8 @@ public override bool AssertEqual( Assert.Equal(expected.GetCollation(), actual.GetCollation()); } }, - () => Assert.Equal(expected.GetOverrides().Select(x => x), actual.GetOverrides().Select(x => x), + () => Assert.Equal( + expected.GetOverrides().Select(x => x), actual.GetOverrides().Select(x => x), (expected, actual) => AssertEqual( expected, @@ -744,7 +790,8 @@ public override bool AssertEqual( { if (isFinalized) { - Assert.Equal(expectedProperty.GetDefaultColumnMappings().Select(x => x), actualProperty.GetDefaultColumnMappings(), + Assert.Equal( + expectedProperty.GetDefaultColumnMappings().Select(x => x), actualProperty.GetDefaultColumnMappings(), (expected, actual) => { Assert.Equal(expected.Column.Table.SchemaQualifiedName, actual.Column.Table.SchemaQualifiedName); @@ -756,7 +803,8 @@ public override bool AssertEqual( { if (isFinalized) { - Assert.Equal(expectedProperty.GetTableColumnMappings().Select(x => x), actualProperty.GetTableColumnMappings(), + Assert.Equal( + expectedProperty.GetTableColumnMappings().Select(x => x), actualProperty.GetTableColumnMappings(), (expected, actual) => { Assert.Equal(expected.Column.Table.SchemaQualifiedName, actual.Column.Table.SchemaQualifiedName); @@ -768,7 +816,8 @@ public override bool AssertEqual( { if (isFinalized) { - Assert.Equal(expectedProperty.GetViewColumnMappings().Select(x => x), actualProperty.GetViewColumnMappings(), + Assert.Equal( + expectedProperty.GetViewColumnMappings().Select(x => x), actualProperty.GetViewColumnMappings(), (expected, actual) => { Assert.Equal(expected.Column.Table.SchemaQualifiedName, actual.Column.Table.SchemaQualifiedName); @@ -780,7 +829,9 @@ public override bool AssertEqual( { if (isFinalized) { - Assert.Equal(expectedProperty.GetSqlQueryColumnMappings().Select(x => x), actualProperty.GetSqlQueryColumnMappings(), (expected, actual) => + Assert.Equal( + expectedProperty.GetSqlQueryColumnMappings().Select(x => x), actualProperty.GetSqlQueryColumnMappings(), + (expected, actual) => { Assert.Equal(expected.Column.Table.SchemaQualifiedName, actual.Column.Table.SchemaQualifiedName); return true; @@ -791,7 +842,9 @@ public override bool AssertEqual( { if (isFinalized) { - Assert.Equal(expectedProperty.GetFunctionColumnMappings().Select(x => x), actualProperty.GetFunctionColumnMappings(), (expected, actual) => + Assert.Equal( + expectedProperty.GetFunctionColumnMappings().Select(x => x), actualProperty.GetFunctionColumnMappings(), + (expected, actual) => { Assert.Equal(expected.Column.Table.SchemaQualifiedName, actual.Column.Table.SchemaQualifiedName); return true; @@ -802,7 +855,9 @@ public override bool AssertEqual( { if (isFinalized) { - Assert.Equal(expectedProperty.GetInsertStoredProcedureParameterMappings().Select(x => x), actualProperty.GetInsertStoredProcedureParameterMappings(), (expected, actual) => + Assert.Equal( + expectedProperty.GetInsertStoredProcedureParameterMappings().Select(x => x), + actualProperty.GetInsertStoredProcedureParameterMappings(), (expected, actual) => { Assert.Equal(expected.Column.Table.SchemaQualifiedName, actual.Column.Table.SchemaQualifiedName); return true; @@ -813,7 +868,9 @@ public override bool AssertEqual( { if (isFinalized) { - Assert.Equal(expectedProperty.GetInsertStoredProcedureResultColumnMappings().Select(x => x), actualProperty.GetInsertStoredProcedureResultColumnMappings(), (expected, actual) => + Assert.Equal( + expectedProperty.GetInsertStoredProcedureResultColumnMappings().Select(x => x), + actualProperty.GetInsertStoredProcedureResultColumnMappings(), (expected, actual) => { Assert.Equal(expected.Column.Table.SchemaQualifiedName, actual.Column.Table.SchemaQualifiedName); return true; @@ -824,7 +881,9 @@ public override bool AssertEqual( { if (isFinalized) { - Assert.Equal(expectedProperty.GetUpdateStoredProcedureParameterMappings().Select(x => x), actualProperty.GetUpdateStoredProcedureParameterMappings(), (expected, actual) => + Assert.Equal( + expectedProperty.GetUpdateStoredProcedureParameterMappings().Select(x => x), + actualProperty.GetUpdateStoredProcedureParameterMappings(), (expected, actual) => { Assert.Equal(expected.Column.Table.SchemaQualifiedName, actual.Column.Table.SchemaQualifiedName); return true; @@ -835,7 +894,9 @@ public override bool AssertEqual( { if (isFinalized) { - Assert.Equal(expectedProperty.GetUpdateStoredProcedureResultColumnMappings().Select(x => x), actualProperty.GetUpdateStoredProcedureResultColumnMappings(), (expected, actual) => + Assert.Equal( + expectedProperty.GetUpdateStoredProcedureResultColumnMappings().Select(x => x), + actualProperty.GetUpdateStoredProcedureResultColumnMappings(), (expected, actual) => { Assert.Equal(expected.Column.Table.SchemaQualifiedName, actual.Column.Table.SchemaQualifiedName); return true; @@ -846,7 +907,9 @@ public override bool AssertEqual( { if (isFinalized) { - Assert.Equal(expectedProperty.GetDeleteStoredProcedureParameterMappings().Select(x => x), actualProperty.GetDeleteStoredProcedureParameterMappings(), (expected, actual) => + Assert.Equal( + expectedProperty.GetDeleteStoredProcedureParameterMappings().Select(x => x), + actualProperty.GetDeleteStoredProcedureParameterMappings(), (expected, actual) => { Assert.Equal(expected.Column.Table.SchemaQualifiedName, actual.Column.Table.SchemaQualifiedName); return true; @@ -905,7 +968,8 @@ public override bool AssertEqual( { if (isFinalized) { - Assert.Equal(expectedForeignKey.GetMappedConstraints().Select(x => x), + Assert.Equal( + expectedForeignKey.GetMappedConstraints().Select(x => x), actualForeignKey.GetMappedConstraints(), (expected, actual) => { @@ -949,7 +1013,8 @@ public override bool AssertEqual( { if (isFinalized) { - Assert.Equal(expectedIndex.GetMappedTableIndexes().Select(x => x), + Assert.Equal( + expectedIndex.GetMappedTableIndexes().Select(x => x), actualIndex.GetMappedTableIndexes(), (expected, actual) => { @@ -992,7 +1057,8 @@ public override bool AssertEqual( { if (isFinalized) { - Assert.Equal(expectedKey.GetMappedConstraints().Select(x => x), + Assert.Equal( + expectedKey.GetMappedConstraints().Select(x => x), actualKey.GetMappedConstraints(), (expected, actual) => { @@ -1040,7 +1106,8 @@ public virtual void AssertEqual( Assert.Equal(expected.Collation, actual.Collation); } }, - () => Assert.Equal(expectedModel.DefaultTables.Values.Select(x => x), actualModel.DefaultTables.Values, + () => Assert.Equal( + expectedModel.DefaultTables.Values.Select(x => x), actualModel.DefaultTables.Values, (expected, actual) => AssertEqual( expected, @@ -1048,7 +1115,8 @@ public virtual void AssertEqual( compareMemberAnnotations ? expected.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations ? actual.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations)), - () => Assert.Equal(expected.Tables.Select(x => x), actual.Tables, + () => Assert.Equal( + expected.Tables.Select(x => x), actual.Tables, (expected, actual) => AssertEqual( expected, @@ -1056,7 +1124,8 @@ public virtual void AssertEqual( compareMemberAnnotations ? expected.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations ? actual.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations)), - () => Assert.Equal(expected.Views.Select(x => x), actual.Views, + () => Assert.Equal( + expected.Views.Select(x => x), actual.Views, (expected, actual) => AssertEqual( expected, @@ -1064,7 +1133,8 @@ public virtual void AssertEqual( compareMemberAnnotations ? expected.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations ? actual.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations)), - () => Assert.Equal(expected.Queries.Select(x => x), actual.Queries, + () => Assert.Equal( + expected.Queries.Select(x => x), actual.Queries, (expected, actual) => AssertEqual( expected, @@ -1072,7 +1142,8 @@ public virtual void AssertEqual( compareMemberAnnotations ? expected.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations ? actual.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations)), - () => Assert.Equal(expected.Functions.Select(x => x), actual.Functions, + () => Assert.Equal( + expected.Functions.Select(x => x), actual.Functions, (expected, actual) => AssertEqual( expected, @@ -1080,7 +1151,8 @@ public virtual void AssertEqual( compareMemberAnnotations ? expected.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations ? actual.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations)), - () => Assert.Equal(expected.StoredProcedures.Select(x => x), actual.StoredProcedures, + () => Assert.Equal( + expected.StoredProcedures.Select(x => x), actual.StoredProcedures, (expected, actual) => AssertEqual( expected, @@ -1088,7 +1160,8 @@ public virtual void AssertEqual( compareMemberAnnotations ? expected.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations ? actual.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations)), - () => Assert.Equal(expected.Sequences.Select(x => x), actual.Sequences, + () => Assert.Equal( + expected.Sequences.Select(x => x), actual.Sequences, (expected, actual) => AssertEqual( expected, @@ -1139,7 +1212,8 @@ public virtual bool AssertEqual( Assert.Multiple( () => AssertEqualBase(expected, actual, expectedAnnotations, actualAnnotations, compareMemberAnnotations), () => Assert.Same(actual, ((RelationalModel)actual.Model).DefaultTables[actual.Name]), - () => Assert.Equal(expected.Columns, actual.Columns, + () => Assert.Equal( + expected.Columns, actual.Columns, (expected, actual) => AssertEqual( expected, @@ -1147,7 +1221,8 @@ public virtual bool AssertEqual( compareMemberAnnotations ? expected.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations ? actual.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations)), - () => Assert.Equal(expected.EntityTypeMappings.Select(x => x), actual.EntityTypeMappings, + () => Assert.Equal( + expected.EntityTypeMappings.Select(x => x), actual.EntityTypeMappings, (expected, actual) => AssertEqual( expected, @@ -1155,7 +1230,8 @@ public virtual bool AssertEqual( compareMemberAnnotations ? expected.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations ? actual.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations)), - () => Assert.Equal(expected.ComplexTypeMappings.Select(x => x), actual.ComplexTypeMappings, + () => Assert.Equal( + expected.ComplexTypeMappings.Select(x => x), actual.ComplexTypeMappings, (expected, actual) => AssertEqual( expected, @@ -1177,7 +1253,8 @@ public virtual bool AssertEqual( Assert.Multiple( () => AssertEqualBase(expected, actual, expectedAnnotations, actualAnnotations, compareMemberAnnotations), () => Assert.Same(actual, actual.Model.FindTable(actual.Name, actual.Schema)), - () => Assert.Equal(expected.Columns.Select(x => x), actual.Columns, + () => Assert.Equal( + expected.Columns.Select(x => x), actual.Columns, (expected, actual) => AssertEqual( expected, @@ -1185,42 +1262,48 @@ public virtual bool AssertEqual( compareMemberAnnotations ? expected.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations ? actual.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations)), - () => Assert.Equal(expected.Indexes.Select(x => x), actual.Indexes, + () => Assert.Equal( + expected.Indexes.Select(x => x), actual.Indexes, (expected, actual) => AssertEqual( expected, actual, compareMemberAnnotations ? expected.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations ? actual.GetAnnotations() : Enumerable.Empty())), - () => Assert.Equal(expected.ForeignKeyConstraints.Select(x => x), actual.ForeignKeyConstraints, + () => Assert.Equal( + expected.ForeignKeyConstraints.Select(x => x), actual.ForeignKeyConstraints, (expected, actual) => AssertEqual( expected, actual, compareMemberAnnotations ? expected.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations ? actual.GetAnnotations() : Enumerable.Empty())), - () => Assert.Equal(expected.ReferencingForeignKeyConstraints.Select(x => x), actual.ReferencingForeignKeyConstraints, + () => Assert.Equal( + expected.ReferencingForeignKeyConstraints.Select(x => x), actual.ReferencingForeignKeyConstraints, (expected, actual) => AssertEqual( expected, actual, compareMemberAnnotations ? expected.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations ? actual.GetAnnotations() : Enumerable.Empty())), - () => Assert.Equal(expected.UniqueConstraints.Select(x => x), actual.UniqueConstraints, + () => Assert.Equal( + expected.UniqueConstraints.Select(x => x), actual.UniqueConstraints, (expected, actual) => AssertEqual( expected, actual, compareMemberAnnotations ? expected.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations ? actual.GetAnnotations() : Enumerable.Empty())), - () => Assert.Equal(expected.Triggers.Select(x => x), actual.Triggers, + () => Assert.Equal( + expected.Triggers.Select(x => x), actual.Triggers, (expected, actual) => AssertEqual( expected, actual, compareMemberAnnotations ? expected.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations ? actual.GetAnnotations() : Enumerable.Empty())), - () => Assert.Equal(expected.EntityTypeMappings.Select(x => x), actual.EntityTypeMappings, + () => Assert.Equal( + expected.EntityTypeMappings.Select(x => x), actual.EntityTypeMappings, (expected, actual) => AssertEqual( expected, @@ -1228,7 +1311,8 @@ public virtual bool AssertEqual( compareMemberAnnotations ? expected.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations ? actual.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations)), - () => Assert.Equal(expected.ComplexTypeMappings.Select(x => x), actual.ComplexTypeMappings, + () => Assert.Equal( + expected.ComplexTypeMappings.Select(x => x), actual.ComplexTypeMappings, (expected, actual) => AssertEqual( expected, @@ -1250,7 +1334,8 @@ public virtual bool AssertEqual( Assert.Multiple( () => AssertEqualBase(expected, actual, expectedAnnotations, actualAnnotations, compareMemberAnnotations), () => Assert.Same(actual, actual.Model.FindView(actual.Name, actual.Schema)), - () => Assert.Equal(expected.Columns.Select(x => x), actual.Columns, + () => Assert.Equal( + expected.Columns.Select(x => x), actual.Columns, (expected, actual) => AssertEqual( expected, @@ -1258,7 +1343,8 @@ public virtual bool AssertEqual( compareMemberAnnotations ? expected.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations ? actual.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations)), - () => Assert.Equal(expected.EntityTypeMappings.Select(x => x), actual.EntityTypeMappings, + () => Assert.Equal( + expected.EntityTypeMappings.Select(x => x), actual.EntityTypeMappings, (expected, actual) => AssertEqual( expected, @@ -1266,7 +1352,8 @@ public virtual bool AssertEqual( compareMemberAnnotations ? expected.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations ? actual.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations)), - () => Assert.Equal(expected.ComplexTypeMappings.Select(x => x), actual.ComplexTypeMappings, + () => Assert.Equal( + expected.ComplexTypeMappings.Select(x => x), actual.ComplexTypeMappings, (expected, actual) => AssertEqual( expected, @@ -1289,7 +1376,8 @@ public virtual bool AssertEqual( () => AssertEqualBase(expected, actual, expectedAnnotations, actualAnnotations, compareMemberAnnotations), () => Assert.Equal(expected.Sql, actual.Sql), () => Assert.Same(actual, actual.Model.FindQuery(actual.Name)), - () => Assert.Equal(expected.Columns.Select(x => x), actual.Columns, + () => Assert.Equal( + expected.Columns.Select(x => x), actual.Columns, (expected, actual) => AssertEqual( expected, @@ -1297,7 +1385,8 @@ public virtual bool AssertEqual( compareMemberAnnotations ? expected.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations ? actual.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations)), - () => Assert.Equal(expected.EntityTypeMappings.Select(x => x), actual.EntityTypeMappings, + () => Assert.Equal( + expected.EntityTypeMappings.Select(x => x), actual.EntityTypeMappings, (expected, actual) => AssertEqual( expected, @@ -1305,7 +1394,8 @@ public virtual bool AssertEqual( compareMemberAnnotations ? expected.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations ? actual.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations)), - () => Assert.Equal(expected.ComplexTypeMappings.Select(x => x), actual.ComplexTypeMappings, + () => Assert.Equal( + expected.ComplexTypeMappings.Select(x => x), actual.ComplexTypeMappings, (expected, actual) => AssertEqual( expected, @@ -1333,7 +1423,8 @@ public virtual bool AssertEqual( () => Assert.Equal( actual.DbFunctions.Select(p => p.ModelName), expected.DbFunctions.Select(p => p.ModelName)), - () => Assert.Equal(expected.Parameters.Select(x => x), actual.Parameters, + () => Assert.Equal( + expected.Parameters.Select(x => x), actual.Parameters, (expected, actual) => AssertEqual( expected, @@ -1341,7 +1432,8 @@ public virtual bool AssertEqual( compareMemberAnnotations ? expected.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations ? actual.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations)), - () => Assert.Equal(expected.Columns.Select(x => x), actual.Columns, + () => Assert.Equal( + expected.Columns.Select(x => x), actual.Columns, (expected, actual) => AssertEqual( expected, @@ -1349,7 +1441,8 @@ public virtual bool AssertEqual( compareMemberAnnotations ? expected.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations ? actual.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations)), - () => Assert.Equal(expected.EntityTypeMappings.Select(x => x), actual.EntityTypeMappings, + () => Assert.Equal( + expected.EntityTypeMappings.Select(x => x), actual.EntityTypeMappings, (expected, actual) => AssertEqual( expected, @@ -1357,7 +1450,8 @@ public virtual bool AssertEqual( compareMemberAnnotations ? expected.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations ? actual.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations)), - () => Assert.Equal(expected.ComplexTypeMappings.Select(x => x), actual.ComplexTypeMappings, + () => Assert.Equal( + expected.ComplexTypeMappings.Select(x => x), actual.ComplexTypeMappings, (expected, actual) => AssertEqual( expected, @@ -1392,7 +1486,8 @@ public virtual bool AssertEqual( compareMemberAnnotations ? expected.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations ? actual.GetAnnotations() : Enumerable.Empty()); Assert.Same(actual, actual.ReturnValue.StoredProcedure); - Assert.Equal(expected.ReturnValue.PropertyMappings.Select(x => x), actual.ReturnValue.PropertyMappings, + Assert.Equal( + expected.ReturnValue.PropertyMappings.Select(x => x), actual.ReturnValue.PropertyMappings, (expected, actual) => AssertEqual( expected, @@ -1405,7 +1500,8 @@ public virtual bool AssertEqual( Assert.Null(actual.ReturnValue); } }, - () => Assert.Equal(expected.Parameters.Select(x => x), actual.Parameters, + () => Assert.Equal( + expected.Parameters.Select(x => x), actual.Parameters, (expected, actual) => AssertEqual( expected, @@ -1413,7 +1509,8 @@ public virtual bool AssertEqual( compareMemberAnnotations ? expected.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations ? actual.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations)), - () => Assert.Equal(expected.ResultColumns.Select(x => x), actual.ResultColumns, + () => Assert.Equal( + expected.ResultColumns.Select(x => x), actual.ResultColumns, (expected, actual) => AssertEqual( expected, @@ -1421,7 +1518,8 @@ public virtual bool AssertEqual( compareMemberAnnotations ? expected.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations ? actual.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations)), - () => Assert.Equal(expected.EntityTypeMappings.Select(x => x), actual.EntityTypeMappings, + () => Assert.Equal( + expected.EntityTypeMappings.Select(x => x), actual.EntityTypeMappings, (expected, actual) => AssertEqual( expected, @@ -1429,7 +1527,8 @@ public virtual bool AssertEqual( compareMemberAnnotations ? expected.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations ? actual.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations)), - () => Assert.Equal(expected.ComplexTypeMappings.Select(x => x), actual.ComplexTypeMappings, + () => Assert.Equal( + expected.ComplexTypeMappings.Select(x => x), actual.ComplexTypeMappings, (expected, actual) => AssertEqual( expected, @@ -1467,7 +1566,8 @@ public virtual bool AssertEqual( { Assert.Multiple( () => AssertEqualBase(expected, actual, expectedAnnotations, actualAnnotations), - () => Assert.Equal(expected.ColumnMappings.Select(x => x), actual.ColumnMappings, + () => Assert.Equal( + expected.ColumnMappings.Select(x => x), actual.ColumnMappings, (expected, actual) => AssertEqual( expected, @@ -1490,7 +1590,8 @@ public virtual bool AssertEqual( () => AssertEqual(expected.DeleteStoredProcedureMapping, actual.DeleteStoredProcedureMapping, compareMemberAnnotations), () => AssertEqual(expected.InsertStoredProcedureMapping, actual.InsertStoredProcedureMapping, compareMemberAnnotations), () => AssertEqual(expected.UpdateStoredProcedureMapping, actual.UpdateStoredProcedureMapping, compareMemberAnnotations), - () => Assert.Equal(expected.ColumnMappings.Select(x => x), actual.ColumnMappings, + () => Assert.Equal( + expected.ColumnMappings.Select(x => x), actual.ColumnMappings, (expected, actual) => AssertEqual( expected, @@ -1510,7 +1611,8 @@ public virtual bool AssertEqual( { Assert.Multiple( () => AssertEqualBase(expected, actual, expectedAnnotations, actualAnnotations), - () => Assert.Equal(expected.ColumnMappings.Select(x => x), actual.ColumnMappings, + () => Assert.Equal( + expected.ColumnMappings.Select(x => x), actual.ColumnMappings, (expected, actual) => AssertEqual( expected, @@ -1531,7 +1633,8 @@ public virtual bool AssertEqual( Assert.Multiple( () => AssertEqualBase(expected, actual, expectedAnnotations, actualAnnotations), () => Assert.Equal(expected.IsDefaultSqlQueryMapping, actual.IsDefaultSqlQueryMapping), - () => Assert.Equal(expected.ColumnMappings.Select(x => x), actual.ColumnMappings, + () => Assert.Equal( + expected.ColumnMappings.Select(x => x), actual.ColumnMappings, (expected, actual) => AssertEqual( expected, @@ -1552,7 +1655,8 @@ public virtual bool AssertEqual( Assert.Multiple( () => AssertEqualBase(expected, actual, expectedAnnotations, actualAnnotations), () => Assert.Equal(expected.IsDefaultFunctionMapping, actual.IsDefaultFunctionMapping), - () => Assert.Equal(expected.ColumnMappings.Select(x => x), actual.ColumnMappings, + () => Assert.Equal( + expected.ColumnMappings.Select(x => x), actual.ColumnMappings, (expected, actual) => AssertEqual( expected, @@ -1593,14 +1697,16 @@ public virtual bool AssertEqual( () => AssertEqualBase(expected, actual, expectedAnnotations, actualAnnotations), () => Assert.Equal(expected.StoredProcedure.GetSchemaQualifiedName(), actual.StoredProcedure.GetSchemaQualifiedName()), () => Assert.Contains(expected.TableMapping?.Table.SchemaQualifiedName, actual.TableMapping?.Table.SchemaQualifiedName), - () => Assert.Equal(expected.ResultColumnMappings.Select(x => x), actual.ResultColumnMappings, + () => Assert.Equal( + expected.ResultColumnMappings.Select(x => x), actual.ResultColumnMappings, (expected, actual) => AssertEqual( expected, actual, compareMemberAnnotations ? expected.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations ? actual.GetAnnotations() : Enumerable.Empty())), - () => Assert.Equal(expected.ParameterMappings.Select(x => x), actual.ParameterMappings, + () => Assert.Equal( + expected.ParameterMappings.Select(x => x), actual.ParameterMappings, (expected, actual) => AssertEqual( expected, @@ -1638,7 +1744,8 @@ public virtual bool AssertEqual( Assert.Multiple( () => AssertEqualBase(expected, actual, expectedAnnotations, actualAnnotations), () => Assert.Same(actual, actual.Table.FindColumn(actual.Name)), - () => Assert.Equal(expected.PropertyMappings.Select(x => x), actual.PropertyMappings, + () => Assert.Equal( + expected.PropertyMappings.Select(x => x), actual.PropertyMappings, (expected, actual) => AssertEqual( expected, @@ -1659,7 +1766,8 @@ public virtual bool AssertEqual( Assert.Multiple( () => AssertEqualBase(expected, actual, expectedAnnotations, actualAnnotations), () => Assert.Same(actual, actual.Table.FindColumn(actual.Name)), - () => Assert.Equal(expected.PropertyMappings.Select(x => x), actual.PropertyMappings, + () => Assert.Equal( + expected.PropertyMappings.Select(x => x), actual.PropertyMappings, (expected, actual) => AssertEqual( expected, @@ -1680,7 +1788,8 @@ public virtual bool AssertEqual( Assert.Multiple( () => AssertEqualBase(expected, actual, expectedAnnotations, actualAnnotations), () => Assert.Same(actual, actual.View.FindColumn(actual.Name)), - () => Assert.Equal(expected.PropertyMappings.Select(x => x), actual.PropertyMappings, + () => Assert.Equal( + expected.PropertyMappings.Select(x => x), actual.PropertyMappings, (expected, actual) => AssertEqual( expected, @@ -1701,7 +1810,8 @@ public virtual bool AssertEqual( Assert.Multiple( () => AssertEqualBase(expected, actual, expectedAnnotations, actualAnnotations), () => Assert.Same(actual, actual.SqlQuery.FindColumn(actual.Name)), - () => Assert.Equal(expected.PropertyMappings.Select(x => x), actual.PropertyMappings, + () => Assert.Equal( + expected.PropertyMappings.Select(x => x), actual.PropertyMappings, (expected, actual) => AssertEqual( expected, @@ -1722,7 +1832,8 @@ public virtual bool AssertEqual( Assert.Multiple( () => AssertEqualBase(expected, actual, expectedAnnotations, actualAnnotations), () => Assert.Same(actual, actual.Function.FindColumn(actual.Name)), - () => Assert.Equal(expected.PropertyMappings.Select(x => x), actual.PropertyMappings, + () => Assert.Equal( + expected.PropertyMappings.Select(x => x), actual.PropertyMappings, (expected, actual) => AssertEqual( expected, @@ -1744,7 +1855,8 @@ public virtual bool AssertEqual( () => Assert.Equal(expected.Name, actual.Name), () => Assert.Equal(expected.StoreType, actual.StoreType), () => Assert.Contains(actual, actual.Function.Parameters), - () => Assert.Equal(expected.DbFunctionParameters.Select(x => x), actual.DbFunctionParameters, + () => Assert.Equal( + expected.DbFunctionParameters.Select(x => x), actual.DbFunctionParameters, (expected, actual) => { Assert.Equal(expected.Name, actual.Name); @@ -1766,7 +1878,8 @@ public virtual bool AssertEqual( () => AssertEqualBase(expected, actual, expectedAnnotations, actualAnnotations), () => Assert.Equal(expected.Position, actual.Position), () => Assert.Same(actual, actual.StoredProcedure.FindResultColumn(actual.Name)), - () => Assert.Equal(expected.PropertyMappings.Select(x => x), actual.PropertyMappings, + () => Assert.Equal( + expected.PropertyMappings.Select(x => x), actual.PropertyMappings, (expected, actual) => AssertEqual( expected, @@ -1789,7 +1902,8 @@ public virtual bool AssertEqual( () => Assert.Equal(expected.Position, actual.Position), () => Assert.Equal(expected.Direction, actual.Direction), () => Assert.Same(actual, actual.StoredProcedure.FindParameter(actual.Name)), - () => Assert.Equal(expected.PropertyMappings.Select(x => x), actual.PropertyMappings, + () => Assert.Equal( + expected.PropertyMappings.Select(x => x), actual.PropertyMappings, (expected, actual) => AssertEqual( expected, @@ -1840,6 +1954,7 @@ public virtual bool AssertEqual( return true; } + public virtual bool AssertEqual( IViewColumnMapping expected, IViewColumnMapping actual, diff --git a/test/EFCore.Relational.Specification.Tests/TestUtilities/RelationalQueryAsserter.cs b/test/EFCore.Relational.Specification.Tests/TestUtilities/RelationalQueryAsserter.cs index 36c247629b3..95f022b888f 100644 --- a/test/EFCore.Relational.Specification.Tests/TestUtilities/RelationalQueryAsserter.cs +++ b/test/EFCore.Relational.Specification.Tests/TestUtilities/RelationalQueryAsserter.cs @@ -9,7 +9,8 @@ public class RelationalQueryAsserter( IQueryFixtureBase queryFixture, Func rewriteExpectedQueryExpression, Func rewriteServerQueryExpression, - bool ignoreEntryCount = false) : QueryAsserter(queryFixture, rewriteExpectedQueryExpression, rewriteServerQueryExpression, ignoreEntryCount) + bool ignoreEntryCount = false) : QueryAsserter( + queryFixture, rewriteExpectedQueryExpression, rewriteServerQueryExpression, ignoreEntryCount) { private static int ExecuteReader(DbCommand command) { @@ -79,7 +80,8 @@ public override async Task AssertQuery( var outputSql = true; try { - await base.AssertQuery(actualQuery, expectedQuery, elementSorter, elementAsserter, assertOrder, assertEmpty, async, testMethodName, filteredQuery); + await base.AssertQuery( + actualQuery, expectedQuery, elementSorter, elementAsserter, assertOrder, assertEmpty, async, testMethodName, filteredQuery); outputSql = false; } finally @@ -104,7 +106,8 @@ public override async Task AssertQueryScalar( var outputSql = true; try { - await base.AssertQueryScalar(actualQuery, expectedQuery, asserter, assertOrder, assertEmpty, async, testMethodName, filteredQuery); + await base.AssertQueryScalar( + actualQuery, expectedQuery, asserter, assertOrder, assertEmpty, async, testMethodName, filteredQuery); outputSql = false; } finally @@ -129,7 +132,8 @@ public override async Task AssertQueryScalar( var outputSql = true; try { - await base.AssertQueryScalar(actualQuery, expectedQuery, asserter, assertOrder, assertEmpty, async, testMethodName, filteredQuery); + await base.AssertQueryScalar( + actualQuery, expectedQuery, asserter, assertOrder, assertEmpty, async, testMethodName, filteredQuery); outputSql = false; } finally @@ -165,7 +169,8 @@ public override Task AssertAll( Expression> expectedPredicate, bool async = false, bool filteredQuery = false) - => RunAndOutputSqlOnFailure(() => base.AssertAll(actualQuery, expectedQuery, actualPredicate, expectedPredicate, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertAll(actualQuery, expectedQuery, actualPredicate, expectedPredicate, async, filteredQuery)); public override Task AssertAny( Func> actualQuery, @@ -181,7 +186,8 @@ public override Task AssertAny( Expression> expectedPredicate, bool async = false, bool filteredQuery = false) - => RunAndOutputSqlOnFailure(() => base.AssertAny(actualQuery, expectedQuery, actualPredicate, expectedPredicate, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertAny(actualQuery, expectedQuery, actualPredicate, expectedPredicate, async, filteredQuery)); public override Task AssertAverage( Func> actualQuery, @@ -271,7 +277,8 @@ public override Task AssertAverage( Action? asserter = null, bool async = false, bool filteredQuery = false) - => RunAndOutputSqlOnFailure(() => base.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); public override Task AssertAverage( Func> actualQuery, @@ -281,7 +288,8 @@ public override Task AssertAverage( Action? asserter = null, bool async = false, bool filteredQuery = false) - => RunAndOutputSqlOnFailure(() => base.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); public override Task AssertAverage( Func> actualQuery, @@ -291,7 +299,8 @@ public override Task AssertAverage( Action? asserter = null, bool async = false, bool filteredQuery = false) - => RunAndOutputSqlOnFailure(() => base.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); public override Task AssertAverage( Func> actualQuery, @@ -301,7 +310,8 @@ public override Task AssertAverage( Action? asserter = null, bool async = false, bool filteredQuery = false) - => RunAndOutputSqlOnFailure(() => base.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); public override Task AssertAverage( Func> actualQuery, @@ -311,7 +321,8 @@ public override Task AssertAverage( Action? asserter = null, bool async = false, bool filteredQuery = false) - => RunAndOutputSqlOnFailure(() => base.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); public override Task AssertAverage( Func> actualQuery, @@ -321,7 +332,8 @@ public override Task AssertAverage( Action? asserter = null, bool async = false, bool filteredQuery = false) - => RunAndOutputSqlOnFailure(() => base.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); public override Task AssertAverage( Func> actualQuery, @@ -331,7 +343,8 @@ public override Task AssertAverage( Action? asserter = null, bool async = false, bool filteredQuery = false) - => RunAndOutputSqlOnFailure(() => base.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); public override Task AssertAverage( Func> actualQuery, @@ -341,7 +354,8 @@ public override Task AssertAverage( Action? asserter = null, bool async = false, bool filteredQuery = false) - => RunAndOutputSqlOnFailure(() => base.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); public override Task AssertAverage( Func> actualQuery, @@ -351,7 +365,8 @@ public override Task AssertAverage( Action? asserter = null, bool async = false, bool filteredQuery = false) - => RunAndOutputSqlOnFailure(() => base.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); public override Task AssertAverage( Func> actualQuery, @@ -361,7 +376,8 @@ public override Task AssertAverage( Action? asserter = null, bool async = false, bool filteredQuery = false) - => RunAndOutputSqlOnFailure(() => base.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); public override Task AssertCount( Func> actualQuery, @@ -377,7 +393,8 @@ public override Task AssertCount( Expression> expectedPredicate, bool async = false, bool filteredQuery = false) - => RunAndOutputSqlOnFailure(() => base.AssertCount(actualQuery, expectedQuery, actualPredicate, expectedPredicate, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertCount(actualQuery, expectedQuery, actualPredicate, expectedPredicate, async, filteredQuery)); public override Task AssertElementAt( Func> actualQuery, @@ -387,7 +404,8 @@ public override Task AssertElementAt( Action? asserter = null, bool async = false, bool filteredQuery = false) - => RunAndOutputSqlOnFailure(() => base.AssertElementAt(actualQuery, expectedQuery, actualIndex, expectedIndex, asserter, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertElementAt(actualQuery, expectedQuery, actualIndex, expectedIndex, asserter, async, filteredQuery)); public override Task AssertElementAtOrDefault( Func> actualQuery, @@ -398,7 +416,8 @@ public override Task AssertElementAtOrDefault( bool async = false, bool filteredQuery = false) where TResult : default - => RunAndOutputSqlOnFailure(() => base.AssertElementAtOrDefault(actualQuery, expectedQuery, actualIndex, expectedIndex, asserter, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertElementAtOrDefault(actualQuery, expectedQuery, actualIndex, expectedIndex, asserter, async, filteredQuery)); public override Task AssertFirst( Func> actualQuery, @@ -416,7 +435,8 @@ public override Task AssertFirst( Action? asserter = null, bool async = false, bool filteredQuery = false) - => RunAndOutputSqlOnFailure(() => base.AssertFirst(actualQuery, expectedQuery, actualPredicate, expectedPredicate, asserter, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertFirst(actualQuery, expectedQuery, actualPredicate, expectedPredicate, asserter, async, filteredQuery)); public override Task AssertFirstOrDefault( Func> actualQuery, @@ -436,7 +456,9 @@ public override Task AssertFirstOrDefault( bool async = false, bool filteredQuery = false) where TResult : default - => RunAndOutputSqlOnFailure(() => base.AssertFirstOrDefault(actualQuery, expectedQuery, actualPredicate, expectedPredicate, asserter, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertFirstOrDefault( + actualQuery, expectedQuery, actualPredicate, expectedPredicate, asserter, async, filteredQuery)); public override Task AssertLast( Func> actualQuery, @@ -454,7 +476,8 @@ public override Task AssertLast( Action? asserter = null, bool async = false, bool filteredQuery = false) - => RunAndOutputSqlOnFailure(() => base.AssertLast(actualQuery, expectedQuery, actualPredicate, expectedPredicate, asserter, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertLast(actualQuery, expectedQuery, actualPredicate, expectedPredicate, asserter, async, filteredQuery)); public override Task AssertLastOrDefault( Func> actualQuery, @@ -474,7 +497,8 @@ public override Task AssertLastOrDefault( bool async = false, bool filteredQuery = false) where TResult : default - => RunAndOutputSqlOnFailure(() => base.AssertLastOrDefault(actualQuery, expectedQuery, actualPredicate, expectedPredicate, asserter, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertLastOrDefault(actualQuery, expectedQuery, actualPredicate, expectedPredicate, asserter, async, filteredQuery)); public override Task AssertLongCount( Func> actualQuery, @@ -490,7 +514,8 @@ public override Task AssertLongCount( Expression> expectedPredicate, bool async = false, bool filteredQuery = false) - => RunAndOutputSqlOnFailure(() => base.AssertLongCount(actualQuery, expectedQuery, actualPredicate, expectedPredicate, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertLongCount(actualQuery, expectedQuery, actualPredicate, expectedPredicate, async, filteredQuery)); public override Task AssertMax( Func> actualQuery, @@ -501,7 +526,8 @@ public override Task AssertMax( bool async = false, bool filteredQuery = false) where TSelector : default - => RunAndOutputSqlOnFailure(() => base.AssertMax(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertMax(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); public override Task AssertMax( Func> actualQuery, @@ -521,7 +547,8 @@ public override Task AssertMin( bool async = false, bool filteredQuery = false) where TSelector : default - => RunAndOutputSqlOnFailure(() => base.AssertMin(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertMin(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); public override Task AssertMin( Func> actualQuery, @@ -548,7 +575,8 @@ public override Task AssertSingle( Action? asserter = null, bool async = false, bool filteredQuery = false) - => RunAndOutputSqlOnFailure(() => base.AssertSingle(actualQuery, expectedQuery, actualPredicate, expectedPredicate, asserter, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertSingle(actualQuery, expectedQuery, actualPredicate, expectedPredicate, asserter, async, filteredQuery)); public override Task AssertSingleOrDefault( Func> actualQuery, @@ -568,7 +596,9 @@ public override Task AssertSingleOrDefault( bool async = false, bool filteredQuery = false) where TResult : default - => RunAndOutputSqlOnFailure(() => base.AssertSingleOrDefault(actualQuery, expectedQuery, actualPredicate, expectedPredicate, asserter, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertSingleOrDefault( + actualQuery, expectedQuery, actualPredicate, expectedPredicate, asserter, async, filteredQuery)); public override Task AssertSum( Func> actualQuery, @@ -658,7 +688,8 @@ public override Task AssertSum( Action? asserter = null, bool async = false, bool filteredQuery = false) - => RunAndOutputSqlOnFailure(() => base.AssertSum(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertSum(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); public override Task AssertSum( Func> actualQuery, @@ -668,7 +699,8 @@ public override Task AssertSum( Action? asserter = null, bool async = false, bool filteredQuery = false) - => RunAndOutputSqlOnFailure(() => base.AssertSum(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertSum(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); public override Task AssertSum( Func> actualQuery, @@ -678,7 +710,8 @@ public override Task AssertSum( Action? asserter = null, bool async = false, bool filteredQuery = false) - => RunAndOutputSqlOnFailure(() => base.AssertSum(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertSum(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); public override Task AssertSum( Func> actualQuery, @@ -688,7 +721,8 @@ public override Task AssertSum( Action? asserter = null, bool async = false, bool filteredQuery = false) - => RunAndOutputSqlOnFailure(() => base.AssertSum(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertSum(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); public override Task AssertSum( Func> actualQuery, @@ -698,7 +732,8 @@ public override Task AssertSum( Action? asserter = null, bool async = false, bool filteredQuery = false) - => RunAndOutputSqlOnFailure(() => base.AssertSum(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertSum(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); public override Task AssertSum( Func> actualQuery, @@ -708,7 +743,8 @@ public override Task AssertSum( Action? asserter = null, bool async = false, bool filteredQuery = false) - => RunAndOutputSqlOnFailure(() => base.AssertSum(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertSum(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); public override Task AssertSum( Func> actualQuery, @@ -718,7 +754,8 @@ public override Task AssertSum( Action? asserter = null, bool async = false, bool filteredQuery = false) - => RunAndOutputSqlOnFailure(() => base.AssertSum(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertSum(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); public override Task AssertSum( Func> actualQuery, @@ -728,7 +765,8 @@ public override Task AssertSum( Action? asserter = null, bool async = false, bool filteredQuery = false) - => RunAndOutputSqlOnFailure(() => base.AssertSum(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertSum(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); public override Task AssertSum( Func> actualQuery, @@ -738,7 +776,8 @@ public override Task AssertSum( Action? asserter = null, bool async = false, bool filteredQuery = false) - => RunAndOutputSqlOnFailure(() => base.AssertSum(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertSum(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); public override Task AssertSum( Func> actualQuery, @@ -748,5 +787,6 @@ public override Task AssertSum( Action? asserter = null, bool async = false, bool filteredQuery = false) - => RunAndOutputSqlOnFailure(() => base.AssertSum(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); + => RunAndOutputSqlOnFailure( + () => base.AssertSum(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async, filteredQuery)); } diff --git a/test/EFCore.Relational.Specification.Tests/TestUtilities/RelationalTestHelpers.cs b/test/EFCore.Relational.Specification.Tests/TestUtilities/RelationalTestHelpers.cs index 5b53c7eb7e4..58759a8ffaa 100644 --- a/test/EFCore.Relational.Specification.Tests/TestUtilities/RelationalTestHelpers.cs +++ b/test/EFCore.Relational.Specification.Tests/TestUtilities/RelationalTestHelpers.cs @@ -5,5 +5,6 @@ namespace Microsoft.EntityFrameworkCore.TestUtilities; public abstract class RelationalTestHelpers : TestHelpers { - public override ModelAsserter ModelAsserter => RelationalModelAsserter.Instance; + public override ModelAsserter ModelAsserter + => RelationalModelAsserter.Instance; } diff --git a/test/EFCore.Relational.Specification.Tests/TestUtilities/RelationalTestStore.cs b/test/EFCore.Relational.Specification.Tests/TestUtilities/RelationalTestStore.cs index 84b476f631a..adcec5650b5 100644 --- a/test/EFCore.Relational.Specification.Tests/TestUtilities/RelationalTestStore.cs +++ b/test/EFCore.Relational.Specification.Tests/TestUtilities/RelationalTestStore.cs @@ -44,10 +44,10 @@ public override async Task InitializeAsync( return this; } - public override void Dispose() + public override async ValueTask DisposeAsync() { - Connection?.Dispose(); - base.Dispose(); + await Connection.DisposeAsync(); + await base.DisposeAsync(); } public virtual string NormalizeDelimitersInRawString(string sql) diff --git a/test/EFCore.Relational.Specification.Tests/TestUtilities/TestSqlLoggerFactory.cs b/test/EFCore.Relational.Specification.Tests/TestUtilities/TestSqlLoggerFactory.cs index c07a15a4603..43ffe427271 100644 --- a/test/EFCore.Relational.Specification.Tests/TestUtilities/TestSqlLoggerFactory.cs +++ b/test/EFCore.Relational.Specification.Tests/TestUtilities/TestSqlLoggerFactory.cs @@ -28,9 +28,7 @@ public TestSqlLoggerFactory() public TestSqlLoggerFactory(Func shouldLogCategory) : base(c => shouldLogCategory(c) || c == DbLoggerCategory.Database.Command.Name) - { - Logger = new TestSqlLogger(shouldLogCategory(DbLoggerCategory.Database.Command.Name)); - } + => Logger = new TestSqlLogger(shouldLogCategory(DbLoggerCategory.Database.Command.Name)); public IReadOnlyList SqlStatements => ((TestSqlLogger)Logger).SqlStatements; diff --git a/test/EFCore.Relational.Specification.Tests/TwoDatabasesTestBase.cs b/test/EFCore.Relational.Specification.Tests/TwoDatabasesTestBase.cs index 286da3eced4..11b88c9e37c 100644 --- a/test/EFCore.Relational.Specification.Tests/TwoDatabasesTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/TwoDatabasesTestBase.cs @@ -98,7 +98,8 @@ public virtual void Can_set_connection_string_in_interceptor(bool withConnection Assert.Equal(new[] { "Modified One", "Modified Two" }, context1.Foos.Select(e => e.Bar).ToList()); } - protected class ConnectionStringConnectionInterceptor(string goodConnectionString, string dummyConnectionString) : DbConnectionInterceptor + protected class ConnectionStringConnectionInterceptor(string goodConnectionString, string dummyConnectionString) + : DbConnectionInterceptor { private readonly string _goodConnectionString = goodConnectionString; private readonly string _dummyConnectionString = dummyConnectionString; diff --git a/test/EFCore.Relational.Specification.Tests/Update/JsonUpdateFixtureBase.cs b/test/EFCore.Relational.Specification.Tests/Update/JsonUpdateFixtureBase.cs index da28dda859c..21a155ea558 100644 --- a/test/EFCore.Relational.Specification.Tests/Update/JsonUpdateFixtureBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Update/JsonUpdateFixtureBase.cs @@ -201,6 +201,17 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con b.Property(x => x.Name); }); + modelBuilder.Entity().Property(x => x.Id).ValueGeneratedNever(); + modelBuilder.Entity().OwnsOne(x => x.EntityReference, b => + { + b.Property(x => x.Id).ValueGeneratedNever(); + b.ToJson(); + b.OwnsOne(x => x.AEntityReference, bb => + { + bb.ToJson(); + }); + }); + base.OnModelCreating(modelBuilder, context); } diff --git a/test/EFCore.Relational.Specification.Tests/Update/JsonUpdateTestBase.cs b/test/EFCore.Relational.Specification.Tests/Update/JsonUpdateTestBase.cs index 39ef060e6c5..d8311cc9739 100644 --- a/test/EFCore.Relational.Specification.Tests/Update/JsonUpdateTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Update/JsonUpdateTestBase.cs @@ -35,12 +35,13 @@ public virtual Task Add_entity_with_json() OwnedCollectionBranch = [], OwnedReferenceBranch = new JsonOwnedBranch { + Id = 7, Date = new DateTime(2010, 10, 10), Enum = JsonEnum.Three, Fraction = 42.42m, OwnedCollectionLeaf = [ - new() { SomethingSomething = "ss1" }, new() { SomethingSomething = "ss2" } + new JsonOwnedLeaf { SomethingSomething = "ss1" }, new JsonOwnedLeaf { SomethingSomething = "ss2" } ], OwnedReferenceLeaf = new JsonOwnedLeaf { SomethingSomething = "ss3" } } @@ -65,6 +66,7 @@ public virtual Task Add_entity_with_json() Assert.Equal(new DateTime(2010, 10, 10), newEntity.OwnedReferenceRoot.OwnedReferenceBranch.Date); Assert.Equal(JsonEnum.Three, newEntity.OwnedReferenceRoot.OwnedReferenceBranch.Enum); Assert.Equal(42.42m, newEntity.OwnedReferenceRoot.OwnedReferenceBranch.Fraction); + Assert.Equal(7, newEntity.OwnedReferenceRoot.OwnedReferenceBranch.Id); Assert.Equal(42.42m, newEntity.OwnedReferenceRoot.OwnedReferenceBranch.Fraction); Assert.Equal("ss3", newEntity.OwnedReferenceRoot.OwnedReferenceBranch.OwnedReferenceLeaf.SomethingSomething); @@ -75,6 +77,46 @@ public virtual Task Add_entity_with_json() Assert.Equal("ss2", collectionLeaf[1].SomethingSomething); }); + [ConditionalFact] + public virtual Task Add_owned_entity_with_json() + => TestHelpers.ExecuteWithStrategyInTransactionAsync( + CreateContext, + UseTransaction, + async context => + { + var newEntity = new JsonEntityHasComplexChild + { + Id = 1, + Name = "NewEntity", + EntityReference = new JsonEntityHasComplexChildForReference + { + Id = 2, + Name = "NewReference", + AEntityReference = new AJsonEntityHasComplexChildForReferenceForReference + { + Id = 3, + Name = "NewReferenceReference" + } + } + }; + + context.Set().Add(newEntity); + ClearLog(); + await context.SaveChangesAsync(); + }, + async context => + { + var query = await context.JsonEntitiesHasComplexChild.ToListAsync(); + Assert.Equal(1, query.Count); + + var newEntity = query.Where(e => e.Id == 1).Single(); + Assert.Equal("NewEntity", newEntity.Name); + Assert.Equal(2, newEntity.EntityReference.Id); + Assert.Equal("NewReference", newEntity.EntityReference.Name); + Assert.Equal(3, newEntity.EntityReference.AEntityReference.Id); + Assert.Equal("NewReferenceReference", newEntity.EntityReference.AEntityReference.Name); + }); + [ConditionalFact] public virtual Task Add_entity_with_json_null_navigations() => TestHelpers.ExecuteWithStrategyInTransactionAsync( @@ -94,12 +136,13 @@ public virtual Task Add_entity_with_json_null_navigations() //OwnedCollectionBranch missing on purpose OwnedReferenceBranch = new JsonOwnedBranch { + Id = 7, Date = new DateTime(2010, 10, 10), Enum = JsonEnum.Three, Fraction = 42.42m, OwnedCollectionLeaf = [ - new() { SomethingSomething = "ss1" }, new() { SomethingSomething = "ss2" } + new JsonOwnedLeaf { SomethingSomething = "ss1" }, new JsonOwnedLeaf { SomethingSomething = "ss2" } ], OwnedReferenceLeaf = null, } @@ -124,6 +167,7 @@ public virtual Task Add_entity_with_json_null_navigations() Assert.Equal(new DateTime(2010, 10, 10), newEntity.OwnedReferenceRoot.OwnedReferenceBranch.Date); Assert.Equal(JsonEnum.Three, newEntity.OwnedReferenceRoot.OwnedReferenceBranch.Enum); Assert.Equal(42.42m, newEntity.OwnedReferenceRoot.OwnedReferenceBranch.Fraction); + Assert.Equal(7, newEntity.OwnedReferenceRoot.OwnedReferenceBranch.Id); Assert.Equal(42.42m, newEntity.OwnedReferenceRoot.OwnedReferenceBranch.Fraction); Assert.Null(newEntity.OwnedReferenceRoot.OwnedReferenceBranch.OwnedReferenceLeaf); @@ -159,12 +203,13 @@ public virtual Task Add_json_reference_root() OwnedCollectionBranch = [], OwnedReferenceBranch = new JsonOwnedBranch { + Id = 7, Date = new DateTime(2010, 10, 10), Enum = JsonEnum.Three, Fraction = 42.42m, OwnedCollectionLeaf = [ - new() { SomethingSomething = "ss1" }, new() { SomethingSomething = "ss2" } + new JsonOwnedLeaf { SomethingSomething = "ss1" }, new JsonOwnedLeaf { SomethingSomething = "ss2" } ], OwnedReferenceLeaf = new JsonOwnedLeaf { SomethingSomething = "ss3" } } @@ -182,6 +227,7 @@ public virtual Task Add_json_reference_root() Assert.Equal(new DateTime(2010, 10, 10), updatedReference.OwnedReferenceBranch.Date); Assert.Equal(JsonEnum.Three, updatedReference.OwnedReferenceBranch.Enum); Assert.Equal(42.42m, updatedReference.OwnedReferenceBranch.Fraction); + Assert.Equal(7, updatedReference.OwnedReferenceBranch.Id); Assert.Equal("ss3", updatedReference.OwnedReferenceBranch.OwnedReferenceLeaf.SomethingSomething); var collectionLeaf = updatedReference.OwnedReferenceBranch.OwnedCollectionLeaf; Assert.Equal(2, collectionLeaf.Count); @@ -237,12 +283,13 @@ public virtual Task Add_element_to_json_collection_root() OwnedCollectionBranch = [], OwnedReferenceBranch = new JsonOwnedBranch { + Id = 7, Date = new DateTime(2010, 10, 10), Enum = JsonEnum.Three, Fraction = 42.42m, OwnedCollectionLeaf = [ - new() { SomethingSomething = "ss1" }, new() { SomethingSomething = "ss2" } + new JsonOwnedLeaf { SomethingSomething = "ss1" }, new JsonOwnedLeaf { SomethingSomething = "ss2" } ], OwnedReferenceLeaf = new JsonOwnedLeaf { SomethingSomething = "ss3" } } @@ -262,6 +309,7 @@ public virtual Task Add_element_to_json_collection_root() Assert.Empty(updatedCollection[2].OwnedCollectionBranch); Assert.Equal(new DateTime(2010, 10, 10), updatedCollection[2].OwnedReferenceBranch.Date); Assert.Equal(JsonEnum.Three, updatedCollection[2].OwnedReferenceBranch.Enum); + Assert.Equal(7, updatedCollection[2].OwnedReferenceBranch.Id); Assert.Equal(42.42m, updatedCollection[2].OwnedReferenceBranch.Fraction); Assert.Equal("ss3", updatedCollection[2].OwnedReferenceBranch.OwnedReferenceLeaf.SomethingSomething); var collectionLeaf = updatedCollection[2].OwnedReferenceBranch.OwnedCollectionLeaf; @@ -287,6 +335,7 @@ public virtual Task Add_element_to_json_collection_root_null_navigations() OwnedCollectionBranch = null, OwnedReferenceBranch = new JsonOwnedBranch { + Id = 7, Date = new DateTime(2010, 10, 10), Enum = JsonEnum.Three, Fraction = 42.42m, @@ -308,6 +357,7 @@ public virtual Task Add_element_to_json_collection_root_null_navigations() Assert.Null(updatedCollection[2].OwnedCollectionBranch); Assert.Equal(new DateTime(2010, 10, 10), updatedCollection[2].OwnedReferenceBranch.Date); Assert.Equal(JsonEnum.Three, updatedCollection[2].OwnedReferenceBranch.Enum); + Assert.Equal(7, updatedCollection[2].OwnedReferenceBranch.Id); Assert.Equal(42.42m, updatedCollection[2].OwnedReferenceBranch.Fraction); Assert.Null(updatedCollection[2].OwnedReferenceBranch.OwnedReferenceLeaf); Assert.Null(updatedCollection[2].OwnedReferenceBranch.OwnedCollectionLeaf); @@ -324,12 +374,13 @@ public virtual Task Add_element_to_json_collection_branch() var entity = query.Single(); var newBranch = new JsonOwnedBranch { + Id = 77, Date = new DateTime(2010, 10, 10), Enum = JsonEnum.Three, Fraction = 42.42m, OwnedCollectionLeaf = [ - new() { SomethingSomething = "ss1" }, new() { SomethingSomething = "ss2" } + new JsonOwnedLeaf { SomethingSomething = "ss1" }, new JsonOwnedLeaf { SomethingSomething = "ss2" } ], OwnedReferenceLeaf = new JsonOwnedLeaf { SomethingSomething = "ss3" } }; @@ -346,6 +397,7 @@ public virtual Task Add_element_to_json_collection_branch() Assert.Equal(new DateTime(2010, 10, 10), updatedCollection[2].Date); Assert.Equal(JsonEnum.Three, updatedCollection[2].Enum); Assert.Equal(42.42m, updatedCollection[2].Fraction); + Assert.Equal(77, updatedCollection[2].Id); Assert.Equal("ss3", updatedCollection[2].OwnedReferenceLeaf.SomethingSomething); var collectionLeaf = updatedCollection[2].OwnedCollectionLeaf; Assert.Equal(2, collectionLeaf.Count); @@ -548,12 +600,13 @@ public virtual Task Add_element_to_json_collection_on_derived() var newBranch = new JsonOwnedBranch { + Id = 77, Date = new DateTime(2010, 10, 10), Enum = JsonEnum.Three, Fraction = 42.42m, OwnedCollectionLeaf = [ - new() { SomethingSomething = "ss1" }, new() { SomethingSomething = "ss2" } + new JsonOwnedLeaf { SomethingSomething = "ss1" }, new JsonOwnedLeaf { SomethingSomething = "ss2" } ], OwnedReferenceLeaf = new JsonOwnedLeaf { SomethingSomething = "ss3" } }; @@ -570,6 +623,7 @@ public virtual Task Add_element_to_json_collection_on_derived() Assert.Equal(new DateTime(2010, 10, 10), updatedCollection[2].Date); Assert.Equal(JsonEnum.Three, updatedCollection[2].Enum); Assert.Equal(42.42m, updatedCollection[2].Fraction); + Assert.Equal(77, updatedCollection[2].Id); Assert.Equal("ss3", updatedCollection[2].OwnedReferenceLeaf.SomethingSomething); var collectionLeaf = updatedCollection[2].OwnedCollectionLeaf; Assert.Equal(2, collectionLeaf.Count); @@ -621,6 +675,7 @@ public virtual Task Edit_element_in_json_branch_collection_and_add_element_to_th entity.OwnedReferenceRoot.OwnedCollectionBranch.Add( new JsonOwnedBranch { + Id = 77, Date = new DateTime(2222, 11, 11), Enum = JsonEnum.Three, Fraction = 45.32m, @@ -638,6 +693,7 @@ public virtual Task Edit_element_in_json_branch_collection_and_add_element_to_th Assert.Equal(new DateTime(2222, 11, 11), result.OwnedReferenceRoot.OwnedCollectionBranch[2].Date); Assert.Equal(JsonEnum.Three, result.OwnedReferenceRoot.OwnedCollectionBranch[2].Enum); Assert.Equal(45.32m, result.OwnedReferenceRoot.OwnedCollectionBranch[2].Fraction); + Assert.Equal(77, result.OwnedReferenceRoot.OwnedCollectionBranch[2].Id); Assert.Equal("cc", result.OwnedReferenceRoot.OwnedCollectionBranch[2].OwnedReferenceLeaf.SomethingSomething); }); @@ -1468,7 +1524,7 @@ public virtual Task Edit_a_scalar_property_and_collection_navigation_on_the_same var query = await context.JsonEntitiesBasic.ToListAsync(); var entity = query.Single(); entity.OwnedReferenceRoot.OwnedReferenceBranch.Fraction = 523.532M; - entity.OwnedReferenceRoot.OwnedReferenceBranch.OwnedCollectionLeaf = [new() { SomethingSomething = "edit" }]; + entity.OwnedReferenceRoot.OwnedReferenceBranch.OwnedCollectionLeaf = [new JsonOwnedLeaf { SomethingSomething = "edit" }]; ClearLog(); await context.SaveChangesAsync(); @@ -1882,8 +1938,8 @@ public virtual Task Edit_single_property_collection_of_guid() { var query = await context.JsonEntitiesAllTypes.ToListAsync(); var entity = query.Single(x => x.Id == 1); - entity.Reference.TestGuidCollection = [new("12345678-1234-4321-5555-987654321000")]; - entity.Collection[0].TestGuidCollection = [new("12345678-1234-4321-5555-987654321000")]; + entity.Reference.TestGuidCollection = [new Guid("12345678-1234-4321-5555-987654321000")]; + entity.Collection[0].TestGuidCollection = [new Guid("12345678-1234-4321-5555-987654321000")]; ClearLog(); await context.SaveChangesAsync(); @@ -1891,8 +1947,8 @@ public virtual Task Edit_single_property_collection_of_guid() async context => { var result = await context.Set().SingleAsync(x => x.Id == 1); - Assert.Equal([new("12345678-1234-4321-5555-987654321000")], result.Reference.TestGuidCollection); - Assert.Equal([new("12345678-1234-4321-5555-987654321000")], result.Collection[0].TestGuidCollection); + Assert.Equal([new Guid("12345678-1234-4321-5555-987654321000")], result.Reference.TestGuidCollection); + Assert.Equal([new Guid("12345678-1234-4321-5555-987654321000")], result.Collection[0].TestGuidCollection); Assert.False(result.Reference.NewCollectionSet); Assert.False(result.Collection[0].NewCollectionSet); @@ -2622,7 +2678,7 @@ public virtual Task Edit_single_property_relational_collection_of_guid() { var query = await context.JsonEntitiesAllTypes.ToListAsync(); var entity = query.Single(x => x.Id == 1); - entity.TestGuidCollection = new ReadOnlyCollection([new("12345678-1234-4321-5555-987654321000")]); + entity.TestGuidCollection = new ReadOnlyCollection([new Guid("12345678-1234-4321-5555-987654321000")]); ClearLog(); await context.SaveChangesAsync(); @@ -2630,7 +2686,7 @@ public virtual Task Edit_single_property_relational_collection_of_guid() async context => { var result = await context.Set().SingleAsync(x => x.Id == 1); - Assert.Equal(new ReadOnlyCollection([new("12345678-1234-4321-5555-987654321000")]), result.TestGuidCollection); + Assert.Equal(new ReadOnlyCollection([new Guid("12345678-1234-4321-5555-987654321000")]), result.TestGuidCollection); Assert.False(result.NewCollectionSet); }); @@ -2688,7 +2744,7 @@ public virtual Task Edit_single_property_relational_collection_of_int64() { var query = await context.JsonEntitiesAllTypes.ToListAsync(); var entity = query.Single(x => x.Id == 1); - entity.TestInt64Collection = new([]); + entity.TestInt64Collection = new ReadOnlyCollection([]); ClearLog(); await context.SaveChangesAsync(); @@ -3096,7 +3152,7 @@ public virtual Task Edit_single_property_collection_of_collection_of_char() var query = await context.JsonEntitiesAllTypes.ToListAsync(); var entity = query.Single(x => x.Id == 1); entity.Reference.TestCharacterCollectionCollection[0] = - ['E', 'F', 'C', 'ö', 'r', 'E', '\"', '\\']; + ['E', 'F', 'C', 'ö', 'r', 'E', '\"', '\\']; entity.Collection[0].TestCharacterCollectionCollection[2] = ['D', 'E', 'F', '\0']; ClearLog(); @@ -3105,7 +3161,9 @@ public virtual Task Edit_single_property_collection_of_collection_of_char() async context => { var result = await context.Set().SingleAsync(x => x.Id == 1); - Assert.Equal([['E', 'F', 'C', 'ö', 'r', 'E', '\"', '\\'], null, ['D', 'E', 'F']], result.Reference.TestCharacterCollectionCollection); + Assert.Equal( + [['E', 'F', 'C', 'ö', 'r', 'E', '\"', '\\'], null, ['D', 'E', 'F']], + result.Reference.TestCharacterCollectionCollection); Assert.Equal([['A', 'B', 'C'], null, ['D', 'E', 'F', '\0']], result.Collection[0].TestCharacterCollectionCollection); }); @@ -3150,8 +3208,12 @@ public virtual Task Edit_single_property_collection_of_collection_of_int16() async context => { var result = await context.Set().SingleAsync(x => x.Id == 1); - Assert.Equal([[short.MinValue, 0, short.MaxValue], null, [short.MinValue, 0, short.MaxValue, 3234]], result.Reference.TestInt16CollectionCollection); - Assert.Equal([[short.MinValue, 0, short.MaxValue], null, [short.MinValue, 0, short.MaxValue], null], result.Collection[0].TestInt16CollectionCollection); + Assert.Equal( + [[short.MinValue, 0, short.MaxValue], null, [short.MinValue, 0, short.MaxValue, 3234]], + result.Reference.TestInt16CollectionCollection); + Assert.Equal( + [[short.MinValue, 0, short.MaxValue], null, [short.MinValue, 0, short.MaxValue], null], + result.Collection[0].TestInt16CollectionCollection); }); [ConditionalFact] @@ -3242,8 +3304,12 @@ public virtual Task Edit_single_property_collection_of_collection_of_nullable_in async context => { var result = await context.Set().SingleAsync(x => x.Id == 1); - Assert.Equal([[77], [int.MinValue, null, int.MaxValue, null], null, [int.MinValue, 0, int.MaxValue], null], result.Reference.TestNullableInt32CollectionCollection); - Assert.Equal([null, [int.MinValue, null, int.MaxValue, null], null, [int.MinValue, 0, int.MaxValue], [null, 77]], result.Collection[0].TestNullableInt32CollectionCollection); + Assert.Equal( + [[77], [int.MinValue, null, int.MaxValue, null], null, [int.MinValue, 0, int.MaxValue], null], + result.Reference.TestNullableInt32CollectionCollection); + Assert.Equal( + [null, [int.MinValue, null, int.MaxValue, null], null, [int.MinValue, 0, int.MaxValue], [null, 77]], + result.Collection[0].TestNullableInt32CollectionCollection); }); [ConditionalFact] @@ -3332,7 +3398,7 @@ public virtual Task Add_and_update_top_level_optional_owned_collection_to_JSON(b OwnedCollectionRoot = value.HasValue ? value.Value - ? [new()] + ? [new JsonOwnedRoot()] : [] : null }; @@ -3366,6 +3432,7 @@ public virtual Task Add_and_update_top_level_optional_owned_collection_to_JSON(b // Because just setting the navigation to an empty collection currently doesn't mark it as modified. context.Entry(newEntity).State = EntityState.Modified; } + await context.SaveChangesAsync(); var saved = context.Database.SqlQueryRaw("select OwnedCollectionRoot from JsonEntitiesBasic where Id = 2").ToList(); @@ -3405,12 +3472,12 @@ public virtual Task Add_and_update_nested_optional_owned_collection_to_JSON(bool { Id = 2, Name = "NewEntity", - OwnedReferenceRoot = new JsonOwnedRoot() + OwnedReferenceRoot = new JsonOwnedRoot { OwnedCollectionBranch = value.HasValue ? value.Value - ? [new()] + ? [new JsonOwnedBranch()] : [] : null } @@ -3445,6 +3512,7 @@ public virtual Task Add_and_update_nested_optional_owned_collection_to_JSON(bool // Because just setting the navigation to an empty collection currently doesn't mark it as modified. context.Entry(newEntity).Reference(e => e.OwnedReferenceRoot).TargetEntry!.State = EntityState.Modified; } + await context.SaveChangesAsync(); }, async context => @@ -3468,7 +3536,6 @@ public virtual Task Add_and_update_nested_optional_owned_collection_to_JSON(bool } }); - [ConditionalTheory] [InlineData(false)] [InlineData(true)] @@ -3490,10 +3557,10 @@ public virtual Task Add_and_update_nested_optional_primitive_collection(bool? va TestDateTimeOffsetCollection = [], TestDoubleCollection = [], TestDecimalCollection = [], - TestGuidCollection = new([]), + TestGuidCollection = new ReadOnlyCollection([]), TestInt16Collection = [], TestInt32Collection = [], - TestInt64Collection = new([]), + TestInt64Collection = new ReadOnlyCollection([]), TestSignedByteCollection = [], TestSingleCollection = [], TestTimeSpanCollection = [], @@ -3519,10 +3586,10 @@ public virtual Task Add_and_update_nested_optional_primitive_collection(bool? va TestNullableEnumWithIntConverterCollectionCollection = [], Collection = [ - new() + new JsonOwnedAllTypes { TestDefaultStringCollection = [], - TestMaxLengthStringCollection = new([]), + TestMaxLengthStringCollection = new ReadOnlyCollection([]), TestBooleanCollection = [], TestDateTimeCollection = [], TestDateTimeOffsetCollection = [], 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/DbSetAsTableNameTest.cs b/test/EFCore.Relational.Tests/DbSetAsTableNameTest.cs index d94e00a99d7..ba4df9e5e61 100644 --- a/test/EFCore.Relational.Tests/DbSetAsTableNameTest.cs +++ b/test/EFCore.Relational.Tests/DbSetAsTableNameTest.cs @@ -142,8 +142,20 @@ protected abstract class SetsContext : DbContext public DbSet WheatThins { get; set; } public DbSet Food { get; set; } public DbSet Beverage { get; set; } - public DbSet ReallyLongNames12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890A { get; set; } - public DbSet ReallyLongNames12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890B { get; set; } + + public DbSet + ReallyLongNames12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890A + { + get; + set; + } + + public DbSet + ReallyLongNames12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890B + { + get; + set; + } public DbSet Bovrils => Set("Bovril"); 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.Relational.Tests/Extensions/RelationalDatabaseFacadeExtensionsTest.cs b/test/EFCore.Relational.Tests/Extensions/RelationalDatabaseFacadeExtensionsTest.cs index a3dc6bb70a2..f2d2a935de3 100644 --- a/test/EFCore.Relational.Tests/Extensions/RelationalDatabaseFacadeExtensionsTest.cs +++ b/test/EFCore.Relational.Tests/Extensions/RelationalDatabaseFacadeExtensionsTest.cs @@ -321,6 +321,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) private class FakeHistoryRepository : IHistoryRepository { + public virtual LockReleaseBehavior LockReleaseBehavior => LockReleaseBehavior.Explicit; + public List AppliedMigrations { get; set; } public IReadOnlyList GetAppliedMigrations() @@ -355,16 +357,17 @@ public string GetBeginIfExistsScript(string migrationId) public string GetEndIfScript() => throw new NotImplementedException(); + public void Create() => throw new NotImplementedException(); public Task CreateAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException(); - public IDisposable GetDatabaseLock(TimeSpan timeout) + public IMigrationsDatabaseLock AcquireDatabaseLock() => throw new NotImplementedException(); - public Task GetDatabaseLockAsync(TimeSpan timeout, CancellationToken cancellationToken = default) + public Task AcquireDatabaseLockAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException(); } @@ -389,7 +392,8 @@ public async Task GetPendingMigrations_works(bool async) .AddSingleton(repository) .AddSingleton(migrationsAssembly)); - Assert.Equal(["00000000000003_Three"], + Assert.Equal( + ["00000000000003_Three"], async ? await context.Database.GetPendingMigrationsAsync() : context.Database.GetPendingMigrations()); diff --git a/test/EFCore.Relational.Tests/Infrastructure/RelationalEventIdTest.cs b/test/EFCore.Relational.Tests/Infrastructure/RelationalEventIdTest.cs index fe1ee28da16..018a4e11014 100644 --- a/test/EFCore.Relational.Tests/Infrastructure/RelationalEventIdTest.cs +++ b/test/EFCore.Relational.Tests/Infrastructure/RelationalEventIdTest.cs @@ -6,7 +6,6 @@ using System.Transactions; using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; using Microsoft.EntityFrameworkCore.Metadata.Internal; -using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Query.SqlExpressions; using Microsoft.EntityFrameworkCore.TestUtilities.FakeProvider; using Index = Microsoft.EntityFrameworkCore.Metadata.Internal.Index; @@ -144,15 +143,6 @@ public string GenerateScript( MigrationsSqlGenerationOptions options = MigrationsSqlGenerationOptions.Default) => throw new NotImplementedException(); - public void Migrate(Action seed, string targetMigration, TimeSpan? lockTimeout) - => throw new NotImplementedException(); - - public Task MigrateAsync(Func seed, - string targetMigration, - TimeSpan? lockTimeout, - CancellationToken cancellationToken = default) - => throw new NotImplementedException(); - public bool HasPendingModelChanges() => throw new NotImplementedException(); } @@ -175,7 +165,8 @@ public string FindMigrationId(string nameOrId) => throw new NotImplementedException(); } - private class FakeMigrationCommand() : MigrationCommand(new FakeRelationalCommand(), null, new FakeRelationalCommandDiagnosticsLogger()); + private class FakeMigrationCommand() + : MigrationCommand(new FakeRelationalCommand(), null, new FakeRelationalCommandDiagnosticsLogger()); private class FakeRelationalCommand : IRelationalCommand { @@ -195,7 +186,9 @@ public Task ExecuteNonQueryAsync(RelationalCommandParameterObject parameter public RelationalDataReader ExecuteReader(RelationalCommandParameterObject parameterObject) => throw new NotImplementedException(); - public Task ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken) + public Task ExecuteReaderAsync( + RelationalCommandParameterObject parameterObject, + CancellationToken cancellationToken) => throw new NotImplementedException(); public object ExecuteScalar(RelationalCommandParameterObject parameterObject) diff --git a/test/EFCore.Relational.Tests/Infrastructure/RelationalModelValidatorTest.Json.cs b/test/EFCore.Relational.Tests/Infrastructure/RelationalModelValidatorTest.Json.cs index 203b04f5174..e5f660882f0 100644 --- a/test/EFCore.Relational.Tests/Infrastructure/RelationalModelValidatorTest.Json.cs +++ b/test/EFCore.Relational.Tests/Infrastructure/RelationalModelValidatorTest.Json.cs @@ -5,6 +5,50 @@ namespace Microsoft.EntityFrameworkCore.Infrastructure; public partial class RelationalModelValidatorTest { + [ConditionalFact] + public void Throw_when_non_json_entity_has_column_type_set() + { + var modelBuilder = CreateConventionModelBuilder(); + modelBuilder.Entity( + b => + { + b.OwnsOne( + x => x.OwnedReference, bb => + { + bb.HasColumnType("nvarchar(2000)"); + bb.Ignore(x => x.NestedCollection); + bb.Ignore(x => x.NestedReference); + }); + b.Ignore(x => x.OwnedCollection); + }); + + VerifyError( + RelationalStrings.ContainerTypeOnNonContainer(nameof(ValidatorJsonOwnedRoot)), + modelBuilder); + } + + [ConditionalFact] + public void Throw_when_non_root_json_entity_has_column_type_set() + { + var modelBuilder = CreateConventionModelBuilder(); + modelBuilder.Entity( + b => + { + b.OwnsOne( + x => x.OwnedReference, bb => + { + bb.ToJson(); + bb.Ignore(x => x.NestedCollection); + bb.OwnsOne(x => x.NestedReference, bbb => bbb.HasColumnType("nvarchar(2000)")); + }); + b.Ignore(x => x.OwnedCollection); + }); + + VerifyError( + RelationalStrings.ContainerTypeOnNestedOwnedEntityType(nameof(ValidatorJsonOwnedBranch)), + modelBuilder); + } + [ConditionalFact] public void Throw_when_non_json_entity_is_the_owner_of_json_entity_ref_ref() { @@ -347,7 +391,7 @@ public void Json_entity_with_explicit_ordinal_key_on_collection_throws() }); }); - VerifyError(RelationalStrings.JsonEntityWithExplicitlyConfiguredOrdinalKey("ValidatorJsonOwnedExplicitOrdinal"), modelBuilder); + VerifyError(RelationalStrings.JsonEntityWithExplicitlyConfiguredKey("ValidatorJsonOwnedExplicitOrdinal", "Ordinal"), modelBuilder); } [ConditionalFact] @@ -614,26 +658,26 @@ public void SeedData_on_entity_with_json_navigation_throws_meaningful_exception( modelBuilder); } - private class ValidatorJsonEntityBasic + protected class ValidatorJsonEntityBasic { public int Id { get; set; } public ValidatorJsonOwnedRoot OwnedReference { get; set; } public List OwnedCollection { get; set; } } - private abstract class ValidatorJsonEntityInheritanceAbstract : ValidatorJsonEntityInheritanceBase + protected abstract class ValidatorJsonEntityInheritanceAbstract : ValidatorJsonEntityInheritanceBase { public Guid Guid { get; set; } } - private class ValidatorJsonEntityInheritanceBase + protected class ValidatorJsonEntityInheritanceBase { public int Id { get; set; } public string Name { get; set; } public ValidatorJsonOwnedBranch ReferenceOnBase { get; set; } } - private class ValidatorJsonEntityInheritanceDerived : ValidatorJsonEntityInheritanceAbstract + protected class ValidatorJsonEntityInheritanceDerived : ValidatorJsonEntityInheritanceAbstract { public bool Switch { get; set; } @@ -642,7 +686,7 @@ private class ValidatorJsonEntityInheritanceDerived : ValidatorJsonEntityInherit public List CollectionOnDerived { get; set; } } - private class ValidatorJsonOwnedRoot + protected class ValidatorJsonOwnedRoot { public string Name { get; set; } public int Number { get; } @@ -651,12 +695,12 @@ private class ValidatorJsonOwnedRoot public List NestedCollection { get; } } - private class ValidatorJsonOwnedBranch + protected class ValidatorJsonOwnedBranch { public double Number { get; set; } } - private class ValidatorJsonEntityExplicitOrdinal + protected class ValidatorJsonEntityExplicitOrdinal { public int Id { get; set; } @@ -665,19 +709,19 @@ private class ValidatorJsonEntityExplicitOrdinal public List OwnedCollection { get; set; } } - private class ValidatorJsonOwnedExplicitOrdinal + protected class ValidatorJsonOwnedExplicitOrdinal { public int Ordinal { get; set; } public DateTime Date { get; set; } } - private class ValidatorJsonEntityJsonReferencingRegularEntity + protected class ValidatorJsonEntityJsonReferencingRegularEntity { public int Id { get; set; } public ValidatorJsonOwnedReferencingRegularEntity Owned { get; set; } } - private class ValidatorJsonOwnedReferencingRegularEntity + protected class ValidatorJsonOwnedReferencingRegularEntity { public string Foo { get; set; } @@ -685,13 +729,13 @@ private class ValidatorJsonOwnedReferencingRegularEntity public ValidatorJsonEntityReferencedEntity Reference { get; } } - private class ValidatorJsonEntityReferencedEntity + protected class ValidatorJsonEntityReferencedEntity { public int Id { get; set; } public DateTime Date { get; set; } } - private class ValidatorJsonEntitySideBySide + protected class ValidatorJsonEntitySideBySide { public int Id { get; set; } public string Name { get; set; } @@ -701,7 +745,7 @@ private class ValidatorJsonEntitySideBySide public List Collection2 { get; set; } } - private class ValidatorJsonEntityTableSplitting + protected class ValidatorJsonEntityTableSplitting { public int Id { get; set; } public ValidatorJsonEntityBasic Link { get; set; } diff --git a/test/EFCore.Relational.Tests/Infrastructure/RelationalModelValidatorTest.cs b/test/EFCore.Relational.Tests/Infrastructure/RelationalModelValidatorTest.cs index 5be11a5de3f..fa7f1afb8fb 100644 --- a/test/EFCore.Relational.Tests/Infrastructure/RelationalModelValidatorTest.cs +++ b/test/EFCore.Relational.Tests/Infrastructure/RelationalModelValidatorTest.cs @@ -2510,10 +2510,11 @@ public virtual void Detects_owned_view_sharing_on_abstract_class_with_TPT() modelBuilder.Entity() .UseTptMappingStrategy() - .OwnsOne(b => b.Details, ob => - { - ob.ToTable((string)null); - }); + .OwnsOne( + b => b.Details, ob => + { + ob.ToTable((string)null); + }); modelBuilder.Entity() .ToView("Animal"); @@ -3809,8 +3810,9 @@ public void Detects_trigger_on_TPH_non_root() modelBuilder.Entity(); modelBuilder.Entity().ToTable(tb => tb.HasTrigger("SomeTrigger")); - VerifyWarning(RelationalResources.LogTriggerOnNonRootTphEntity(new TestLogger()) - .GenerateMessage("Cat", "Animal"), modelBuilder); + VerifyWarning( + RelationalResources.LogTriggerOnNonRootTphEntity(new TestLogger()) + .GenerateMessage("Cat", "Animal"), modelBuilder); } private class TpcBase diff --git a/test/EFCore.Relational.Tests/Metadata/RelationalModelTest.cs b/test/EFCore.Relational.Tests/Metadata/RelationalModelTest.cs index dfd8f64e2fa..e037d461016 100644 --- a/test/EFCore.Relational.Tests/Metadata/RelationalModelTest.cs +++ b/test/EFCore.Relational.Tests/Metadata/RelationalModelTest.cs @@ -35,7 +35,8 @@ public void Both_design_and_runtime_RelationalModels_are_built_for_external_mode var designTimeModel = context.GetService().Model; var runtimeModel = context.Model; - Assert.NotSame(designTimeModel.FindRuntimeAnnotationValue(RelationalAnnotationNames.RelationalModelFactory), + Assert.NotSame( + designTimeModel.FindRuntimeAnnotationValue(RelationalAnnotationNames.RelationalModelFactory), runtimeModel.FindRuntimeAnnotationValue(RelationalAnnotationNames.RelationalModelFactory)); var designTimeRelationalModel = designTimeModel.GetRelationalModel(); @@ -1341,7 +1342,8 @@ private static void AssertSprocs(IRelationalModel model, Mapping mapping, bool m Assert.DoesNotContain(abstractCustomerType.GetInsertStoredProcedureMappings(), m => m.IncludesDerivedTypes != false); Assert.Equal( "SpecialCustomer_Insert", - specialCustomerType.GetInsertStoredProcedureMappings().Single(m => m.IncludesDerivedTypes == true).StoreStoredProcedure.Name); + specialCustomerType.GetInsertStoredProcedureMappings().Single(m => m.IncludesDerivedTypes == true).StoreStoredProcedure + .Name); Assert.Null(baseInsertSproc.Schema); Assert.Equal( new[] @@ -1379,7 +1381,8 @@ private static void AssertSprocs(IRelationalModel model, Mapping mapping, bool m Assert.DoesNotContain(abstractCustomerType.GetUpdateStoredProcedureMappings(), m => m.IncludesDerivedTypes != false); Assert.Equal( "SpecialCustomer_Update", - specialCustomerType.GetUpdateStoredProcedureMappings().Single(m => m.IncludesDerivedTypes == true).StoreStoredProcedure.Name); + specialCustomerType.GetUpdateStoredProcedureMappings().Single(m => m.IncludesDerivedTypes == true).StoreStoredProcedure + .Name); Assert.Null(baseUpdateSproc.Schema); Assert.Equal( @@ -1418,7 +1421,8 @@ private static void AssertSprocs(IRelationalModel model, Mapping mapping, bool m Assert.DoesNotContain(abstractCustomerType.GetDeleteStoredProcedureMappings(), m => m.IncludesDerivedTypes != false); Assert.Equal( "SpecialCustomer_Delete", - specialCustomerType.GetDeleteStoredProcedureMappings().Single(m => m.IncludesDerivedTypes == true).StoreStoredProcedure.Name); + specialCustomerType.GetDeleteStoredProcedureMappings().Single(m => m.IncludesDerivedTypes == true).StoreStoredProcedure + .Name); Assert.Null(baseDeleteSproc.Schema); Assert.Equal( @@ -3042,6 +3046,9 @@ public void Can_use_relational_model_with_SQL_queries() private static IQueryable GetOrdersForCustomer(int id) => throw new NotImplementedException(); + private static IQueryable GetOrdersForCustomer(string name) + => throw new NotImplementedException(); + [ConditionalFact] public void Can_use_relational_model_with_functions() { @@ -3060,41 +3067,50 @@ public void Can_use_relational_model_with_functions() modelBuilder.HasDbFunction( typeof(RelationalModelTest).GetMethod( - nameof(GetOrdersForCustomer), BindingFlags.NonPublic | BindingFlags.Static)); + nameof(GetOrdersForCustomer), BindingFlags.NonPublic | BindingFlags.Static, [typeof(int)] )); + + modelBuilder.HasDbFunction( + typeof(RelationalModelTest).GetMethod( + nameof(GetOrdersForCustomer), BindingFlags.NonPublic | BindingFlags.Static, [typeof(string)])); var model = Finalize(modelBuilder); Assert.Single(model.Model.GetEntityTypes()); - Assert.Equal(2, model.Functions.Count()); + Assert.Equal(3, model.Functions.Count()); Assert.Empty(model.Views); Assert.Empty(model.Tables); var orderType = model.Model.FindEntityType(typeof(Order)); Assert.Null(orderType.FindPrimaryKey()); - Assert.Equal(2, orderType.GetFunctionMappings().Count()); + Assert.Equal(3, orderType.GetFunctionMappings().Count()); var orderMapping = orderType.GetFunctionMappings().First(); Assert.Null(orderMapping.IsSharedTablePrincipal); Assert.Null(orderMapping.IsSplitEntityTypePrincipal); Assert.True(orderMapping.IsDefaultFunctionMapping); - var tvfMapping = orderType.GetFunctionMappings().Last(); + var tvfMapping = orderType.GetFunctionMappings().ElementAt(1); Assert.Null(tvfMapping.IsSharedTablePrincipal); Assert.Null(tvfMapping.IsSplitEntityTypePrincipal); Assert.False(tvfMapping.IsDefaultFunctionMapping); + var tvfMapping2 = orderType.GetFunctionMappings().Last(); + Assert.Null(tvfMapping2.IsSharedTablePrincipal); + Assert.Null(tvfMapping2.IsSplitEntityTypePrincipal); + Assert.False(tvfMapping2.IsDefaultFunctionMapping); + Assert.Null(orderMapping.IncludesDerivedTypes); Assert.Equal( - new[] { nameof(Order.AlternateId), nameof(Order.CustomerId), nameof(Order.Id), nameof(Order.OrderDate) }, + [nameof(Order.AlternateId), nameof(Order.CustomerId), nameof(Order.Id), nameof(Order.OrderDate)], orderMapping.ColumnMappings.Select(m => m.Property.Name)); var ordersFunction = orderMapping.StoreFunction; Assert.Same(ordersFunction, model.FindFunction(ordersFunction.Name, ordersFunction.Schema, [])); Assert.Equal( - new[] { orderType }, + [orderType], ordersFunction.EntityTypeMappings.Select(m => m.TypeBase)); Assert.Equal( - new[] { nameof(Order.CustomerId), nameof(Order.Id), nameof(Order.OrderDate), "SomeName" }, + [nameof(Order.CustomerId), nameof(Order.Id), nameof(Order.OrderDate), "SomeName"], ordersFunction.Columns.Select(m => m.Name)); Assert.Equal("GetOrders", ordersFunction.Name); Assert.Null(ordersFunction.Schema); @@ -3113,7 +3129,7 @@ public void Can_use_relational_model_with_functions() Assert.Same(orderDateColumn, ordersFunction.FindColumn(nameof(Order.OrderDate))); Assert.Same(orderDateColumn, orderDate.FindColumn(StoreObjectIdentifier.DbFunction(ordersFunction.Name))); Assert.Same(orderDateColumn, ordersFunction.FindColumn(orderDate)); - Assert.Equal(new[] { orderDate }, orderDateColumn.PropertyMappings.Select(m => m.Property)); + Assert.Equal([orderDate], orderDateColumn.PropertyMappings.Select(m => m.Property)); Assert.Equal(nameof(Order.OrderDate), orderDateColumn.Name); Assert.Equal("default_datetime_mapping", orderDateColumn.StoreType); Assert.False(orderDateColumn.IsNullable); @@ -3123,7 +3139,7 @@ public void Can_use_relational_model_with_functions() var tvfFunction = tvfMapping.StoreFunction; Assert.Same(tvfMapping, tvfFunction.EntityTypeMappings.Single()); - Assert.Same(tvfFunction, model.FindFunction(tvfFunction.Name, tvfFunction.Schema, new[] { "default_int_mapping" })); + Assert.Same(tvfFunction, model.FindFunction(tvfFunction.Name, tvfFunction.Schema, ["default_int_mapping"])); Assert.Equal(nameof(GetOrdersForCustomer), tvfFunction.Name); Assert.Null(tvfFunction.Schema); Assert.False(tvfFunction.IsBuiltIn); @@ -3132,9 +3148,24 @@ public void Can_use_relational_model_with_functions() var tvfDbFunction = tvfFunction.DbFunctions.Single(); Assert.Same(tvfFunction, tvfDbFunction.StoreFunction); - Assert.Same(model.Model.GetDbFunctions().Single(f => f.Parameters.Count() == 1), tvfDbFunction); + Assert.Same(model.Model.GetDbFunctions().First(f => f.Parameters.Count() == 1), tvfDbFunction); Assert.Same(tvfFunction.Parameters.Single(), tvfDbFunction.Parameters.Single().StoreFunctionParameter); Assert.Equal(tvfDbFunction.Parameters.Single().Name, tvfFunction.Parameters.Single().DbFunctionParameters.Single().Name); + + var tvfFunction2 = tvfMapping2.StoreFunction; + Assert.Same(tvfMapping2, tvfFunction2.EntityTypeMappings.Single()); + Assert.Same(tvfFunction2, model.FindFunction(tvfFunction2.Name, tvfFunction2.Schema, ["just_string(max)"])); + Assert.Equal(nameof(GetOrdersForCustomer), tvfFunction2.Name); + Assert.Null(tvfFunction2.Schema); + Assert.False(tvfFunction2.IsBuiltIn); + Assert.False(tvfFunction2.IsShared); + Assert.Null(tvfFunction2.ReturnType); + + var tvfDbFunction2 = tvfFunction2.DbFunctions.Single(); + Assert.Same(tvfFunction2, tvfDbFunction2.StoreFunction); + Assert.Same(model.Model.GetDbFunctions().Last(f => f.Parameters.Count() == 1), tvfDbFunction2); + Assert.Same(tvfFunction2.Parameters.Single(), tvfDbFunction2.Parameters.Single().StoreFunctionParameter); + Assert.Equal(tvfDbFunction2.Parameters.Single().Name, tvfFunction2.Parameters.Single().DbFunctionParameters.Single().Name); } [ConditionalFact] @@ -3224,6 +3255,7 @@ private class SpecialCustomer : AbstractCustomer private class CustomerDetails { public string Address { get; set; } + // ReSharper disable once UnusedAutoPropertyAccessor.Local public DateTime BirthDay { get; set; } } diff --git a/test/EFCore.Relational.Tests/Migrations/Internal/MigrationsModelDifferTest.cs b/test/EFCore.Relational.Tests/Migrations/Internal/MigrationsModelDifferTest.cs index c9e9a08882e..3c00a36a40b 100644 --- a/test/EFCore.Relational.Tests/Migrations/Internal/MigrationsModelDifferTest.cs +++ b/test/EFCore.Relational.Tests/Migrations/Internal/MigrationsModelDifferTest.cs @@ -8646,7 +8646,7 @@ public void Split_out_subtype_with_seed_data() x.Property("Name"); x.Property("Discriminator"); - x.HasDiscriminator("Discriminator") + x.HasDiscriminator() .HasValue(1) .HasValue(2); @@ -11142,9 +11142,7 @@ public Order() } public Order(int secretId) - { - _secretId = secretId; - } + => _secretId = secretId; public int Id { get; set; } @@ -11834,9 +11832,7 @@ public Blog() } private Blog(Action lazyLoader) - { - _loader = lazyLoader; - } + => _loader = lazyLoader; public int BlogId { get; set; } public string Url { get; set; } @@ -11858,9 +11854,7 @@ public Post() } private Post(ILazyLoader loader) - { - _loader = loader; - } + => _loader = loader; public int PostId { get; set; } public string Title { get; set; } diff --git a/test/EFCore.Relational.Tests/Migrations/MigrationCommandExecutorTest.cs b/test/EFCore.Relational.Tests/Migrations/MigrationCommandExecutorTest.cs index f428f1e65c9..f1ca15a4b7b 100644 --- a/test/EFCore.Relational.Tests/Migrations/MigrationCommandExecutorTest.cs +++ b/test/EFCore.Relational.Tests/Migrations/MigrationCommandExecutorTest.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.EntityFrameworkCore.Migrations.Internal; using Microsoft.EntityFrameworkCore.Storage.Internal; using Microsoft.EntityFrameworkCore.TestUtilities.FakeProvider; @@ -122,15 +121,17 @@ public async Task Executes_transaction_suppressed_migration_commands_in_user_tra { Assert.Equal( RelationalStrings.TransactionSuppressedMigrationInUserTransaction, - (await Assert.ThrowsAsync(async () - => await migrationCommandExecutor.ExecuteNonQueryAsync(commandList, fakeConnection))).Message); + (await Assert.ThrowsAsync( + async () + => await migrationCommandExecutor.ExecuteNonQueryAsync(commandList, fakeConnection))).Message); } else { Assert.Equal( RelationalStrings.TransactionSuppressedMigrationInUserTransaction, - Assert.Throws(() - => migrationCommandExecutor.ExecuteNonQuery(commandList, fakeConnection)).Message); + Assert.Throws( + () + => migrationCommandExecutor.ExecuteNonQuery(commandList, fakeConnection)).Message); } tx.Rollback(); @@ -355,13 +356,15 @@ public async Task Disposes_transaction_on_exception(bool async) if (async) { - await Assert.ThrowsAsync(async () - => await migrationCommandExecutor.ExecuteNonQueryAsync(commandList, fakeConnection)); + await Assert.ThrowsAsync( + async () + => await migrationCommandExecutor.ExecuteNonQueryAsync(commandList, fakeConnection)); } else { - Assert.Throws(() - => migrationCommandExecutor.ExecuteNonQuery(commandList, fakeConnection)); + Assert.Throws( + () + => migrationCommandExecutor.ExecuteNonQuery(commandList, fakeConnection)); } Assert.Equal(1, fakeDbConnection.OpenCount); diff --git a/test/EFCore.Relational.Tests/RelationalApiConsistencyTest.cs b/test/EFCore.Relational.Tests/RelationalApiConsistencyTest.cs index 15b0f1a4087..3916535c30d 100644 --- a/test/EFCore.Relational.Tests/RelationalApiConsistencyTest.cs +++ b/test/EFCore.Relational.Tests/RelationalApiConsistencyTest.cs @@ -7,7 +7,8 @@ namespace Microsoft.EntityFrameworkCore; -public class RelationalApiConsistencyTest(RelationalApiConsistencyTest.RelationalApiConsistencyFixture fixture) : ApiConsistencyTestBase(fixture) +public class RelationalApiConsistencyTest(RelationalApiConsistencyTest.RelationalApiConsistencyFixture fixture) + : ApiConsistencyTestBase(fixture) { protected override void AddServices(ServiceCollection serviceCollection) => new EntityFrameworkRelationalServicesBuilder(serviceCollection).TryAddCoreServices(); @@ -556,10 +557,11 @@ public class RelationalApiConsistencyFixture : ApiConsistencyFixtureBase nameof(IRelationalConnectionDiagnosticsLogger.ConnectionDisposedAsync)), // internal methods made public for AOT - typeof(ShaperProcessingExpressionVisitor).GetMethod(nameof(ShaperProcessingExpressionVisitor.PopulateSplitIncludeCollectionAsync)), + typeof(ShaperProcessingExpressionVisitor).GetMethod( + nameof(ShaperProcessingExpressionVisitor.PopulateSplitIncludeCollectionAsync)), typeof(ShaperProcessingExpressionVisitor).GetMethod(nameof(ShaperProcessingExpressionVisitor.PopulateSplitCollectionAsync)), typeof(ShaperProcessingExpressionVisitor).GetMethod(nameof(ShaperProcessingExpressionVisitor.TaskAwaiter)), - typeof(RelationalShapedQueryCompilingExpressionVisitor).GetMethod(nameof(RelationalShapedQueryCompilingExpressionVisitor.NonQueryResultAsync)), + typeof(RelationalShapedQueryCompilingExpressionVisitor).GetMethod(nameof(NonQueryResultAsync)), ]; public override HashSet MetadataMethodExceptions { get; } = @@ -576,9 +578,21 @@ public class RelationalApiConsistencyFixture : ApiConsistencyFixtureBase typeof(RelationalMaterializerLiftableConstantContext).GetMethod("set_RelationalDependencies"), typeof(RelationalMaterializerLiftableConstantContext).GetMethod("get_CommandBuilderDependencies"), typeof(RelationalMaterializerLiftableConstantContext).GetMethod("set_CommandBuilderDependencies"), - typeof(RelationalMaterializerLiftableConstantContext).GetMethod("Deconstruct", [typeof(ShapedQueryCompilingExpressionVisitorDependencies).MakeByRefType()]), - typeof(RelationalMaterializerLiftableConstantContext).GetMethod("Deconstruct", [typeof(ShapedQueryCompilingExpressionVisitorDependencies).MakeByRefType(), typeof(RelationalShapedQueryCompilingExpressionVisitorDependencies).MakeByRefType()]), - typeof(RelationalMaterializerLiftableConstantContext).GetMethod("Deconstruct", [typeof(ShapedQueryCompilingExpressionVisitorDependencies).MakeByRefType(), typeof(RelationalShapedQueryCompilingExpressionVisitorDependencies).MakeByRefType(), typeof(RelationalCommandBuilderDependencies).MakeByRefType()]), + typeof(RelationalMaterializerLiftableConstantContext).GetMethod( + "Deconstruct", [typeof(ShapedQueryCompilingExpressionVisitorDependencies).MakeByRefType()]), + typeof(RelationalMaterializerLiftableConstantContext).GetMethod( + "Deconstruct", + [ + typeof(ShapedQueryCompilingExpressionVisitorDependencies).MakeByRefType(), + typeof(RelationalShapedQueryCompilingExpressionVisitorDependencies).MakeByRefType() + ]), + typeof(RelationalMaterializerLiftableConstantContext).GetMethod( + "Deconstruct", + [ + typeof(ShapedQueryCompilingExpressionVisitorDependencies).MakeByRefType(), + typeof(RelationalShapedQueryCompilingExpressionVisitorDependencies).MakeByRefType(), + typeof(RelationalCommandBuilderDependencies).MakeByRefType() + ]), #pragma warning restore EF9100 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. ]; diff --git a/test/EFCore.Relational.Tests/RelationalConnectionTest.cs b/test/EFCore.Relational.Tests/RelationalConnectionTest.cs index e06bf17947a..2d26f147675 100644 --- a/test/EFCore.Relational.Tests/RelationalConnectionTest.cs +++ b/test/EFCore.Relational.Tests/RelationalConnectionTest.cs @@ -901,12 +901,10 @@ public void Can_create_new_connection_with_CommandTimeout_set_to_zero() [ConditionalFact] public void Throws_if_create_new_connection_with_CommandTimeout_negative() - { - Assert.Throws( + => Assert.Throws( () => new FakeRelationalOptionsExtension() .WithConnectionString("Database=FrodoLives") .WithCommandTimeout(-1)); - } [ConditionalFact] public void Can_set_CommandTimeout() diff --git a/test/EFCore.Relational.Tests/Storage/RelationalCommandTest.cs b/test/EFCore.Relational.Tests/Storage/RelationalCommandTest.cs index eec5503a85c..a751990e9fc 100644 --- a/test/EFCore.Relational.Tests/Storage/RelationalCommandTest.cs +++ b/test/EFCore.Relational.Tests/Storage/RelationalCommandTest.cs @@ -492,9 +492,9 @@ public async Task Throws_when_parameters_are_configured_and_parameter_values_is_ var relationalCommand = CreateRelationalCommand( parameters: new[] { - new TypeMappedRelationalParameter("FirstInvariant", "FirstParameter", new IntTypeMapping("int", DbType.Int32), false), + new TypeMappedRelationalParameter("FirstInvariant", "FirstParameter", new IntTypeMapping("int"), false), new TypeMappedRelationalParameter( - "SecondInvariant", "SecondParameter", new LongTypeMapping("long", DbType.Int64), true), + "SecondInvariant", "SecondParameter", new LongTypeMapping("long"), true), new TypeMappedRelationalParameter("ThirdInvariant", "ThirdParameter", RelationalTypeMapping.NullMapping, null) }); @@ -529,9 +529,9 @@ public async Task Throws_when_parameters_are_configured_and_value_is_missing( var relationalCommand = CreateRelationalCommand( parameters: new[] { - new TypeMappedRelationalParameter("FirstInvariant", "FirstParameter", new IntTypeMapping("int", DbType.Int32), false), + new TypeMappedRelationalParameter("FirstInvariant", "FirstParameter", new IntTypeMapping("int"), false), new TypeMappedRelationalParameter( - "SecondInvariant", "SecondParameter", new LongTypeMapping("long", DbType.Int64), true), + "SecondInvariant", "SecondParameter", new LongTypeMapping("long"), true), new TypeMappedRelationalParameter("ThirdInvariant", "ThirdParameter", RelationalTypeMapping.NullMapping, null) }); @@ -568,9 +568,9 @@ public async Task Configures_DbCommand_with_type_mapped_parameters( var relationalCommand = CreateRelationalCommand( parameters: new[] { - new TypeMappedRelationalParameter("FirstInvariant", "FirstParameter", new IntTypeMapping("int", DbType.Int32), false), + new TypeMappedRelationalParameter("FirstInvariant", "FirstParameter", new IntTypeMapping("int"), false), new TypeMappedRelationalParameter( - "SecondInvariant", "SecondParameter", new LongTypeMapping("long", DbType.Int64), true), + "SecondInvariant", "SecondParameter", new LongTypeMapping("long"), true), new TypeMappedRelationalParameter("ThirdInvariant", "ThirdParameter", RelationalTypeMapping.NullMapping, null) }); @@ -636,9 +636,9 @@ public async Task Configures_DbCommand_with_composite_parameters( new[] { new TypeMappedRelationalParameter( - "FirstInvariant", "FirstParameter", new IntTypeMapping("int", DbType.Int32), false), + "FirstInvariant", "FirstParameter", new IntTypeMapping("int"), false), new TypeMappedRelationalParameter( - "SecondInvariant", "SecondParameter", new LongTypeMapping("long", DbType.Int64), true), + "SecondInvariant", "SecondParameter", new LongTypeMapping("long"), true), new TypeMappedRelationalParameter("ThirdInvariant", "ThirdParameter", RelationalTypeMapping.NullMapping, null) }) }); @@ -700,9 +700,9 @@ public async Task Throws_when_composite_parameters_are_configured_and_value_is_m new[] { new TypeMappedRelationalParameter( - "FirstInvariant", "FirstParameter", new IntTypeMapping("int", DbType.Int32), false), + "FirstInvariant", "FirstParameter", new IntTypeMapping("int"), false), new TypeMappedRelationalParameter( - "SecondInvariant", "SecondParameter", new LongTypeMapping("long", DbType.Int64), true), + "SecondInvariant", "SecondParameter", new LongTypeMapping("long"), true), new TypeMappedRelationalParameter("ThirdInvariant", "ThirdParameter", RelationalTypeMapping.NullMapping, null) }) }); @@ -745,7 +745,7 @@ public async Task Throws_when_composite_parameters_are_configured_and_value_is_n new[] { new TypeMappedRelationalParameter( - "FirstInvariant", "FirstParameter", new IntTypeMapping("int", DbType.Int32), false) + "FirstInvariant", "FirstParameter", new IntTypeMapping("int"), false) }) }); @@ -996,7 +996,7 @@ public async Task Logs_commands_without_parameter_values( parameters: new[] { new TypeMappedRelationalParameter( - "FirstInvariant", "FirstParameter", new IntTypeMapping("int", DbType.Int32), false) + "FirstInvariant", "FirstParameter", new IntTypeMapping("int"), false) }); var parameterValues = new Dictionary { { "FirstInvariant", 17 } }; @@ -1054,7 +1054,7 @@ public async Task Logs_commands_parameter_values( parameters: new[] { new TypeMappedRelationalParameter( - "FirstInvariant", "FirstParameter", new IntTypeMapping("int", DbType.Int32), false) + "FirstInvariant", "FirstParameter", new IntTypeMapping("int"), false) }); var parameterValues = new Dictionary { { "FirstInvariant", 17 } }; @@ -1113,7 +1113,7 @@ public async Task Reports_command_diagnostic( parameters: new[] { new TypeMappedRelationalParameter( - "FirstInvariant", "FirstParameter", new IntTypeMapping("int", DbType.Int32), false) + "FirstInvariant", "FirstParameter", new IntTypeMapping("int"), false) }); var parameterValues = new Dictionary { { "FirstInvariant", 17 } }; @@ -1186,7 +1186,7 @@ public async Task Reports_command_diagnostic_on_exception( parameters: new[] { new TypeMappedRelationalParameter( - "FirstInvariant", "FirstParameter", new IntTypeMapping("int", DbType.Int32), false) + "FirstInvariant", "FirstParameter", new IntTypeMapping("int"), false) }); var parameterValues = new Dictionary { { "FirstInvariant", 17 } }; @@ -1265,7 +1265,7 @@ public async Task Reports_command_diagnostic_on_cancellation( parameters: new[] { new TypeMappedRelationalParameter( - "FirstInvariant", "FirstParameter", new IntTypeMapping("int", DbType.Int32), false) + "FirstInvariant", "FirstParameter", new IntTypeMapping("int"), false) }); var parameterValues = new Dictionary { { "FirstInvariant", 17 } }; diff --git a/test/EFCore.Relational.Tests/Storage/RelationalParameterBuilderTest.cs b/test/EFCore.Relational.Tests/Storage/RelationalParameterBuilderTest.cs index 47bdee99c40..8be3b7ba3a9 100644 --- a/test/EFCore.Relational.Tests/Storage/RelationalParameterBuilderTest.cs +++ b/test/EFCore.Relational.Tests/Storage/RelationalParameterBuilderTest.cs @@ -96,7 +96,7 @@ public void Can_add_composite_parameter() new TypeMappedRelationalParameter( "FirstInvariant", "FirstName", - new IntTypeMapping("int", DbType.Int32), + new IntTypeMapping("int"), nullable: false), new TypeMappedRelationalParameter( "SecondInvariant", diff --git a/test/EFCore.Relational.Tests/Storage/RelationalTypeMappingTest.cs b/test/EFCore.Relational.Tests/Storage/RelationalTypeMappingTest.cs index 2f24c151101..450d5eb092b 100644 --- a/test/EFCore.Relational.Tests/Storage/RelationalTypeMappingTest.cs +++ b/test/EFCore.Relational.Tests/Storage/RelationalTypeMappingTest.cs @@ -296,7 +296,7 @@ public void Can_create_simple_nullable_parameter() public void Can_create_simple_parameter_with_DbType() { using var command = CreateTestCommand(); - var parameter = new IntTypeMapping("int", DbType.Int32) + var parameter = new IntTypeMapping("int") .CreateParameter(command, "Name", 17, nullable: false); Assert.Equal(ParameterDirection.Input, parameter.Direction); @@ -310,7 +310,7 @@ public void Can_create_simple_parameter_with_DbType() public void Can_create_simple_nullable_parameter_with_DbType() { using var command = CreateTestCommand(); - var parameter = new IntTypeMapping("int", DbType.Int32) + var parameter = new IntTypeMapping("int") .CreateParameter(command, "Name", 17, nullable: true); Assert.Equal(ParameterDirection.Input, parameter.Direction); @@ -374,7 +374,7 @@ public virtual void ByteArray_literal_generated_correctly() [ConditionalFact] public virtual void Byte_literal_generated_correctly() { - var typeMapping = new ByteTypeMapping("byte", DbType.Byte); + var typeMapping = new ByteTypeMapping("byte"); Test_GenerateSqlLiteral_helper(typeMapping, byte.MinValue, "0"); Test_GenerateSqlLiteral_helper(typeMapping, byte.MaxValue, "255"); @@ -421,7 +421,7 @@ public virtual void TimeOnly_literal_generated_correctly() [ConditionalFact] public virtual void Decimal_literal_generated_correctly() { - var typeMapping = new DecimalTypeMapping("decimal", DbType.Decimal); + var typeMapping = new DecimalTypeMapping("decimal"); Test_GenerateSqlLiteral_helper(typeMapping, decimal.MinValue, "-79228162514264337593543950335.0"); Test_GenerateSqlLiteral_helper(typeMapping, decimal.MaxValue, "79228162514264337593543950335.0"); @@ -430,7 +430,7 @@ public virtual void Decimal_literal_generated_correctly() [ConditionalFact] public virtual void Double_literal_generated_correctly() { - var typeMapping = new DoubleTypeMapping("double", DbType.Double); + var typeMapping = new DoubleTypeMapping("double"); Test_GenerateSqlLiteral_helper(typeMapping, double.NaN, "NaN"); Test_GenerateSqlLiteral_helper(typeMapping, double.PositiveInfinity, "Infinity"); @@ -442,7 +442,7 @@ public virtual void Double_literal_generated_correctly() [ConditionalFact] public virtual void Float_literal_generated_correctly() { - var typeMapping = new FloatTypeMapping("float", DbType.Single); + var typeMapping = new FloatTypeMapping("float"); Test_GenerateSqlLiteral_helper(typeMapping, float.NaN, "NaN"); Test_GenerateSqlLiteral_helper(typeMapping, float.PositiveInfinity, "Infinity"); @@ -461,7 +461,7 @@ public virtual void Guid_literal_generated_correctly() [ConditionalFact] public virtual void NullableInt_literal_generated_correctly() { - var typeMapping = new IntTypeMapping("int?", DbType.Int32); + var typeMapping = new IntTypeMapping("int?"); Test_GenerateSqlLiteral_helper(typeMapping, default(int?), "NULL"); Test_GenerateSqlLiteral_helper(typeMapping, (int?)123, "123"); @@ -470,7 +470,7 @@ public virtual void NullableInt_literal_generated_correctly() [ConditionalFact] public virtual void Int_literal_generated_correctly() { - var typeMapping = new IntTypeMapping("int", DbType.Int32); + var typeMapping = new IntTypeMapping("int"); Test_GenerateSqlLiteral_helper(typeMapping, int.MinValue, "-2147483648"); Test_GenerateSqlLiteral_helper(typeMapping, int.MaxValue, "2147483647"); @@ -479,7 +479,7 @@ public virtual void Int_literal_generated_correctly() [ConditionalFact] public virtual void Long_literal_generated_correctly() { - var typeMapping = new LongTypeMapping("long", DbType.Int64); + var typeMapping = new LongTypeMapping("long"); Test_GenerateSqlLiteral_helper(typeMapping, long.MinValue, "-9223372036854775808"); Test_GenerateSqlLiteral_helper(typeMapping, long.MaxValue, "9223372036854775807"); @@ -488,7 +488,7 @@ public virtual void Long_literal_generated_correctly() [ConditionalFact] public virtual void SByte_literal_generated_correctly() { - var typeMapping = new SByteTypeMapping("sbyte", DbType.SByte); + var typeMapping = new SByteTypeMapping("sbyte"); Test_GenerateSqlLiteral_helper(typeMapping, sbyte.MinValue, "-128"); Test_GenerateSqlLiteral_helper(typeMapping, sbyte.MaxValue, "127"); @@ -497,7 +497,7 @@ public virtual void SByte_literal_generated_correctly() [ConditionalFact] public virtual void Short_literal_generated_correctly() { - var typeMapping = new ShortTypeMapping("short", DbType.Int16); + var typeMapping = new ShortTypeMapping("short"); Test_GenerateSqlLiteral_helper(typeMapping, short.MinValue, "-32768"); Test_GenerateSqlLiteral_helper(typeMapping, short.MaxValue, "32767"); @@ -514,7 +514,7 @@ public virtual void Timespan_literal_generated_correctly() [ConditionalFact] public virtual void UInt_literal_generated_correctly() { - var typeMapping = new UIntTypeMapping("uint", DbType.UInt32); + var typeMapping = new UIntTypeMapping("uint"); Test_GenerateSqlLiteral_helper(typeMapping, uint.MinValue, "0"); Test_GenerateSqlLiteral_helper(typeMapping, uint.MaxValue, "4294967295"); @@ -523,7 +523,7 @@ public virtual void UInt_literal_generated_correctly() [ConditionalFact] public virtual void ULong_literal_generated_correctly() { - var typeMapping = new ULongTypeMapping("ulong", DbType.UInt64); + var typeMapping = new ULongTypeMapping("ulong"); Test_GenerateSqlLiteral_helper(typeMapping, ulong.MinValue, "0"); Test_GenerateSqlLiteral_helper(typeMapping, ulong.MaxValue, "18446744073709551615"); @@ -532,7 +532,7 @@ public virtual void ULong_literal_generated_correctly() [ConditionalFact] public virtual void UShort_literal_generated_correctly() { - var typeMapping = new UShortTypeMapping("ushort", DbType.UInt16); + var typeMapping = new UShortTypeMapping("ushort"); Test_GenerateSqlLiteral_helper(typeMapping, ushort.MinValue, "0"); Test_GenerateSqlLiteral_helper(typeMapping, ushort.MaxValue, "65535"); @@ -541,7 +541,7 @@ public virtual void UShort_literal_generated_correctly() [ConditionalFact] public virtual void Double_value_comparer_handles_NaN() { - var typeMapping = new DoubleTypeMapping("double precision", DbType.Double); + var typeMapping = new DoubleTypeMapping("double precision"); Assert.True(typeMapping.Comparer.Equals(3.0, 3.0)); Assert.True(typeMapping.Comparer.Equals(double.NaN, double.NaN)); @@ -551,7 +551,7 @@ public virtual void Double_value_comparer_handles_NaN() [ConditionalFact] public virtual void Float_value_comparer_handles_NaN() { - var typeMapping = new FloatTypeMapping("float", DbType.Single); + var typeMapping = new FloatTypeMapping("float"); Assert.True(typeMapping.Comparer.Equals(3.0f, 3.0f)); Assert.True(typeMapping.Comparer.Equals(float.NaN, float.NaN)); @@ -561,7 +561,7 @@ public virtual void Float_value_comparer_handles_NaN() [ConditionalFact] public virtual void DateTimeOffset_value_comparer_behaves_correctly() { - var typeMapping = new DateTimeOffsetTypeMapping("datetimeoffset", DbType.DateTimeOffset); + var typeMapping = new DateTimeOffsetTypeMapping("datetimeoffset"); var same1 = new DateTimeOffset(2000, 1, 1, 12, 0, 0, TimeSpan.FromHours(0)); var same2 = new DateTimeOffset(2000, 1, 1, 12, 0, 0, TimeSpan.FromHours(0)); diff --git a/test/EFCore.Relational.Tests/TestUtilities/FakeProvider/FakeCommandExecutor.cs b/test/EFCore.Relational.Tests/TestUtilities/FakeProvider/FakeCommandExecutor.cs index 7a22cbea17c..f7ed5444156 100644 --- a/test/EFCore.Relational.Tests/TestUtilities/FakeProvider/FakeCommandExecutor.cs +++ b/test/EFCore.Relational.Tests/TestUtilities/FakeProvider/FakeCommandExecutor.cs @@ -14,17 +14,22 @@ public class FakeCommandExecutor( Func> executeReaderAsync = null) { private readonly Func _executeNonQuery = executeNonQuery - ?? (c => -1); + ?? (c => -1); + private readonly Func _executeScalar = executeScalar - ?? (c => null); + ?? (c => null); + private readonly Func _executeReader = executeReader - ?? ((c, b) => new FakeDbDataReader()); + ?? ((c, b) => new FakeDbDataReader()); + private readonly Func> _executeNonQueryAsync = executeNonQueryAsync - ?? ((c, ct) => Task.FromResult(-1)); + ?? ((c, ct) => Task.FromResult(-1)); + private readonly Func> _executeScalarAsync = executeScalarAsync - ?? ((c, ct) => Task.FromResult(null)); + ?? ((c, ct) => Task.FromResult(null)); + private readonly Func> _executeReaderAsync = executeReaderAsync - ?? ((c, ct, b) => Task.FromResult(new FakeDbDataReader())); + ?? ((c, ct, b) => Task.FromResult(new FakeDbDataReader())); public virtual int ExecuteNonQuery(FakeDbCommand command) => _executeNonQuery(command); diff --git a/test/EFCore.Relational.Tests/TestUtilities/FakeProvider/FakeRelationalConnection.cs b/test/EFCore.Relational.Tests/TestUtilities/FakeProvider/FakeRelationalConnection.cs index 482a090304a..98caf4177df 100644 --- a/test/EFCore.Relational.Tests/TestUtilities/FakeProvider/FakeRelationalConnection.cs +++ b/test/EFCore.Relational.Tests/TestUtilities/FakeProvider/FakeRelationalConnection.cs @@ -8,33 +8,33 @@ namespace Microsoft.EntityFrameworkCore.TestUtilities.FakeProvider; public class FakeRelationalConnection(IDbContextOptions options = null) : RelationalConnection( - new RelationalConnectionDependencies( - options ?? CreateOptions(), - new DiagnosticsLogger( - new LoggerFactory(), - new LoggingOptions(), - new DiagnosticListener("FakeDiagnosticListener"), - new TestRelationalLoggingDefinitions(), - new NullDbContextLogger()), - new RelationalConnectionDiagnosticsLogger( - new LoggerFactory(), - new LoggingOptions(), - new DiagnosticListener("FakeDiagnosticListener"), - new TestRelationalLoggingDefinitions(), - new NullDbContextLogger(), - CreateOptions()), - new NamedConnectionStringResolver(options ?? CreateOptions()), - new RelationalTransactionFactory( - new RelationalTransactionFactoryDependencies( - new RelationalSqlGenerationHelper( - new RelationalSqlGenerationHelperDependencies()))), - new CurrentDbContext(new FakeDbContext()), - new RelationalCommandBuilderFactory( - new RelationalCommandBuilderDependencies( - new TestRelationalTypeMappingSource( - TestServiceFactory.Instance.Create(), - TestServiceFactory.Instance.Create()), - new ExceptionDetector())))) + new RelationalConnectionDependencies( + options ?? CreateOptions(), + new DiagnosticsLogger( + new LoggerFactory(), + new LoggingOptions(), + new DiagnosticListener("FakeDiagnosticListener"), + new TestRelationalLoggingDefinitions(), + new NullDbContextLogger()), + new RelationalConnectionDiagnosticsLogger( + new LoggerFactory(), + new LoggingOptions(), + new DiagnosticListener("FakeDiagnosticListener"), + new TestRelationalLoggingDefinitions(), + new NullDbContextLogger(), + CreateOptions()), + new NamedConnectionStringResolver(options ?? CreateOptions()), + new RelationalTransactionFactory( + new RelationalTransactionFactoryDependencies( + new RelationalSqlGenerationHelper( + new RelationalSqlGenerationHelperDependencies()))), + new CurrentDbContext(new FakeDbContext()), + new RelationalCommandBuilderFactory( + new RelationalCommandBuilderDependencies( + new TestRelationalTypeMappingSource( + TestServiceFactory.Instance.Create(), + TestServiceFactory.Instance.Create()), + new ExceptionDetector())))) { private DbConnection _connection; diff --git a/test/EFCore.Relational.Tests/TestUtilities/FakeRelationalTestHelpers.cs b/test/EFCore.Relational.Tests/TestUtilities/FakeRelationalTestHelpers.cs index 8f1b2ec34a2..56314269ea4 100644 --- a/test/EFCore.Relational.Tests/TestUtilities/FakeRelationalTestHelpers.cs +++ b/test/EFCore.Relational.Tests/TestUtilities/FakeRelationalTestHelpers.cs @@ -25,5 +25,6 @@ public override DbContextOptionsBuilder UseProviderOptions(DbContextOptionsBuild public override LoggingDefinitions LoggingDefinitions { get; } = new TestRelationalLoggingDefinitions(); - public override ModelAsserter ModelAsserter => RelationalModelAsserter.Instance; + public override ModelAsserter ModelAsserter + => RelationalModelAsserter.Instance; } diff --git a/test/EFCore.Relational.Tests/TestUtilities/TestRelationalConventionSetBuilder.cs b/test/EFCore.Relational.Tests/TestUtilities/TestRelationalConventionSetBuilder.cs index de75c775256..11916686c0a 100644 --- a/test/EFCore.Relational.Tests/TestUtilities/TestRelationalConventionSetBuilder.cs +++ b/test/EFCore.Relational.Tests/TestUtilities/TestRelationalConventionSetBuilder.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore.TestUtilities; public class TestRelationalConventionSetBuilder( ProviderConventionSetBuilderDependencies dependencies, - RelationalConventionSetBuilderDependencies relationalDependencies) : RelationalConventionSetBuilder(dependencies, relationalDependencies) + RelationalConventionSetBuilderDependencies relationalDependencies) + : RelationalConventionSetBuilder(dependencies, relationalDependencies) { public static ConventionSet Build() => ConventionSet.CreateConventionSet(FakeRelationalTestHelpers.Instance.CreateContext()); diff --git a/test/EFCore.Relational.Tests/TestUtilities/TestRelationalTypeMappingSource.cs b/test/EFCore.Relational.Tests/TestUtilities/TestRelationalTypeMappingSource.cs index 3db839763b7..b200bc67402 100644 --- a/test/EFCore.Relational.Tests/TestUtilities/TestRelationalTypeMappingSource.cs +++ b/test/EFCore.Relational.Tests/TestUtilities/TestRelationalTypeMappingSource.cs @@ -124,14 +124,14 @@ private class TestStringTypeMapping( bool unicode = false, int? size = null, bool fixedLength = false) : StringTypeMapping( - new RelationalTypeMappingParameters( - new CoreTypeMappingParameters(typeof(string)), - storeType, - StoreTypePostfix.None, - dbType, - unicode, - size, - fixedLength)) + new RelationalTypeMappingParameters( + new CoreTypeMappingParameters(typeof(string)), + storeType, + StoreTypePostfix.None, + dbType, + unicode, + size, + fixedLength)) { protected override string ProcessStoreType( RelationalTypeMappingParameters parameters, diff --git a/test/EFCore.Specification.Tests/ApiConsistencyTestBase.cs b/test/EFCore.Specification.Tests/ApiConsistencyTestBase.cs index 28576155f1c..531aaeccc5f 100644 --- a/test/EFCore.Specification.Tests/ApiConsistencyTestBase.cs +++ b/test/EFCore.Specification.Tests/ApiConsistencyTestBase.cs @@ -579,32 +579,45 @@ private string ValidateConventionBuilderMethods(IReadOnlyList method var expectedName = methodName.StartsWith("HasNo", StringComparison.Ordinal) ? "CanRemove" + methodName[5..] - : methodName.StartsWith("Ignore", StringComparison.Ordinal) - ? methodName - : "CanSet" - + (methodName.StartsWith("Has", StringComparison.Ordinal) - || methodName.StartsWith("Use", StringComparison.Ordinal) - ? methodName[3..] - : methodName.StartsWith("To", StringComparison.Ordinal) - ? methodName[2..] - : methodName.StartsWith("With", StringComparison.Ordinal) - ? methodName[4..] - : methodName); + : "CanSet" + + (methodName.StartsWith("Has", StringComparison.Ordinal) + || methodName.StartsWith("Use", StringComparison.Ordinal) + ? methodName[3..] + : methodName.StartsWith("To", StringComparison.Ordinal) + ? methodName[2..] + : methodName.StartsWith("With", StringComparison.Ordinal) + ? methodName[4..] + : methodName); if (!methodLookup.TryGetValue(expectedName, out var canSetMethod)) { + if (methodName.StartsWith("HasNo", StringComparison.Ordinal) + || methodName.StartsWith("To", StringComparison.Ordinal) + || methodName.StartsWith("With", StringComparison.Ordinal)) + { + return $"{declaringType.Name} expected to have a {expectedName} method"; + } + + var otherExpectedName = "Can" + methodName; if (methodName.StartsWith("Has", StringComparison.Ordinal)) { - var otherExpectedName = "CanHave" + methodName[3..]; - if (!methodLookup.TryGetValue(otherExpectedName, out canSetMethod)) - { - return $"{declaringType.Name} expected to have a {expectedName} or {otherExpectedName} method"; - } + otherExpectedName = "CanHave" + methodName[3..]; } - else + else if (methodName.StartsWith("HasNo", StringComparison.Ordinal)) { - return $"{declaringType.Name} expected to have a {expectedName} method"; + otherExpectedName = "CanHaveNo" + methodName[3..]; } + + if (!methodLookup.TryGetValue(otherExpectedName, out canSetMethod)) + { + return $"{declaringType.Name} expected to have a {expectedName} or {otherExpectedName} method"; + } + } + + if (canSetMethod.ReturnType != typeof(bool)) + { + return $"{declaringType.Name}.{canSetMethod.Name}({Format(canSetMethod.GetParameters())})" + + $" expected to have return type of 'bool'"; } var parameterIndex = method.IsStatic ? 1 : 0; @@ -1232,9 +1245,7 @@ public int GetHashCode(Type obj) public abstract class ApiConsistencyFixtureBase { protected ApiConsistencyFixtureBase() - { - Initialize(); - } + => Initialize(); public virtual HashSet FluentApiTypes { get; } = []; @@ -1271,25 +1282,26 @@ protected ApiConsistencyFixtureBase() public virtual Dictionary> UnmatchedMirrorMethods { get; } = new(); public virtual Dictionary MetadataMethodNameTransformers { get; } = new(); public virtual HashSet MetadataMethodExceptions { get; } = []; + public virtual HashSet VirtualMethodExceptions { get; } = - [ + [ // un-sealed record #pragma warning disable EF9100 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. typeof(MaterializerLiftableConstantContext).GetMethod("get_Dependencies"), typeof(MaterializerLiftableConstantContext).GetMethod("set_Dependencies"), typeof(MaterializerLiftableConstantContext).GetMethod("Deconstruct"), #pragma warning restore EF9100 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. - ]; + ]; public virtual HashSet ComputedDependencyProperties { get; } = - [ - typeof(ProviderConventionSetBuilderDependencies).GetProperty( - nameof(ProviderConventionSetBuilderDependencies.ContextType)), - typeof(QueryCompilationContextDependencies).GetProperty(nameof(QueryCompilationContextDependencies.ContextType)), - typeof(QueryCompilationContextDependencies).GetProperty( - nameof(QueryCompilationContextDependencies.QueryTrackingBehavior)), - typeof(QueryContextDependencies).GetProperty(nameof(QueryContextDependencies.StateManager)) - ]; + [ + typeof(ProviderConventionSetBuilderDependencies).GetProperty( + nameof(ProviderConventionSetBuilderDependencies.ContextType)), + typeof(QueryCompilationContextDependencies).GetProperty(nameof(QueryCompilationContextDependencies.ContextType)), + typeof(QueryCompilationContextDependencies).GetProperty( + nameof(QueryCompilationContextDependencies.QueryTrackingBehavior)), + typeof(QueryContextDependencies).GetProperty(nameof(QueryContextDependencies.StateManager)) + ]; public Dictionary MetadataTypes { get; } = new() @@ -1427,7 +1439,8 @@ protected static MethodInfo GetMethod( string name, int genericParameterCount, Func parameterGenerator) - => type.GetGenericMethod(name, + => type.GetGenericMethod( + name, genericParameterCount, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly, parameterGenerator); diff --git a/test/EFCore.Specification.Tests/BadDataJsonDeserializationTestBase.cs b/test/EFCore.Specification.Tests/BadDataJsonDeserializationTestBase.cs index bda389f7d88..5389827a391 100644 --- a/test/EFCore.Specification.Tests/BadDataJsonDeserializationTestBase.cs +++ b/test/EFCore.Specification.Tests/BadDataJsonDeserializationTestBase.cs @@ -165,9 +165,9 @@ protected virtual void Throws_for_bad_JSON_value( } protected class SingleTypeDbContext( - Action buildOptions, - Action buildModel, - Action? configureConventions = null) + Action buildOptions, + Action buildModel, + Action? configureConventions = null) : DbContext { protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) diff --git a/test/EFCore.Specification.Tests/BuiltInDataTypesTestBase.cs b/test/EFCore.Specification.Tests/BuiltInDataTypesTestBase.cs index 9387b221d41..ada9f374292 100644 --- a/test/EFCore.Specification.Tests/BuiltInDataTypesTestBase.cs +++ b/test/EFCore.Specification.Tests/BuiltInDataTypesTestBase.cs @@ -2341,39 +2341,41 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con eb.HasData( new sbyte[] { -10, -7, -4, -3, -2, -1, 0, 1, 2, 3, 8, 15 } - .Select((x, i) => - new BuiltInDataTypes - { - Id = 17 + i, - PartitionId = 2, - TestInt16 = x, - TestInt32 = x, - TestInt64 = x, - TestDouble = x * 0.25, - TestDecimal = x * 0.2M, - TestDateTime = DateTime.Parse("01/01/2000 12:34:56"), - TestDateTimeOffset = new DateTimeOffset(DateTime.Parse("01/01/2000 12:34:56"), TimeSpan.FromHours(-8.0)), - TestTimeSpan = new TimeSpan(0, 10, 9, 8, 7), - TestDateOnly = new DateOnly(2020, 3, 1), - TestTimeOnly = new TimeOnly(12, 30, 45, 123), - TestSingle = x * 0.25F, - TestBoolean = x > 0, - TestByte = (byte)(10 + x), - TestUnsignedInt16 = (byte)(10 + x), - TestUnsignedInt32 = (byte)(10 + x), - TestUnsignedInt64 = (byte)(10 + x), - TestCharacter = 'a', - TestSignedByte = x, - Enum64 = Enum64.SomeValue, - Enum32 = Enum32.SomeValue, - Enum16 = Enum16.SomeValue, - Enum8 = Enum8.SomeValue, - EnumU64 = EnumU64.SomeValue, - EnumU32 = EnumU32.SomeValue, - EnumU16 = EnumU16.SomeValue, - EnumS8 = EnumS8.SomeValue - } - ) + .Select( + (x, i) => + new BuiltInDataTypes + { + Id = 17 + i, + PartitionId = 2, + TestInt16 = x, + TestInt32 = x, + TestInt64 = x, + TestDouble = x * 0.25, + TestDecimal = x * 0.2M, + TestDateTime = DateTime.Parse("01/01/2000 12:34:56"), + TestDateTimeOffset = + new DateTimeOffset(DateTime.Parse("01/01/2000 12:34:56"), TimeSpan.FromHours(-8.0)), + TestTimeSpan = new TimeSpan(0, 10, 9, 8, 7), + TestDateOnly = new DateOnly(2020, 3, 1), + TestTimeOnly = new TimeOnly(12, 30, 45, 123), + TestSingle = x * 0.25F, + TestBoolean = x > 0, + TestByte = (byte)(10 + x), + TestUnsignedInt16 = (byte)(10 + x), + TestUnsignedInt32 = (byte)(10 + x), + TestUnsignedInt64 = (byte)(10 + x), + TestCharacter = 'a', + TestSignedByte = x, + Enum64 = Enum64.SomeValue, + Enum32 = Enum32.SomeValue, + Enum16 = Enum16.SomeValue, + Enum8 = Enum8.SomeValue, + EnumU64 = EnumU64.SomeValue, + EnumU32 = EnumU32.SomeValue, + EnumU16 = EnumU16.SomeValue, + EnumS8 = EnumS8.SomeValue + } + ) ); eb.Property(e => e.Id).ValueGeneratedNever(); @@ -2416,38 +2418,39 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con eb.HasData( new sbyte?[] { null, -10, -7, -4, -3, -2, -1, 0, 1, 2, 3, 8, 15 } - .Select((x, i) => - new BuiltInNullableDataTypes - { - Id = 17 + i, - PartitionId = 2, - TestNullableInt16 = x, - TestNullableInt32 = x, - TestNullableInt64 = x, - TestNullableDouble = x * 0.25, - TestNullableDecimal = x * 0.2M, - TestNullableDateTimeOffset = new DateTimeOffset(new DateTime(), TimeSpan.FromHours(-8.0)), - TestNullableTimeSpan = new TimeSpan(0, 10, 9, 8, 7), - TestNullableDateOnly = new DateOnly(2020, 3, 1), - TestNullableTimeOnly = new TimeOnly(12, 30, 45, 123), - TestNullableSingle = x * 0.25F, - TestNullableBoolean = x == null ? null : x > 0, - TestNullableByte = (byte?)(10 + x), - TestNullableUnsignedInt16 = (byte?)(10 + x), - TestNullableUnsignedInt32 = (byte?)(10 + x), - TestNullableUnsignedInt64 = (byte?)(10 + x), - TestNullableCharacter = 'a', - TestNullableSignedByte = x, - Enum64 = Enum64.SomeValue, - Enum32 = Enum32.SomeValue, - Enum16 = Enum16.SomeValue, - Enum8 = Enum8.SomeValue, - EnumU64 = EnumU64.SomeValue, - EnumU32 = EnumU32.SomeValue, - EnumU16 = EnumU16.SomeValue, - EnumS8 = EnumS8.SomeValue - } - ) + .Select( + (x, i) => + new BuiltInNullableDataTypes + { + Id = 17 + i, + PartitionId = 2, + TestNullableInt16 = x, + TestNullableInt32 = x, + TestNullableInt64 = x, + TestNullableDouble = x * 0.25, + TestNullableDecimal = x * 0.2M, + TestNullableDateTimeOffset = new DateTimeOffset(new DateTime(), TimeSpan.FromHours(-8.0)), + TestNullableTimeSpan = new TimeSpan(0, 10, 9, 8, 7), + TestNullableDateOnly = new DateOnly(2020, 3, 1), + TestNullableTimeOnly = new TimeOnly(12, 30, 45, 123), + TestNullableSingle = x * 0.25F, + TestNullableBoolean = x == null ? null : x > 0, + TestNullableByte = (byte?)(10 + x), + TestNullableUnsignedInt16 = (byte?)(10 + x), + TestNullableUnsignedInt32 = (byte?)(10 + x), + TestNullableUnsignedInt64 = (byte?)(10 + x), + TestNullableCharacter = 'a', + TestNullableSignedByte = x, + Enum64 = Enum64.SomeValue, + Enum32 = Enum32.SomeValue, + Enum16 = Enum16.SomeValue, + Enum8 = Enum8.SomeValue, + EnumU64 = EnumU64.SomeValue, + EnumU32 = EnumU32.SomeValue, + EnumU16 = EnumU16.SomeValue, + EnumS8 = EnumS8.SomeValue + } + ) ); eb.Property(e => e.Id).ValueGeneratedNever(); diff --git a/test/EFCore.Specification.Tests/BulkUpdates/ComplexTypeBulkUpdatesTestBase.cs b/test/EFCore.Specification.Tests/BulkUpdates/ComplexTypeBulkUpdatesTestBase.cs index 9c5224e2fa6..763af7947b9 100644 --- a/test/EFCore.Specification.Tests/BulkUpdates/ComplexTypeBulkUpdatesTestBase.cs +++ b/test/EFCore.Specification.Tests/BulkUpdates/ComplexTypeBulkUpdatesTestBase.cs @@ -106,11 +106,7 @@ public virtual Task Update_complex_type_to_parameter(bool async) AddressLine1 = "New AddressLine1", AddressLine2 = "New AddressLine2", ZipCode = 99999, - Country = new() - { - Code = "FR", - FullName = "France" - }, + Country = new Country { Code = "FR", FullName = "France" }, Tags = new List { "new_tag1", "new_tag2" } }; @@ -126,11 +122,7 @@ public virtual Task Update_complex_type_to_parameter(bool async) [MemberData(nameof(IsAsyncData))] public virtual Task Update_nested_complex_type_to_parameter(bool async) { - var newCountry = new Country - { - Code = "FR", - FullName = "France" - }; + var newCountry = new Country { Code = "FR", FullName = "France" }; return AssertUpdate( async, @@ -157,18 +149,15 @@ public virtual Task Update_complex_type_to_inline_without_lambda(bool async) async, ss => ss.Set(), c => c, - s => s.SetProperty(x => x.ShippingAddress, new Address - { - AddressLine1 = "New AddressLine1", - AddressLine2 = "New AddressLine2", - ZipCode = 99999, - Country = new() + s => s.SetProperty( + x => x.ShippingAddress, new Address { - Code = "FR", - FullName = "France" - }, - Tags = new List { "new_tag1", "new_tag2" } - }), + AddressLine1 = "New AddressLine1", + AddressLine2 = "New AddressLine2", + ZipCode = 99999, + Country = new Country { Code = "FR", FullName = "France" }, + Tags = new List { "new_tag1", "new_tag2" } + }), rowsAffectedCount: 3); [ConditionalTheory] @@ -178,18 +167,15 @@ public virtual Task Update_complex_type_to_inline_with_lambda(bool async) async, ss => ss.Set(), c => c, - s => s.SetProperty(x => x.ShippingAddress, x => new Address - { - AddressLine1 = "New AddressLine1", - AddressLine2 = "New AddressLine2", - ZipCode = 99999, - Country = new() + s => s.SetProperty( + x => x.ShippingAddress, x => new Address { - Code = "FR", - FullName = "France" - }, - Tags = new List { "new_tag1", "new_tag2" } - }), + AddressLine1 = "New AddressLine1", + AddressLine2 = "New AddressLine2", + ZipCode = 99999, + Country = new Country { Code = "FR", FullName = "France" }, + Tags = new List { "new_tag1", "new_tag2" } + }), rowsAffectedCount: 3); [ConditionalTheory] diff --git a/test/EFCore.Specification.Tests/BulkUpdates/InheritanceBulkUpdatesTestBase.cs b/test/EFCore.Specification.Tests/BulkUpdates/InheritanceBulkUpdatesTestBase.cs index 195b23bd23e..d020ebb7c58 100644 --- a/test/EFCore.Specification.Tests/BulkUpdates/InheritanceBulkUpdatesTestBase.cs +++ b/test/EFCore.Specification.Tests/BulkUpdates/InheritanceBulkUpdatesTestBase.cs @@ -185,4 +185,5 @@ public virtual Task Update_with_interface_in_EF_Property_in_property_expression( e => e, // ReSharper disable once RedundantCast s => s.SetProperty(c => EF.Property((ISugary)c, nameof(ISugary.SugarGrams)), 0), - rowsAffectedCount: 1);} + rowsAffectedCount: 1); +} diff --git a/test/EFCore.Specification.Tests/BulkUpdates/NonSharedModelBulkUpdatesTestBase.cs b/test/EFCore.Specification.Tests/BulkUpdates/NonSharedModelBulkUpdatesTestBase.cs index c5cca8e6334..21099591a5f 100644 --- a/test/EFCore.Specification.Tests/BulkUpdates/NonSharedModelBulkUpdatesTestBase.cs +++ b/test/EFCore.Specification.Tests/BulkUpdates/NonSharedModelBulkUpdatesTestBase.cs @@ -296,8 +296,6 @@ public class Post public virtual Blog Blog { get; set; } } -#nullable disable - #region HelperMethods public Task AssertDelete( diff --git a/test/EFCore.Specification.Tests/ComplexTypesTrackingTestBase.cs b/test/EFCore.Specification.Tests/ComplexTypesTrackingTestBase.cs index 0e855cc7871..c7c372ee85d 100644 --- a/test/EFCore.Specification.Tests/ComplexTypesTrackingTestBase.cs +++ b/test/EFCore.Specification.Tests/ComplexTypesTrackingTestBase.cs @@ -997,8 +997,9 @@ protected void AssertPropertiesModified(EntityEntry entry, bool expected) protected static EntityEntry TrackFromQuery(DbContext context, TEntity pub) where TEntity : class - => new(context.GetService().StartTrackingFromQuery( - context.Model.FindEntityType(typeof(TEntity))!, pub, Snapshot.Empty)); + => new( + context.GetService().StartTrackingFromQuery( + context.Model.FindEntityType(typeof(TEntity))!, pub, Snapshot.Empty)); protected virtual Task ExecuteWithStrategyInTransactionAsync( Func testOperation, diff --git a/test/EFCore.Specification.Tests/CustomConvertersTestBase.cs b/test/EFCore.Specification.Tests/CustomConvertersTestBase.cs index d06679043d2..5dffaf88d9a 100644 --- a/test/EFCore.Specification.Tests/CustomConvertersTestBase.cs +++ b/test/EFCore.Specification.Tests/CustomConvertersTestBase.cs @@ -179,7 +179,6 @@ public virtual async Task Can_query_and_update_with_conversion_for_custom_type() protected class User(Email email) { - // ReSharper disable once AutoPropertyCanBeMadeGetOnly.Local public Guid Id { get; private set; } = Guid.NewGuid(); @@ -192,9 +191,7 @@ protected class Email private readonly string _value; private Email(string value) - { - _value = value; - } + => _value = value; public override bool Equals(object obj) => _value == ((Email)obj)?._value; @@ -344,9 +341,7 @@ public class Order public struct OrderId { private OrderId(string stringValue) - { - StringValue = stringValue; - } + => StringValue = stringValue; public string StringValue { get; } 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/F1FixtureBase.cs b/test/EFCore.Specification.Tests/F1FixtureBase.cs index 0daf63bb51f..cf5f697c7ed 100644 --- a/test/EFCore.Specification.Tests/F1FixtureBase.cs +++ b/test/EFCore.Specification.Tests/F1FixtureBase.cs @@ -17,9 +17,37 @@ protected override bool UsePooling public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) => base.AddOptions(builder) .UseModel(CreateModelExternal()) + .UseSeeding( + (c, _) => + { + if (!ShouldSeed((F1Context)c)) + { + return; + } + + F1Context.AddSeedData((F1Context)c); + c.SaveChanges(); + }) + .UseAsyncSeeding( + async (c, _, t) => + { + if (!await ShouldSeedAsync((F1Context)c)) + { + return; + } + + F1Context.AddSeedData((F1Context)c); + await c.SaveChangesAsync(t); + }) .ConfigureWarnings( w => w.Ignore(CoreEventId.SaveChangesStarting, CoreEventId.SaveChangesCompleted)); + protected virtual bool ShouldSeed(F1Context context) + => context.EngineSuppliers.Count() == 0; + + protected virtual async Task ShouldSeedAsync(F1Context context) + => await context.EngineSuppliers.CountAsync() == 0; + protected override IServiceCollection AddServices(IServiceCollection serviceCollection) => base.AddServices(serviceCollection.AddSingleton()); @@ -248,7 +276,4 @@ private static void ConfigureConstructorBinding( parameterBindings ); } - - protected override Task SeedAsync(F1Context context) - => F1Context.SeedAsync(context); } diff --git a/test/EFCore.Specification.Tests/FindTestBase.cs b/test/EFCore.Specification.Tests/FindTestBase.cs index 3618da38e09..d12e516facd 100644 --- a/test/EFCore.Specification.Tests/FindTestBase.cs +++ b/test/EFCore.Specification.Tests/FindTestBase.cs @@ -1,11 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable disable + using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -#nullable disable - // ReSharper disable InconsistentNaming namespace Microsoft.EntityFrameworkCore { @@ -817,13 +817,13 @@ protected override Task SeedAsync(PoolableDbContext context) { Id = 77, Foo = "Smokey", - OwnedReference = new() + OwnedReference = new Owned1 { Prop = 7, - NestedOwned = new() { Prop = "7" }, - NestedOwnedCollection = new() { new() { Prop = "71" }, new() { Prop = "72" } } + NestedOwned = new Owned2 { Prop = "7" }, + NestedOwnedCollection = new List { new() { Prop = "71" }, new() { Prop = "72" } } }, - OwnedCollection = new() { new() { Prop = 71 }, new() { Prop = 72 } } + OwnedCollection = new List { new Owned1 { Prop = 71 }, new Owned1 { Prop = 72 } } }, new NullableIntKey { Id = 77, Foo = "Smokey" }, new StringKey { Id = "Cat", Foo = "Alice" }, diff --git a/test/EFCore.Specification.Tests/GraphUpdates/GraphUpdatesTestBase.cs b/test/EFCore.Specification.Tests/GraphUpdates/GraphUpdatesTestBase.cs index ec390202571..83ed6b1d7f0 100644 --- a/test/EFCore.Specification.Tests/GraphUpdates/GraphUpdatesTestBase.cs +++ b/test/EFCore.Specification.Tests/GraphUpdates/GraphUpdatesTestBase.cs @@ -898,15 +898,23 @@ protected virtual IQueryable ModifyQueryRoot(IQueryable query) protected virtual OwnerRoot CreateOwnerRoot() => new() { - OptionalSingle = new() { Name = "OS", Single = new() { Name = "OS2" } }, - RequiredSingle = new() { Name = "RS", Single = new() { Name = "RS2 " } }, + OptionalSingle = new OwnedOptionalSingle1 { Name = "OS", Single = new OwnedOptionalSingle2 { Name = "OS2" } }, + RequiredSingle = new OwnedRequiredSingle1 { Name = "RS", Single = new OwnedRequiredSingle2 { Name = "RS2 " } }, OptionalChildren = { - new() { Name = "OC1" }, new() { Name = "OC2", Children = { new() { Name = "OCC1" }, new() { Name = "OCC2" } } } + new OwnedOptional1 { Name = "OC1" }, + new OwnedOptional1 + { + Name = "OC2", Children = { new OwnedOptional2 { Name = "OCC1" }, new OwnedOptional2 { Name = "OCC2" } } + } }, RequiredChildren = { - new() { Name = "RC1", Children = { new() { Name = "RCC1" }, new() { Name = "RCC2" } } }, new() { Name = "RC2" } + new OwnedRequired1 + { + Name = "RC1", Children = { new OwnedRequired2 { Name = "RCC1" }, new OwnedRequired2 { Name = "RCC2" } } + }, + new OwnedRequired1 { Name = "RC2" } } }; diff --git a/test/EFCore.Specification.Tests/GraphUpdates/GraphUpdatesTestBaseMiscellaneous.cs b/test/EFCore.Specification.Tests/GraphUpdates/GraphUpdatesTestBaseMiscellaneous.cs index 33c7d260379..361a19c9c88 100644 --- a/test/EFCore.Specification.Tests/GraphUpdates/GraphUpdatesTestBaseMiscellaneous.cs +++ b/test/EFCore.Specification.Tests/GraphUpdates/GraphUpdatesTestBaseMiscellaneous.cs @@ -134,7 +134,7 @@ public virtual Task Can_insert_when_nullable_bool_PK_in_composite_key_has_sentin protected async Task Can_insert_when_PK_property_in_composite_key_has_sentinel_value(bool async, T initialValue) where T : new() { - var inserted = new CompositeKeyWith() + var inserted = new CompositeKeyWith { SourceId = Guid.NewGuid(), TargetId = Guid.NewGuid(), @@ -184,7 +184,7 @@ public virtual Task Throws_for_single_property_nullable_bool_key_with_default_va protected async Task Throws_for_single_property_key_with_default_value_generation(bool async, T initialValue) where T : new() { - var inserted = new BoolOnlyKey() { PrimaryGroup = initialValue }; + var inserted = new BoolOnlyKey { PrimaryGroup = initialValue }; await ExecuteWithStrategyInTransactionAsync( async context => @@ -410,7 +410,7 @@ public virtual async Task Clearing_shadow_key_owned_collection_throws(bool async } owner.OwnedCollection = addNew - ? [new(), new()] + ? [new Owned(), new Owned()] : new List(); Assert.Equal( @@ -636,11 +636,11 @@ public virtual async Task Clearing_CLR_key_owned_collection(bool async, bool use } owner.OwnedCollection = addNew - ? [new() { Bar = "OfGold" }, new() { Bar = "OfSoap" }] + ? [new OwnedWithKey { Bar = "OfGold" }, new OwnedWithKey { Bar = "OfSoap" }] : new List(); owner.OwnedCollectionPrivateKey = addNew - ? [new() { Bar = "OfChocolate" }, new() { Bar = "OfLead" }] + ? [new OwnedWithPrivateKey { Bar = "OfChocolate" }, new OwnedWithPrivateKey { Bar = "OfLead" }] : new List(); if (async) @@ -731,7 +731,7 @@ public virtual async Task Update_principal_with_non_generated_shadow_key_owned_c [ConditionalTheory] // Issue #21206 [InlineData(false)] [InlineData(true)] - public async Task Discriminator_values_are_not_marked_as_unknown(bool async) + public virtual async Task Discriminator_values_are_not_marked_as_unknown(bool async) => await ExecuteWithStrategyInTransactionAsync( async context => { @@ -1766,8 +1766,8 @@ public virtual Task Save_changed_owned_one_to_one() context.Entry(root.RequiredSingle).State = EntityState.Deleted; } - root.OptionalSingle = new() { Name = "OS`", Single = new() { Name = "OS2`" } }; - root.RequiredSingle = new() { Name = "RS`", Single = new() { Name = "RS2`" } }; + root.OptionalSingle = new OwnedOptionalSingle1 { Name = "OS`", Single = new OwnedOptionalSingle2 { Name = "OS2`" } }; + root.RequiredSingle = new OwnedRequiredSingle1 { Name = "RS`", Single = new OwnedRequiredSingle2 { Name = "RS2`" } }; Assert.True(context.ChangeTracker.HasChanges()); @@ -1812,10 +1812,18 @@ public virtual Task Save_changed_owned_one_to_many() root.OptionalChildren.Remove(optionalChildren); root.RequiredChildren.Remove(requiredChildren); - root.OptionalChildren.First().Children.Add(new() { Name = "OCC3" }); - root.OptionalChildren.Add(new() { Name = "OC3", Children = { new() { Name = "OCC4" }, new() { Name = "OCC5" } } }); - root.RequiredChildren.First().Children.Add(new() { Name = "RCC3" }); - root.RequiredChildren.Add(new() { Name = "RC3", Children = { new() { Name = "RCC4" }, new() { Name = "RCC5" } } }); + root.OptionalChildren.First().Children.Add(new OwnedOptional2 { Name = "OCC3" }); + root.OptionalChildren.Add( + new OwnedOptional1 + { + Name = "OC3", Children = { new OwnedOptional2 { Name = "OCC4" }, new OwnedOptional2 { Name = "OCC5" } } + }); + root.RequiredChildren.First().Children.Add(new OwnedRequired2 { Name = "RCC3" }); + root.RequiredChildren.Add( + new OwnedRequired1 + { + Name = "RC3", Children = { new OwnedRequired2 { Name = "RCC4" }, new OwnedRequired2 { Name = "RCC5" } } + }); Assert.True(context.ChangeTracker.HasChanges()); @@ -2292,7 +2300,7 @@ public virtual Task Mark_explicitly_set_stable_dependent_appropriately(bool asyn ? await context.FindAsync(parentId) : context.Find(parentId); - var child = new StableChild32084() + var child = new StableChild32084 { Id = childId, ParentId = parent!.Id, }; diff --git a/test/EFCore.Specification.Tests/JsonTypesTestBase.cs b/test/EFCore.Specification.Tests/JsonTypesTestBase.cs index 3316bab9453..c0096a11891 100644 --- a/test/EFCore.Specification.Tests/JsonTypesTestBase.cs +++ b/test/EFCore.Specification.Tests/JsonTypesTestBase.cs @@ -1321,7 +1321,7 @@ public class NullablePointType } [ConditionalFact] - public async virtual Task Can_read_write_point_with_Z() + public virtual async Task Can_read_write_point_with_Z() { var factory = NtsGeometryServices.Instance.CreateGeometryFactory(srid: 4326); @@ -1703,7 +1703,7 @@ public virtual Task Can_read_write_custom_converted_type_JSON_values(string valu b => b.Entity().HasNoKey().Property(e => e.Address), b => b.Properties().HaveConversion(), nameof(IpAddressType.Address), - new(IPAddress.Parse(value)), + new IpAddress(IPAddress.Parse(value)), json); protected class IpAddressConverter() : ValueConverter( @@ -1767,7 +1767,8 @@ protected class Int16CollectionType public virtual Task Can_read_write_collection_of_int_JSON_values() => Can_read_and_write_JSON_value>( nameof(Int32CollectionType.Int32), - new ReadOnlyCollection([ + new ReadOnlyCollection( + [ int.MinValue, 0, int.MaxValue @@ -1924,7 +1925,7 @@ public virtual Task Can_read_write_collection_of_DateOnly_JSON_values() nameof(DateOnlyCollectionType.DateOnly), [ DateOnly.MinValue, - new(2023, 5, 29), + new DateOnly(2023, 5, 29), DateOnly.MaxValue ], """{"Prop":["0001-01-01","2023-05-29","9999-12-31"]}""", @@ -1941,7 +1942,7 @@ public virtual Task Can_read_write_collection_of_TimeOnly_JSON_values() nameof(TimeOnlyCollectionType.TimeOnly), [ TimeOnly.MinValue, - new(11, 5, 2, 3, 4), + new TimeOnly(11, 5, 2, 3, 4), TimeOnly.MaxValue ], """{"Prop":["00:00:00.0000000","11:05:02.0030040","23:59:59.9999999"]}""", @@ -1960,7 +1961,7 @@ public virtual Task Can_read_write_collection_of_DateTime_JSON_values(string exp nameof(DateTimeCollectionType.DateTime), [ DateTime.MinValue, - new(2023, 5, 29, 10, 52, 47), + new DateTime(2023, 5, 29, 10, 52, 47), DateTime.MaxValue ], expected, @@ -1972,15 +1973,16 @@ protected class DateTimeCollectionType } [ConditionalTheory] - [InlineData("""{"Prop":["0001-01-01T00:00:00+00:00","2023-05-29T10:52:47-02:00","2023-05-29T10:52:47+00:00","2023-05-29T10:52:47+02:00","9999-12-31T23:59:59.9999999+00:00"]}""")] + [InlineData( + """{"Prop":["0001-01-01T00:00:00+00:00","2023-05-29T10:52:47-02:00","2023-05-29T10:52:47+00:00","2023-05-29T10:52:47+02:00","9999-12-31T23:59:59.9999999+00:00"]}""")] public virtual Task Can_read_write_collection_of_DateTimeOffset_JSON_values(string expected) => Can_read_and_write_JSON_value>( nameof(DateTimeOffsetCollectionType.DateTimeOffset), [ DateTimeOffset.MinValue, - new(new DateTime(2023, 5, 29, 10, 52, 47), new TimeSpan(-2, 0, 0)), - new(new DateTime(2023, 5, 29, 10, 52, 47), new TimeSpan(0, 0, 0)), - new(new DateTime(2023, 5, 29, 10, 52, 47), new TimeSpan(2, 0, 0)), + new DateTimeOffset(new DateTime(2023, 5, 29, 10, 52, 47), new TimeSpan(-2, 0, 0)), + new DateTimeOffset(new DateTime(2023, 5, 29, 10, 52, 47), new TimeSpan(0, 0, 0)), + new DateTimeOffset(new DateTime(2023, 5, 29, 10, 52, 47), new TimeSpan(2, 0, 0)), DateTimeOffset.MaxValue ], expected, @@ -1997,7 +1999,7 @@ public virtual Task Can_read_write_collection_of_TimeSpan_JSON_values() nameof(TimeSpanCollectionType.TimeSpan), [ TimeSpan.MinValue, - new(1, 2, 3, 4, 5), + new TimeSpan(1, 2, 3, 4, 5), TimeSpan.MaxValue ], """{"Prop":["-10675199:2:48:05.4775808","1:2:03:04.005","10675199:2:48:05.4775807"]}""", @@ -2039,13 +2041,14 @@ protected class CharacterCollectionType } [ConditionalTheory] - [InlineData("""{"Prop":["00000000-0000-0000-0000-000000000000","8c44242f-8e3f-4a20-8be8-98c7c1aadebd","ffffffff-ffff-ffff-ffff-ffffffffffff"]}""")] + [InlineData( + """{"Prop":["00000000-0000-0000-0000-000000000000","8c44242f-8e3f-4a20-8be8-98c7c1aadebd","ffffffff-ffff-ffff-ffff-ffffffffffff"]}""")] public virtual Task Can_read_write_collection_of_GUID_JSON_values(string expected) => Can_read_and_write_JSON_value>( nameof(GuidCollectionType.Guid), [ - new(), - new("8C44242F-8E3F-4A20-8BE8-98C7C1AADEBD"), + new Guid(), + new Guid("8C44242F-8E3F-4A20-8BE8-98C7C1AADEBD"), Guid.Parse("FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF") ], expected, @@ -2097,8 +2100,8 @@ public virtual Task Can_read_write_collection_of_URI_JSON_values() => Can_read_and_write_JSON_value>( nameof(UriCollectionType.Uri), [ - new("https://user:password@www.contoso.com:80/Home/Index.htm?q1=v1&q2=v2#FragmentName"), - new("file:///C:/test/path/file.txt") + new Uri("https://user:password@www.contoso.com:80/Home/Index.htm?q1=v1&q2=v2#FragmentName"), + new Uri("file:///C:/test/path/file.txt") ], """{"Prop":["https://user:password@www.contoso.com:80/Home/Index.htm?q1=v1\u0026q2=v2#FragmentName","file:///C:/test/path/file.txt"]}""", mappedCollection: true); @@ -2112,7 +2115,8 @@ protected class UriCollectionType public virtual Task Can_read_write_collection_of_IP_address_JSON_values() => Can_read_and_write_JSON_value>( nameof(IpAddressCollectionType.IpAddress), - new ReadOnlyCollection([ + new ReadOnlyCollection( + [ IPAddress.Parse("127.0.0.1"), IPAddress.Parse("0.0.0.0"), IPAddress.Parse("255.255.255.255"), @@ -2506,7 +2510,7 @@ public virtual Task Can_read_write_collection_of_nullable_DateOnly_JSON_values() nameof(NullableDateOnlyCollectionType.DateOnly), [ DateOnly.MinValue, - new(2023, 5, 29), + new DateOnly(2023, 5, 29), DateOnly.MaxValue, null ], @@ -2525,7 +2529,7 @@ public virtual Task Can_read_write_collection_of_nullable_TimeOnly_JSON_values() [ null, TimeOnly.MinValue, - new(11, 5, 2, 3, 4), + new TimeOnly(11, 5, 2, 3, 4), TimeOnly.MaxValue ], """{"Prop":[null,"00:00:00.0000000","11:05:02.0030040","23:59:59.9999999"]}""", @@ -2544,7 +2548,7 @@ public virtual Task Can_read_write_collection_of_nullable_DateTime_JSON_values(s [ DateTime.MinValue, null, - new(2023, 5, 29, 10, 52, 47), + new DateTime(2023, 5, 29, 10, 52, 47), DateTime.MaxValue ], expected, @@ -2556,16 +2560,17 @@ protected class NullableDateTimeCollectionType } [ConditionalTheory] - [InlineData("""{"Prop":["0001-01-01T00:00:00+00:00","2023-05-29T10:52:47-02:00","2023-05-29T10:52:47+00:00",null,"2023-05-29T10:52:47+02:00","9999-12-31T23:59:59.9999999+00:00"]}""")] + [InlineData( + """{"Prop":["0001-01-01T00:00:00+00:00","2023-05-29T10:52:47-02:00","2023-05-29T10:52:47+00:00",null,"2023-05-29T10:52:47+02:00","9999-12-31T23:59:59.9999999+00:00"]}""")] public virtual Task Can_read_write_collection_of_nullable_DateTimeOffset_JSON_values(string expected) => Can_read_and_write_JSON_value>( nameof(NullableDateTimeOffsetCollectionType.DateTimeOffset), [ DateTimeOffset.MinValue, - new(new DateTime(2023, 5, 29, 10, 52, 47), new TimeSpan(-2, 0, 0)), - new(new DateTime(2023, 5, 29, 10, 52, 47), new TimeSpan(0, 0, 0)), + new DateTimeOffset(new DateTime(2023, 5, 29, 10, 52, 47), new TimeSpan(-2, 0, 0)), + new DateTimeOffset(new DateTime(2023, 5, 29, 10, 52, 47), new TimeSpan(0, 0, 0)), null, - new(new DateTime(2023, 5, 29, 10, 52, 47), new TimeSpan(2, 0, 0)), + new DateTimeOffset(new DateTime(2023, 5, 29, 10, 52, 47), new TimeSpan(2, 0, 0)), DateTimeOffset.MaxValue ], expected, @@ -2582,7 +2587,7 @@ public virtual Task Can_read_write_collection_of_nullable_TimeSpan_JSON_values() nameof(NullableTimeSpanCollectionType.TimeSpan), [ TimeSpan.MinValue, - new(1, 2, 3, 4, 5), + new TimeSpan(1, 2, 3, 4, 5), TimeSpan.MaxValue, null ], @@ -2631,14 +2636,15 @@ protected class NullableCharacterCollectionType } [ConditionalTheory] - [InlineData("""{"Prop":["00000000-0000-0000-0000-000000000000",null,"8c44242f-8e3f-4a20-8be8-98c7c1aadebd","ffffffff-ffff-ffff-ffff-ffffffffffff"]}""")] + [InlineData( + """{"Prop":["00000000-0000-0000-0000-000000000000",null,"8c44242f-8e3f-4a20-8be8-98c7c1aadebd","ffffffff-ffff-ffff-ffff-ffffffffffff"]}""")] public virtual Task Can_read_write_collection_of_nullable_GUID_JSON_values(string expected) => Can_read_and_write_JSON_value>( nameof(NullableGuidCollectionType.Guid), [ - new(), + new Guid(), null, - new("8C44242F-8E3F-4A20-8BE8-98C7C1AADEBD"), + new Guid("8C44242F-8E3F-4A20-8BE8-98C7C1AADEBD"), Guid.Parse("FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF") ], expected, @@ -2692,9 +2698,9 @@ public virtual Task Can_read_write_collection_of_nullable_URI_JSON_values() => Can_read_and_write_JSON_value>( nameof(NullableUriCollectionType.Uri), [ - new("https://user:password@www.contoso.com:80/Home/Index.htm?q1=v1&q2=v2#FragmentName"), + new Uri("https://user:password@www.contoso.com:80/Home/Index.htm?q1=v1&q2=v2#FragmentName"), null, - new("file:///C:/test/path/file.txt") + new Uri("file:///C:/test/path/file.txt") ], """{"Prop":["https://user:password@www.contoso.com:80/Home/Index.htm?q1=v1\u0026q2=v2#FragmentName",null,"file:///C:/test/path/file.txt"]}""", mappedCollection: true); @@ -3344,9 +3350,9 @@ public virtual Task Can_read_write_collection_of_int_with_converter_JSON_values( }), nameof(DddIdCollectionType.DddId), [ - new() { Id = int.MinValue }, - new() { Id = 0 }, - new() { Id = int.MaxValue } + new DddId { Id = int.MinValue }, + new DddId { Id = 0 }, + new DddId { Id = int.MaxValue } ], """{"Prop":[-2147483648,0,2147483647]}""", facets: new Dictionary { { CoreAnnotationNames.ValueConverter, typeof(DddIdConverter) } }); @@ -3363,10 +3369,10 @@ public virtual Task Can_read_write_collection_of_nullable_int_with_converter_JSO nameof(NullableDddIdCollectionType.DddId), [ null, - new() { Id = int.MinValue }, + new DddId { Id = int.MinValue }, null, - new() { Id = 0 }, - new() { Id = int.MaxValue } + new DddId { Id = 0 }, + new DddId { Id = int.MaxValue } ], """{"Prop":[null,-2147483648,null,0,2147483647]}""", facets: new Dictionary { { CoreAnnotationNames.ValueConverter, typeof(DddIdConverter) } }); @@ -3410,8 +3416,8 @@ public virtual Task Can_read_write_collection_of_Guid_converted_to_bytes_JSON_va b => b.ElementType().HasConversion(), nameof(GuidCollectionType.Guid), [ - new(), - new("8C44242F-8E3F-4A20-8BE8-98C7C1AADEBD"), + new Guid(), + new Guid("8C44242F-8E3F-4A20-8BE8-98C7C1AADEBD"), Guid.Parse("FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF") ], expected, @@ -3547,7 +3553,8 @@ protected class BinaryArrayListType } [ConditionalTheory] - [InlineData("""{"Prop":[["00000000-0000-0000-0000-000000000000","8c44242f-8e3f-4a20-8be8-98c7c1aadebd"],[],["ffffffff-ffff-ffff-ffff-ffffffffffff"]]}""")] + [InlineData( + """{"Prop":[["00000000-0000-0000-0000-000000000000","8c44242f-8e3f-4a20-8be8-98c7c1aadebd"],[],["ffffffff-ffff-ffff-ffff-ffffffffffff"]]}""")] public virtual Task Can_read_write_list_of_array_of_GUID_JSON_values(string expected) => Can_read_and_write_JSON_value>( nameof(GuidArrayListType.Prop), @@ -3566,13 +3573,17 @@ protected class GuidArrayListType } [ConditionalTheory] - [InlineData("""{"Prop":[["00000000-0000-0000-0000-000000000000",null,"8c44242f-8e3f-4a20-8be8-98c7c1aadebd"],[],["ffffffff-ffff-ffff-ffff-ffffffffffff"]]}""")] + [InlineData( + """{"Prop":[["00000000-0000-0000-0000-000000000000",null,"8c44242f-8e3f-4a20-8be8-98c7c1aadebd"],[],["ffffffff-ffff-ffff-ffff-ffffffffffff"]]}""")] public virtual Task Can_read_write_list_of_array_of_nullable_GUID_JSON_values(string expected) => Can_read_and_write_JSON_value>( nameof(NullableGuidArrayListType.Prop), new List { - new Guid?[] { new Guid("00000000-0000-0000-0000-000000000000"), null, new Guid("8C44242F-8E3F-4A20-8BE8-98C7C1AADEBD") }, + new Guid?[] + { + new Guid("00000000-0000-0000-0000-000000000000"), null, new Guid("8C44242F-8E3F-4A20-8BE8-98C7C1AADEBD") + }, Array.Empty(), new Guid?[] { new Guid("FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF") } }, @@ -3590,7 +3601,12 @@ public virtual Task Can_read_write_array_of_list_of_int_JSON_values() nameof(Int32ListArrayType.Prop), new List[] { - new() { int.MinValue, 0, int.MaxValue }, + new() + { + int.MinValue, + 0, + int.MaxValue + }, new(), new() { 77 } }, @@ -3608,7 +3624,12 @@ public virtual Task Can_read_write_array_of_list_of_string_JSON_values() nameof(StringListArrayType.Prop), new List[] { - new() { "X", "Y", "" }, + new() + { + "X", + "Y", + "" + }, new(), new() { "77" } }, @@ -3644,7 +3665,12 @@ public virtual Task Can_read_write_array_of_list_of_ulong_JSON_values() nameof(ULongListArrayType.Prop), new List[] { - new() { ulong.MinValue, 1UL, ulong.MaxValue }, + new() + { + ulong.MinValue, + 1UL, + ulong.MaxValue + }, new(), new() { 77UL } }, @@ -3663,7 +3689,12 @@ public virtual Task Can_read_write_array_of_list_of_binary_JSON_values(string ex nameof(BinaryListArrayType.Prop), new List[] { - new() { new byte[] { 0, 1, 2 }, new byte[] { 1 }, new byte[] { 77 } }, + new() + { + new byte[] { 0, 1, 2 }, + new byte[] { 1 }, + new byte[] { 77 } + }, new(), new() { new byte[] { 78 } } }, @@ -3676,7 +3707,8 @@ protected class BinaryListArrayType } [ConditionalTheory] - [InlineData("""{"Prop":[["00000000-0000-0000-0000-000000000000","8c44242f-8e3f-4a20-8be8-98c7c1aadebd"],[],["ffffffff-ffff-ffff-ffff-ffffffffffff"]]}""")] + [InlineData( + """{"Prop":[["00000000-0000-0000-0000-000000000000","8c44242f-8e3f-4a20-8be8-98c7c1aadebd"],[],["ffffffff-ffff-ffff-ffff-ffffffffffff"]]}""")] public virtual Task Can_read_write_array_of_list_of_GUID_JSON_values(string expected) => Can_read_and_write_JSON_value[]>( nameof(GuidListArrayType.Prop), @@ -3700,9 +3732,23 @@ public virtual Task Can_read_write_list_of_list_of_list_of_int_JSON_values() nameof(Int32ListListListType.Prop), new List>> { - new() { new () { int.MinValue, 0, int.MaxValue }, new() { 77 } }, + new() + { + new List + { + int.MinValue, + 0, + int.MaxValue + }, + new List { 77 } + }, new(), - new() { new () { 1, 2 }, new(), new() { 78, 79 } } + new() + { + new List { 1, 2 }, + new List(), + new List { 78, 79 } + } }, """{"Prop":[[[-2147483648,0,2147483647],[77]],[],[[1,2],[],[78,79]]]}""", mappedCollection: true); @@ -3735,9 +3781,18 @@ public virtual Task Can_read_write_list_of_array_of_list_of_string_JSON_values() nameof(StringListArrayListType.Prop), new List[]> { - new List[] { new () { "int.MinValue", "", "int.MaxValue" }, new() { "77" } }, + new List[] + { + new() + { + "int.MinValue", + "", + "int.MaxValue" + }, + new() { "77" } + }, Array.Empty>(), - new List[] { new () { "1", "2" }, new(), new() { "78", "79" } } + new List[] { new() { "1", "2" }, new(), new() { "78", "79" } } }, """{"Prop":[[["int.MinValue","","int.MaxValue"],["77"]],[],[["1","2"],[],["78","79"]]]}""", mappedCollection: true); @@ -3755,7 +3810,12 @@ public virtual Task Can_read_write_array_of_list_of_array_of_string_JSON_values( { new() { new[] { "int.MinValue", "", "int.MaxValue" }, new[] { "77" } }, new(), - new() { new[] { "1", "2" }, Array.Empty(), new[] { "78", "79" } } + new() + { + new[] { "1", "2" }, + Array.Empty(), + new[] { "78", "79" } + } }, """{"Prop":[[["int.MinValue","","int.MaxValue"],["77"]],[],[["1","2"],[],["78","79"]]]}""", mappedCollection: true); @@ -3789,7 +3849,10 @@ public virtual Task Can_read_write_list_of_array_of_list_of_IPAddress_JSON_value nameof(IpAddressListArrayListType.Prop), new List[]> { - new List[] { new() { IPAddress.Parse("127.0.0.1"), IPAddress.Parse("2a00:23c7:c60f:4f01:ba43:6d5a:e648:7577") } }, + new List[] + { + new() { IPAddress.Parse("127.0.0.1"), IPAddress.Parse("2a00:23c7:c60f:4f01:ba43:6d5a:e648:7577") } + }, Array.Empty>(), new List[] { new() { new IPAddress(0) } } }, @@ -3826,9 +3889,12 @@ public virtual Task Can_read_write_list_of_array_of_list_of_array_of_binary_JSON nameof(BinaryListArrayArrayListType.Prop), new List[]> { - new List[] { new() { new byte[][] { new byte[] { 0, 1, 2 }, [1], [77] } }, new(), new() { new byte[][] { }, Array.Empty() } }, + new List[] + { + new() { new[] { new byte[] { 0, 1, 2 }, [1], [77] } }, new(), new() { new byte[][] { }, Array.Empty() } + }, Array.Empty>(), - new List[] { new() { new byte[][] { } }, new() { new byte[][] { new byte[] { 0, 1, 2 }, [1], [77] } } }, + new List[] { new() { new byte[][] { } }, new() { new[] { new byte[] { 0, 1, 2 }, [1], [77] } } }, }, expected, mappedCollection: true); @@ -4223,7 +4289,8 @@ public override void ToJsonTyped(Utf8JsonWriter writer, Geometry value) private readonly Expression> _instanceLambda = () => Instance; /// - public override Expression ConstructorExpression => _instanceLambda.Body; + public override Expression ConstructorExpression + => _instanceLambda.Body; } private readonly NullabilityInfoContext _nullabilityInfoContext = new(); diff --git a/test/EFCore.Specification.Tests/KeysWithConvertersTestBase.cs b/test/EFCore.Specification.Tests/KeysWithConvertersTestBase.cs index ad6ea7bb260..90a6b92c44b 100644 --- a/test/EFCore.Specification.Tests/KeysWithConvertersTestBase.cs +++ b/test/EFCore.Specification.Tests/KeysWithConvertersTestBase.cs @@ -451,7 +451,8 @@ await principalQuery.SingleAsync(e => e.Id.Equals(new IntStructKey { Id = 14 })) dependents = [ await context.Set().FirstOrDefaultAsync(e => e.Id.Equals(new IntStructKey { Id = 111 })), - await context.Set().FirstOrDefaultAsync(e => e.Id.Equals(new IntStructKey { Id = oneTwelve })), + await context.Set() + .FirstOrDefaultAsync(e => e.Id.Equals(new IntStructKey { Id = oneTwelve })), await context.Set().FirstOrDefaultAsync(e => e.Id.Equals(oneThirteen)), await context.Set().FirstOrDefaultAsync(e => e.Id.Equals(new IntStructKey { Id = 114 })), await context.Set() @@ -463,7 +464,8 @@ await context.Set().FirstOrDefaultAsync(e => e.Id Assert.Same(dependents[1], await context.Set().FindAsync(new IntStructKey { Id = oneTwelve })); Assert.Same(dependents[2], await context.Set().FindAsync(oneThirteen)); Assert.Same(dependents[3], await context.FindAsync(typeof(IntStructKeyRequiredDependent), new IntStructKey { Id = 114 })); - Assert.Same(dependents[4], await context.FindAsync(typeof(IntStructKeyRequiredDependent), new IntStructKey { Id = oneFifteeen })); + Assert.Same( + dependents[4], await context.FindAsync(typeof(IntStructKeyRequiredDependent), new IntStructKey { Id = oneFifteeen })); Assert.Same(dependents[5], await context.FindAsync(typeof(IntStructKeyRequiredDependent), oneSixteen)); } @@ -574,13 +576,15 @@ await context.Set().FirstOrDefaultAsync ]; Assert.Same( - dependents[0], await context.Set().FindAsync(new ComparableIntStructKey { Id = 111 })); + dependents[0], + await context.Set().FindAsync(new ComparableIntStructKey { Id = 111 })); Assert.Same( dependents[1], await context.Set().FindAsync(new ComparableIntStructKey { Id = oneTwelve })); Assert.Same(dependents[2], await context.Set().FindAsync(oneThirteen)); Assert.Same( - dependents[3], await context.FindAsync(typeof(ComparableIntStructKeyRequiredDependent), new ComparableIntStructKey { Id = 114 })); + dependents[3], + await context.FindAsync(typeof(ComparableIntStructKeyRequiredDependent), new ComparableIntStructKey { Id = 114 })); Assert.Same( dependents[4], await context.FindAsync(typeof(ComparableIntStructKeyRequiredDependent), new ComparableIntStructKey { Id = oneFifteeen })); @@ -695,7 +699,8 @@ await context.Set().FirstOrDefau Assert.Same( dependents[0], - await context.Set().FindAsync(new GenericComparableIntStructKey { Id = 111 })); + await context.Set() + .FindAsync(new GenericComparableIntStructKey { Id = 111 })); Assert.Same( dependents[1], await context.Set() @@ -703,7 +708,8 @@ await context.Set() Assert.Same(dependents[2], await context.Set().FindAsync(oneThirteen)); Assert.Same( dependents[3], - await context.FindAsync(typeof(GenericComparableIntStructKeyRequiredDependent), new GenericComparableIntStructKey { Id = 114 })); + await context.FindAsync( + typeof(GenericComparableIntStructKeyRequiredDependent), new GenericComparableIntStructKey { Id = 114 })); Assert.Same( dependents[4], await context.FindAsync( @@ -924,7 +930,8 @@ await context.Set().SingleAsync(e => e.Id = ]; Assert.Same(dependents[0], await context.Set().FindAsync(new EnumerableClassKey(101))); - Assert.Same(dependents[1], await context.Set().FindAsync(new EnumerableClassKey(oneOhTwo))); + Assert.Same( + dependents[1], await context.Set().FindAsync(new EnumerableClassKey(oneOhTwo))); Assert.Same(dependents[2], await context.Set().FindAsync(oneOhThree)); Assert.Same(dependents[3], await context.FindAsync(new EnumerableClassKey(104))); Assert.Same(dependents[4], await context.FindAsync(new EnumerableClassKey(oneOhFive))); @@ -1764,11 +1771,13 @@ await context.Set().FirstOrDefaultAsync(e => e. Assert.Same( dependents[0], await context.Set().FindAsync(new BytesStructKey { Id = [111] })); - Assert.Same(dependents[1], await context.Set().FindAsync(new BytesStructKey { Id = oneTwelve })); + Assert.Same( + dependents[1], await context.Set().FindAsync(new BytesStructKey { Id = oneTwelve })); Assert.Same(dependents[2], await context.Set().FindAsync(oneThirteen)); Assert.Same( dependents[3], await context.FindAsync(typeof(BytesStructKeyRequiredDependent), new BytesStructKey { Id = [114] })); - Assert.Same(dependents[4], await context.FindAsync(typeof(BytesStructKeyRequiredDependent), new BytesStructKey { Id = oneFifteeen })); + Assert.Same( + dependents[4], await context.FindAsync(typeof(BytesStructKeyRequiredDependent), new BytesStructKey { Id = oneFifteeen })); Assert.Same(dependents[5], await context.FindAsync(typeof(BytesStructKeyRequiredDependent), oneSixteen)); } @@ -1892,7 +1901,8 @@ await context.FindAsync( typeof(ComparableBytesStructKeyRequiredDependent), new ComparableBytesStructKey { Id = [114] })); Assert.Same( dependents[4], - await context.FindAsync(typeof(ComparableBytesStructKeyRequiredDependent), new ComparableBytesStructKey { Id = oneFifteeen })); + await context.FindAsync( + typeof(ComparableBytesStructKeyRequiredDependent), new ComparableBytesStructKey { Id = oneFifteeen })); Assert.Same(dependents[5], await context.FindAsync(typeof(ComparableBytesStructKeyRequiredDependent), oneSixteen)); } @@ -2250,7 +2260,8 @@ public virtual async Task Can_query_and_update_owned_entity_with_binary_struct_k using (var context = CreateContext()) { - var owner = await context.Set().SingleAsync(o => o.Id.Equals(new BytesStructKey(new byte[] { 1, 5, 7, 1 }))); + var owner = await context.Set() + .SingleAsync(o => o.Id.Equals(new BytesStructKey(new byte[] { 1, 5, 7, 1 }))); Assert.Equal(77, owner.Owned.Position); owner.Owned = new OwnedBytesStructKey(88); @@ -2491,7 +2502,8 @@ public virtual async Task Can_query_and_update_owned_entity_with_generic_compara using (var context = CreateContext()) { - var owner = await context.Set().SingleAsync(o => o.Id.Equals(new GenericComparableIntClassKey(1))); + var owner = await context.Set() + .SingleAsync(o => o.Id.Equals(new GenericComparableIntClassKey(1))); Assert.Equal(77, owner.Owned.Position); owner.Owned = new OwnedGenericComparableIntClassKey(88); @@ -2779,12 +2791,15 @@ await context.Set().SingleAsync(e ]; Assert.Same( - dependents[0], await context.Set().FindAsync(new ComparableIntStructKey(101))); + dependents[0], + await context.Set().FindAsync(new ComparableIntStructKey(101))); Assert.Same( - dependents[1], await context.Set().FindAsync(new ComparableIntStructKey(oneOhTwo))); + dependents[1], + await context.Set().FindAsync(new ComparableIntStructKey(oneOhTwo))); Assert.Same(dependents[2], await context.Set().FindAsync(oneOhThree)); Assert.Same( - dependents[3], await context.FindAsync(typeof(ComparableIntStructKeyOptionalDependentShadow), new ComparableIntStructKey(104))); + dependents[3], + await context.FindAsync(typeof(ComparableIntStructKeyOptionalDependentShadow), new ComparableIntStructKey(104))); Assert.Same( dependents[4], await context.FindAsync(typeof(ComparableIntStructKeyOptionalDependentShadow), new ComparableIntStructKey(oneOhFive))); @@ -2963,14 +2978,17 @@ await context.Set().Single Assert.Same( dependents[0], - await context.Set().FindAsync(new GenericComparableIntStructKey(101))); + await context.Set() + .FindAsync(new GenericComparableIntStructKey(101))); Assert.Same( dependents[1], - await context.Set().FindAsync(new GenericComparableIntStructKey(oneOhTwo))); + await context.Set() + .FindAsync(new GenericComparableIntStructKey(oneOhTwo))); Assert.Same(dependents[2], await context.Set().FindAsync(oneOhThree)); Assert.Same( dependents[3], - await context.FindAsync(typeof(GenericComparableIntStructKeyOptionalDependentShadow), new GenericComparableIntStructKey(104))); + await context.FindAsync( + typeof(GenericComparableIntStructKeyOptionalDependentShadow), new GenericComparableIntStructKey(104))); Assert.Same( dependents[4], await context.FindAsync( @@ -3120,18 +3138,21 @@ await principalQuery.SingleAsync(e => e.Id.Equals(new IntStructKey { Id = 14 })) dependents = [ - await context.Set().FirstOrDefaultAsync(e => e.Id.Equals(new IntStructKey { Id = 111 })), + await context.Set() + .FirstOrDefaultAsync(e => e.Id.Equals(new IntStructKey { Id = 111 })), await context.Set() .FirstOrDefaultAsync(e => e.Id.Equals(new IntStructKey { Id = oneTwelve })), await context.Set().FirstOrDefaultAsync(e => e.Id.Equals(oneThirteen)), - await context.Set().FirstOrDefaultAsync(e => e.Id.Equals(new IntStructKey { Id = 114 })), + await context.Set() + .FirstOrDefaultAsync(e => e.Id.Equals(new IntStructKey { Id = 114 })), await context.Set() .FirstOrDefaultAsync(e => e.Id.Equals(new IntStructKey { Id = oneFifteeen })), await context.Set().FirstOrDefaultAsync(e => e.Id.Equals(oneSixteen)) ]; Assert.Same(dependents[0], await context.Set().FindAsync(new IntStructKey { Id = 111 })); - Assert.Same(dependents[1], await context.Set().FindAsync(new IntStructKey { Id = oneTwelve })); + Assert.Same( + dependents[1], await context.Set().FindAsync(new IntStructKey { Id = oneTwelve })); Assert.Same(dependents[2], await context.Set().FindAsync(oneThirteen)); Assert.Same(dependents[3], await context.FindAsync(typeof(IntStructKeyRequiredDependentShadow), new IntStructKey { Id = 114 })); Assert.Same( @@ -3294,14 +3315,16 @@ await context.Set().FirstOrDefaul await context.Set().FindAsync(new ComparableIntStructKey { Id = 111 })); Assert.Same( dependents[1], - await context.Set().FindAsync(new ComparableIntStructKey { Id = oneTwelve })); + await context.Set() + .FindAsync(new ComparableIntStructKey { Id = oneTwelve })); Assert.Same(dependents[2], await context.Set().FindAsync(oneThirteen)); Assert.Same( dependents[3], await context.FindAsync(typeof(ComparableIntStructKeyRequiredDependentShadow), new ComparableIntStructKey { Id = 114 })); Assert.Same( dependents[4], - await context.FindAsync(typeof(ComparableIntStructKeyRequiredDependentShadow), new ComparableIntStructKey { Id = oneFifteeen })); + await context.FindAsync( + typeof(ComparableIntStructKeyRequiredDependentShadow), new ComparableIntStructKey { Id = oneFifteeen })); Assert.Same(dependents[5], await context.FindAsync(typeof(ComparableIntStructKeyRequiredDependentShadow), oneSixteen)); } @@ -3466,7 +3489,8 @@ await context.Set() .FirstOrDefaultAsync(e => e.Id.Equals(new GenericComparableIntStructKey { Id = 111 })), await context.Set() .FirstOrDefaultAsync(e => e.Id.Equals(new GenericComparableIntStructKey { Id = oneTwelve })), - await context.Set().FirstOrDefaultAsync(e => e.Id.Equals(oneThirteen)), + await context.Set() + .FirstOrDefaultAsync(e => e.Id.Equals(oneThirteen)), await context.Set() .FirstOrDefaultAsync(e => e.Id.Equals(new GenericComparableIntStructKey { Id = 114 })), await context.Set() @@ -3800,7 +3824,8 @@ await context.Set().SingleAsync(e => e.I ]; Assert.Same(dependents[0], await context.Set().FindAsync(new BareIntClassKey(101))); - Assert.Same(dependents[1], await context.Set().FindAsync(new BareIntClassKey(oneOhTwo))); + Assert.Same( + dependents[1], await context.Set().FindAsync(new BareIntClassKey(oneOhTwo))); Assert.Same(dependents[2], await context.Set().FindAsync(oneOhThree)); Assert.Same(dependents[3], await context.FindAsync(new BareIntClassKey(104))); Assert.Same(dependents[4], await context.FindAsync(new BareIntClassKey(oneOhFive))); @@ -3963,9 +3988,11 @@ await context.Set().SingleAsync(e Assert.Same( dependents[0], await context.Set().FindAsync(new ComparableIntClassKey(101))); Assert.Same( - dependents[1], await context.Set().FindAsync(new ComparableIntClassKey(oneOhTwo))); + dependents[1], + await context.Set().FindAsync(new ComparableIntClassKey(oneOhTwo))); Assert.Same(dependents[2], await context.Set().FindAsync(oneOhThree)); - Assert.Same(dependents[3], await context.FindAsync(new ComparableIntClassKey(104))); + Assert.Same( + dependents[3], await context.FindAsync(new ComparableIntClassKey(104))); Assert.Same( dependents[4], await context.FindAsync(new ComparableIntClassKey(oneOhFive))); Assert.Same(dependents[5], await context.FindAsync(oneOhSix)); @@ -4131,7 +4158,8 @@ await context.Set().SingleAsync(e => e.Id Assert.Same( dependents[3], await context.FindAsync(typeof(BytesStructKeyOptionalDependentShadow), new BytesStructKey { Id = [104] })); - Assert.Same(dependents[4], await context.FindAsync(typeof(BytesStructKeyOptionalDependentShadow), new BytesStructKey(oneOhFive))); + Assert.Same( + dependents[4], await context.FindAsync(typeof(BytesStructKeyOptionalDependentShadow), new BytesStructKey(oneOhFive))); Assert.Same(dependents[5], await context.FindAsync(typeof(BytesStructKeyOptionalDependentShadow), oneOhSix)); } @@ -4216,10 +4244,7 @@ public virtual async Task Can_insert_and_read_back_with_structural_struct_binary { Id = new StructuralComparableBytesStructKey([105]), Principal = principals0[2] }, - new StructuralComparableBytesStructKeyOptionalDependentShadow - { - Id = new StructuralComparableBytesStructKey([106]) - }); + new StructuralComparableBytesStructKeyOptionalDependentShadow { Id = new StructuralComparableBytesStructKey([106]) }); Assert.Equal(10, await context.SaveChangesAsync()); } @@ -4322,7 +4347,8 @@ await context.Set() dependents[1], await context.Set() .FindAsync(new StructuralComparableBytesStructKey(oneOhTwo))); - Assert.Same(dependents[2], await context.Set().FindAsync(oneOhThree)); + Assert.Same( + dependents[2], await context.Set().FindAsync(oneOhThree)); Assert.Same( dependents[3], await context.FindAsync( @@ -4333,7 +4359,8 @@ await context.FindAsync( await context.FindAsync( typeof(StructuralComparableBytesStructKeyOptionalDependentShadow), new StructuralComparableBytesStructKey(oneOhFive))); - Assert.Same(dependents[5], await context.FindAsync(typeof(StructuralComparableBytesStructKeyOptionalDependentShadow), oneOhSix)); + Assert.Same( + dependents[5], await context.FindAsync(typeof(StructuralComparableBytesStructKeyOptionalDependentShadow), oneOhSix)); } void Validate( @@ -4606,10 +4633,7 @@ public virtual async Task Can_insert_and_read_back_with_generic_comparable_struc { Id = new GenericComparableBytesStructKey([105]), Principal = principals0[2] }, - new GenericComparableBytesStructKeyOptionalDependentShadow - { - Id = new GenericComparableBytesStructKey([106]) - }); + new GenericComparableBytesStructKeyOptionalDependentShadow { Id = new GenericComparableBytesStructKey([106]) }); Assert.Equal(10, await context.SaveChangesAsync()); } @@ -4890,7 +4914,8 @@ await context.Set().FirstOrDefaultAsync(e dependents[3], await context.FindAsync(typeof(BytesStructKeyRequiredDependentShadow), new BytesStructKey { Id = [114] })); Assert.Same( - dependents[4], await context.FindAsync(typeof(BytesStructKeyRequiredDependentShadow), new BytesStructKey { Id = oneFifteeen })); + dependents[4], + await context.FindAsync(typeof(BytesStructKeyRequiredDependentShadow), new BytesStructKey { Id = oneFifteeen })); Assert.Same(dependents[5], await context.FindAsync(typeof(BytesStructKeyRequiredDependentShadow), oneSixteen)); } @@ -5075,7 +5100,8 @@ await context.Set() .FindAsync(new ComparableBytesStructKey { Id = [111] })); Assert.Same( dependents[1], - await context.Set().FindAsync(new ComparableBytesStructKey { Id = oneTwelve })); + await context.Set() + .FindAsync(new ComparableBytesStructKey { Id = oneTwelve })); Assert.Same(dependents[2], await context.Set().FindAsync(oneThirteen)); Assert.Same( dependents[3], @@ -5260,12 +5286,14 @@ await context.Set() .FirstOrDefaultAsync(e => e.Id.Equals(new StructuralComparableBytesStructKey { Id = new byte[] { 111 } })), await context.Set() .FirstOrDefaultAsync(e => e.Id.Equals(new StructuralComparableBytesStructKey { Id = oneTwelve })), - await context.Set().FirstOrDefaultAsync(e => e.Id.Equals(oneThirteen)), + await context.Set() + .FirstOrDefaultAsync(e => e.Id.Equals(oneThirteen)), await context.Set() .FirstOrDefaultAsync(e => e.Id.Equals(new StructuralComparableBytesStructKey { Id = new byte[] { 114 } })), await context.Set() .FirstOrDefaultAsync(e => e.Id.Equals(new StructuralComparableBytesStructKey { Id = oneFifteeen })), - await context.Set().FirstOrDefaultAsync(e => e.Id.Equals(oneSixteen)) + await context.Set() + .FirstOrDefaultAsync(e => e.Id.Equals(oneSixteen)) ]; Assert.Same( @@ -5276,7 +5304,8 @@ await context.Set() dependents[1], await context.Set() .FindAsync(new StructuralComparableBytesStructKey { Id = oneTwelve })); - Assert.Same(dependents[2], await context.Set().FindAsync(oneThirteen)); + Assert.Same( + dependents[2], await context.Set().FindAsync(oneThirteen)); Assert.Same( dependents[3], await context.FindAsync( @@ -5287,7 +5316,8 @@ await context.FindAsync( await context.FindAsync( typeof(StructuralComparableBytesStructKeyRequiredDependentShadow), new StructuralComparableBytesStructKey { Id = oneFifteeen })); - Assert.Same(dependents[5], await context.FindAsync(typeof(StructuralComparableBytesStructKeyRequiredDependentShadow), oneSixteen)); + Assert.Same( + dependents[5], await context.FindAsync(typeof(StructuralComparableBytesStructKeyRequiredDependentShadow), oneSixteen)); } void Validate( @@ -5462,12 +5492,14 @@ await context.Set() .FirstOrDefaultAsync(e => e.Id.Equals(new GenericComparableBytesStructKey { Id = new byte[] { 111 } })), await context.Set() .FirstOrDefaultAsync(e => e.Id.Equals(new GenericComparableBytesStructKey { Id = oneTwelve })), - await context.Set().FirstOrDefaultAsync(e => e.Id.Equals(oneThirteen)), + await context.Set() + .FirstOrDefaultAsync(e => e.Id.Equals(oneThirteen)), await context.Set() .FirstOrDefaultAsync(e => e.Id.Equals(new GenericComparableBytesStructKey { Id = new byte[] { 114 } })), await context.Set() .FirstOrDefaultAsync(e => e.Id.Equals(new GenericComparableBytesStructKey { Id = oneFifteeen })), - await context.Set().FirstOrDefaultAsync(e => e.Id.Equals(oneSixteen)) + await context.Set() + .FirstOrDefaultAsync(e => e.Id.Equals(oneSixteen)) ]; Assert.Same( diff --git a/test/EFCore.Specification.Tests/LazyLoadProxyTestBase.cs b/test/EFCore.Specification.Tests/LazyLoadProxyTestBase.cs index 978261d356c..2012b95f63d 100644 --- a/test/EFCore.Specification.Tests/LazyLoadProxyTestBase.cs +++ b/test/EFCore.Specification.Tests/LazyLoadProxyTestBase.cs @@ -4533,9 +4533,7 @@ protected Applicant() } public Applicant(FullName name) - { - Name = name ?? throw new ArgumentNullException(nameof(name)); - } + => Name = name ?? throw new ArgumentNullException(nameof(name)); } public class FirstName @@ -4547,9 +4545,7 @@ protected FirstName() } private FirstName(string value) - { - _value = value; - } + => _value = value; public static FirstName Create(string firstName) => new(firstName); @@ -4564,9 +4560,7 @@ protected LastName() } private LastName(string value) - { - _value = value; - } + => _value = value; public static LastName Create(string lastName) => new(lastName); @@ -4583,9 +4577,7 @@ protected Pyrson() } public Pyrson(FullName name) - { - Name = name ?? throw new ArgumentNullException(nameof(name)); - } + => Name = name ?? throw new ArgumentNullException(nameof(name)); public virtual Culture Culture { get; set; } public virtual Milk Milk { get; set; } = null!; diff --git a/test/EFCore.Specification.Tests/LoadTestBase.cs b/test/EFCore.Specification.Tests/LoadTestBase.cs index 709858621b2..c9c97a3a2a8 100644 --- a/test/EFCore.Specification.Tests/LoadTestBase.cs +++ b/test/EFCore.Specification.Tests/LoadTestBase.cs @@ -5353,9 +5353,7 @@ public Parent Parent protected abstract class RootClass { protected RootClass(Action lazyLoader) - { - LazyLoader = lazyLoader; - } + => LazyLoader = lazyLoader; protected RootClass() { @@ -5422,9 +5420,7 @@ public OptionalChildView() } public OptionalChildView(Action lazyLoader) - { - _loader = lazyLoader; - } + => _loader = lazyLoader; public int? RootId { get; set; } @@ -5445,9 +5441,7 @@ public RequiredChildView() } public RequiredChildView(Action lazyLoader) - { - _loader = lazyLoader; - } + => _loader = lazyLoader; public int RootId { get; set; } @@ -5469,9 +5463,7 @@ public ParentFullLoaderByConstructor() } private ParentFullLoaderByConstructor(ILazyLoader loader) - { - _loader = loader; - } + => _loader = loader; [DatabaseGenerated(DatabaseGeneratedOption.None)] public int Id { get; set; } @@ -5521,9 +5513,7 @@ public ChildFullLoaderByConstructor() } public ChildFullLoaderByConstructor(ILazyLoader loader) - { - _loader = loader; - } + => _loader = loader; [DatabaseGenerated(DatabaseGeneratedOption.None)] public int Id { get; set; } @@ -5558,9 +5548,7 @@ public SingleFullLoaderByConstructor() } public SingleFullLoaderByConstructor(ILazyLoader loader) - { - _loader = loader; - } + => _loader = loader; [DatabaseGenerated(DatabaseGeneratedOption.None)] public int Id { get; set; } @@ -5596,9 +5584,7 @@ public ParentDelegateLoaderByConstructor() } private ParentDelegateLoaderByConstructor(Action lazyLoader) - { - _loader = lazyLoader; - } + => _loader = lazyLoader; [DatabaseGenerated(DatabaseGeneratedOption.None)] public int Id { get; set; } @@ -5627,9 +5613,7 @@ public ChildDelegateLoaderByConstructor() } private ChildDelegateLoaderByConstructor(Action lazyLoader) - { - _loader = lazyLoader; - } + => _loader = lazyLoader; [DatabaseGenerated(DatabaseGeneratedOption.None)] public int Id { get; set; } @@ -5665,9 +5649,7 @@ public SingleDelegateLoaderByConstructor() } private SingleDelegateLoaderByConstructor(Action lazyLoader) - { - _loader = lazyLoader; - } + => _loader = lazyLoader; [DatabaseGenerated(DatabaseGeneratedOption.None)] public int Id { get; set; } diff --git a/test/EFCore.Specification.Tests/ManyToManyTrackingTestBase.cs b/test/EFCore.Specification.Tests/ManyToManyTrackingTestBase.cs index 6a0e444e4d1..4c008887538 100644 --- a/test/EFCore.Specification.Tests/ManyToManyTrackingTestBase.cs +++ b/test/EFCore.Specification.Tests/ManyToManyTrackingTestBase.cs @@ -594,8 +594,10 @@ public virtual Task Can_update_many_to_many_composite_shared_with_navs() return ExecuteWithStrategyInTransactionAsync( async context => { - var leftEntities = await context.Set().Include(e => e.RootSkipShared).OrderBy(e => e.Key2).ToListAsync(); - var rightEntities = await context.Set().Include(e => e.CompositeKeySkipShared).OrderBy(e => e.Name).ToListAsync(); + var leftEntities = await context.Set().Include(e => e.RootSkipShared).OrderBy(e => e.Key2) + .ToListAsync(); + var rightEntities = await context.Set().Include(e => e.CompositeKeySkipShared).OrderBy(e => e.Name) + .ToListAsync(); var roots = new[] { @@ -687,8 +689,10 @@ public virtual Task Can_update_many_to_many_composite_shared_with_navs() ValidateFixup(context, leftEntities, rightEntities, 24, 24, 47 - 4); }, async context => { - var leftEntities = await context.Set().Include(e => e.RootSkipShared).OrderBy(e => e.Key2).ToListAsync(); - var rightEntities = await context.Set().Include(e => e.CompositeKeySkipShared).OrderBy(e => e.Name).ToListAsync(); + var leftEntities = await context.Set().Include(e => e.RootSkipShared).OrderBy(e => e.Key2) + .ToListAsync(); + var rightEntities = await context.Set().Include(e => e.CompositeKeySkipShared).OrderBy(e => e.Name) + .ToListAsync(); ValidateFixup(context, leftEntities, rightEntities, 24, 24, 47 - 4); }); @@ -1018,7 +1022,8 @@ public virtual Task Can_update_many_to_many_composite_additional_pk_with_navs() async context => { var leftEntities = await context.Set().Include(e => e.ThreeSkipFull).OrderBy(e => e.Key2).ToListAsync(); - var rightEntities = await context.Set().Include(e => e.CompositeKeySkipFull).OrderBy(e => e.Name).ToListAsync(); + var rightEntities = + await context.Set().Include(e => e.CompositeKeySkipFull).OrderBy(e => e.Name).ToListAsync(); var threes = new[] { @@ -1116,7 +1121,8 @@ public virtual Task Can_update_many_to_many_composite_additional_pk_with_navs() }, async context => { var leftEntities = await context.Set().Include(e => e.ThreeSkipFull).OrderBy(e => e.Key2).ToListAsync(); - var rightEntities = await context.Set().Include(e => e.CompositeKeySkipFull).OrderBy(e => e.Name).ToListAsync(); + var rightEntities = + await context.Set().Include(e => e.CompositeKeySkipFull).OrderBy(e => e.Name).ToListAsync(); ValidateFixup(context, leftEntities, rightEntities, 24, 24, 53 - 4); }); @@ -2551,8 +2557,10 @@ public virtual Task Can_update_many_to_many_shared_with_payload() return ExecuteWithStrategyInTransactionAsync( async context => { - var leftEntities = await context.Set().Include(e => e.ThreeSkipPayloadFullShared).OrderBy(e => e.Name).ToListAsync(); - var rightEntities = await context.Set().Include(e => e.OneSkipPayloadFullShared).OrderBy(e => e.Name).ToListAsync(); + var leftEntities = await context.Set().Include(e => e.ThreeSkipPayloadFullShared).OrderBy(e => e.Name) + .ToListAsync(); + var rightEntities = await context.Set().Include(e => e.OneSkipPayloadFullShared).OrderBy(e => e.Name) + .ToListAsync(); leftEntities[0].ThreeSkipPayloadFullShared.Add( context.EntityThrees.CreateInstance( @@ -2643,8 +2651,10 @@ public virtual Task Can_update_many_to_many_shared_with_payload() ValidateFixup(context, leftEntities, rightEntities, 24, 24, 48 - 4, postSave: true); }, async context => { - var leftEntities = await context.Set().Include(e => e.ThreeSkipPayloadFullShared).OrderBy(e => e.Name).ToListAsync(); - var rightEntities = await context.Set().Include(e => e.OneSkipPayloadFullShared).OrderBy(e => e.Name).ToListAsync(); + var leftEntities = await context.Set().Include(e => e.ThreeSkipPayloadFullShared).OrderBy(e => e.Name) + .ToListAsync(); + var rightEntities = await context.Set().Include(e => e.OneSkipPayloadFullShared).OrderBy(e => e.Name) + .ToListAsync(); ValidateFixup(context, leftEntities, rightEntities, 24, 24, 48 - 4, postSave: true); }); diff --git a/test/EFCore.Specification.Tests/ModelBuilding/GiantModel.cs b/test/EFCore.Specification.Tests/ModelBuilding/GiantModel.cs index 32db7483401..2784a30ee9f 100644 --- a/test/EFCore.Specification.Tests/ModelBuilding/GiantModel.cs +++ b/test/EFCore.Specification.Tests/ModelBuilding/GiantModel.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // + namespace Microsoft.EntityFrameworkCore.ModelBuilding; public static class GiantModel diff --git a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.ComplexType.cs b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.ComplexType.cs index caa9480ca54..ac2c52eb438 100644 --- a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.ComplexType.cs +++ b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.ComplexType.cs @@ -2077,8 +2077,8 @@ public virtual void Can_set_sentinel_for_primitive_collections() Assert.Null(complexType.FindProperty("Up")!.Sentinel); Assert.Equal(new ObservableCollection(), complexType.FindProperty("Down")!.Sentinel); Assert.Equal(Array.Empty(), complexType.FindProperty("Charm")!.Sentinel); - Assert.Equal(new List { }, complexType.FindProperty("Strange")!.Sentinel); - Assert.Equal(new int[] { 77 }, complexType.FindProperty("Top")!.Sentinel); + Assert.Equal(new List(), complexType.FindProperty("Strange")!.Sentinel); + Assert.Equal(new[] { 77 }, complexType.FindProperty("Top")!.Sentinel); Assert.Equal(new List { "" }, complexType.FindProperty("Bottom")!.Sentinel); } @@ -2168,22 +2168,23 @@ public virtual void PrimitiveCollectionBuilder_methods_can_be_chained() .Entity() .ComplexProperty(e => e.CollectionQuarks) .PrimitiveCollection(e => e.Up) - .ElementType(t => t - .HasAnnotation("B", "C") - .HasConversion(typeof(long)) - .HasConversion(new CastingConverter()) - .HasConversion(typeof(long), typeof(CustomValueComparer)) - .HasConversion(typeof(long), new CustomValueComparer()) - .HasConversion(new CastingConverter()) - .HasConversion(new CastingConverter(), new CustomValueComparer()) - .HasConversion() - .HasConversion(new CustomValueComparer()) - .HasConversion>() - .HasMaxLength(2) - .HasPrecision(1) - .HasPrecision(1, 2) - .IsRequired() - .IsUnicode()) + .ElementType( + t => t + .HasAnnotation("B", "C") + .HasConversion(typeof(long)) + .HasConversion(new CastingConverter()) + .HasConversion(typeof(long), typeof(CustomValueComparer)) + .HasConversion(typeof(long), new CustomValueComparer()) + .HasConversion(new CastingConverter()) + .HasConversion(new CastingConverter(), new CustomValueComparer()) + .HasConversion() + .HasConversion(new CustomValueComparer()) + .HasConversion>() + .HasMaxLength(2) + .HasPrecision(1) + .HasPrecision(1, 2) + .IsRequired() + .IsUnicode()) .IsRequired() .HasAnnotation("A", "V") .IsConcurrencyToken() diff --git a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.Generic.cs b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.Generic.cs index 98877a481a7..abacffdbb5c 100644 --- a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.Generic.cs +++ b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.Generic.cs @@ -2,11 +2,13 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable InconsistentNaming + namespace Microsoft.EntityFrameworkCore.ModelBuilding; public abstract partial class ModelBuilderTest { - public class GenericTestModelBuilder(ModelBuilderFixtureBase fixture, Action? configure) : TestModelBuilder(fixture, configure) + public class GenericTestModelBuilder(ModelBuilderFixtureBase fixture, Action? configure) + : TestModelBuilder(fixture, configure) { public override TestEntityTypeBuilder Entity() => new GenericTestEntityTypeBuilder(ModelBuilder.Entity()); @@ -41,7 +43,8 @@ public override TestModelBuilder Ignore() } } - protected class GenericTestEntityTypeBuilder(EntityTypeBuilder entityTypeBuilder) : TestEntityTypeBuilder, IInfrastructure> + protected class GenericTestEntityTypeBuilder(EntityTypeBuilder entityTypeBuilder) + : TestEntityTypeBuilder, IInfrastructure> where TEntity : class { protected EntityTypeBuilder EntityTypeBuilder { get; } = entityTypeBuilder; @@ -454,7 +457,8 @@ public ComplexPropertyBuilder Instance => PropertyBuilder; } - protected class GenericTestDiscriminatorBuilder(DiscriminatorBuilder discriminatorBuilder) : TestDiscriminatorBuilder + protected class GenericTestDiscriminatorBuilder(DiscriminatorBuilder discriminatorBuilder) + : TestDiscriminatorBuilder { protected DiscriminatorBuilder DiscriminatorBuilder { get; } = discriminatorBuilder; @@ -477,8 +481,9 @@ public override TestDiscriminatorBuilder HasValue(string entityT => Wrap(DiscriminatorBuilder.HasValue(entityTypeName, value)); } - protected class GenericTestOwnedEntityTypeBuilder(OwnedEntityTypeBuilder ownedEntityTypeBuilder) : TestOwnedEntityTypeBuilder, - IInfrastructure> + protected class GenericTestOwnedEntityTypeBuilder(OwnedEntityTypeBuilder ownedEntityTypeBuilder) + : TestOwnedEntityTypeBuilder, + IInfrastructure> where TEntity : class { protected OwnedEntityTypeBuilder OwnedEntityTypeBuilder { get; } = ownedEntityTypeBuilder; @@ -487,7 +492,8 @@ public OwnedEntityTypeBuilder Instance => OwnedEntityTypeBuilder; } - protected class GenericTestPropertyBuilder(PropertyBuilder propertyBuilder) : TestPropertyBuilder, IInfrastructure> + protected class GenericTestPropertyBuilder(PropertyBuilder propertyBuilder) + : TestPropertyBuilder, IInfrastructure> { protected PropertyBuilder PropertyBuilder { get; } = propertyBuilder; @@ -850,7 +856,8 @@ ComplexTypePropertyBuilder IInfrastructure PropertyBuilder; } - protected class GenericTestComplexTypePrimitiveCollectionBuilder(ComplexTypePrimitiveCollectionBuilder primitiveCollectionBuilder) : + protected class GenericTestComplexTypePrimitiveCollectionBuilder( + ComplexTypePrimitiveCollectionBuilder primitiveCollectionBuilder) : TestComplexTypePrimitiveCollectionBuilder, IInfrastructure> { @@ -921,7 +928,8 @@ ComplexTypePrimitiveCollectionBuilder IInfrastructure PrimitiveCollectionBuilder; } - protected class GenericTestKeyBuilder(KeyBuilder keyBuilder) : TestKeyBuilder, IInfrastructure> + protected class GenericTestKeyBuilder(KeyBuilder keyBuilder) + : TestKeyBuilder, IInfrastructure> { private KeyBuilder KeyBuilder { get; } = keyBuilder; @@ -935,7 +943,8 @@ KeyBuilder IInfrastructure>.Instance => KeyBuilder; } - protected class GenericTestIndexBuilder(IndexBuilder indexBuilder) : TestIndexBuilder, IInfrastructure> + protected class GenericTestIndexBuilder(IndexBuilder indexBuilder) + : TestIndexBuilder, IInfrastructure> { private IndexBuilder IndexBuilder { get; } = indexBuilder; @@ -955,7 +964,8 @@ IndexBuilder IInfrastructure>.Instance => IndexBuilder; } - protected class GenericTestNavigationBuilder(NavigationBuilder navigationBuilder) : TestNavigationBuilder + protected class GenericTestNavigationBuilder(NavigationBuilder navigationBuilder) + : TestNavigationBuilder where TSource : class where TTarget : class { @@ -981,7 +991,9 @@ public override TestNavigationBuilder IsRequired(bool required = true) } protected class - GenericTestReferenceNavigationBuilder(ReferenceNavigationBuilder referenceNavigationBuilder) : TestReferenceNavigationBuilder + GenericTestReferenceNavigationBuilder( + ReferenceNavigationBuilder referenceNavigationBuilder) + : TestReferenceNavigationBuilder where TEntity : class where TRelatedEntity : class { @@ -1006,7 +1018,8 @@ public override TestReferenceReferenceBuilder WithOne( ReferenceNavigationBuilder.WithOne(navigationExpression)); } - protected class GenericTestCollectionNavigationBuilder(CollectionNavigationBuilder collectionNavigationBuilder) : + protected class GenericTestCollectionNavigationBuilder( + CollectionNavigationBuilder collectionNavigationBuilder) : TestCollectionNavigationBuilder where TEntity : class where TRelatedEntity : class @@ -1033,7 +1046,8 @@ public override TestCollectionCollectionBuilder WithMan CollectionNavigationBuilder.WithMany(navigationExpression)); } - protected class GenericTestReferenceCollectionBuilder(ReferenceCollectionBuilder referenceCollectionBuilder) + protected class GenericTestReferenceCollectionBuilder( + ReferenceCollectionBuilder referenceCollectionBuilder) : TestReferenceCollectionBuilder where TEntity : class where TRelatedEntity : class @@ -1071,7 +1085,8 @@ public override TestReferenceCollectionBuilder OnDelete => Wrap(ReferenceCollectionBuilder.OnDelete(deleteBehavior)); } - protected class GenericTestReferenceReferenceBuilder(ReferenceReferenceBuilder referenceReferenceBuilder) : + protected class GenericTestReferenceReferenceBuilder( + ReferenceReferenceBuilder referenceReferenceBuilder) : TestReferenceReferenceBuilder where TEntity : class where TRelatedEntity : class @@ -1336,7 +1351,8 @@ OwnershipBuilder IInfrastructure OwnershipBuilder; } - protected class GenericTestOwnedNavigationBuilder(OwnedNavigationBuilder ownedNavigationBuilder) + protected class GenericTestOwnedNavigationBuilder( + OwnedNavigationBuilder ownedNavigationBuilder) : TestOwnedNavigationBuilder, IInfrastructure> where TEntity : class @@ -1407,9 +1423,17 @@ public override TestOwnedNavigationBuilder Ignore( public override TestIndexBuilder HasIndex(params string[] propertyNames) => new GenericTestIndexBuilder(OwnedNavigationBuilder.HasIndex(propertyNames)); + public override TestIndexBuilder HasIndex(string[] propertyNames, string name) + => new GenericTestIndexBuilder(OwnedNavigationBuilder.HasIndex(propertyNames, name)); + public override TestIndexBuilder HasIndex(Expression> indexExpression) => new GenericTestIndexBuilder(OwnedNavigationBuilder.HasIndex(indexExpression)); + public override TestIndexBuilder HasIndex( + Expression> indexExpression, + string name) + => new GenericTestIndexBuilder(OwnedNavigationBuilder.HasIndex(indexExpression, name)); + public override TestOwnershipBuilder WithOwner(string? ownerReference) => new GenericTestOwnershipBuilder( OwnedNavigationBuilder.WithOwner(ownerReference)); diff --git a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.Inheritance.cs b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.Inheritance.cs index 1534c3600e4..6cc741e6d46 100644 --- a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.Inheritance.cs +++ b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.Inheritance.cs @@ -148,7 +148,8 @@ public virtual void Can_set_and_remove_base_type() Fixture.TestHelpers.ModelAsserter.AssertEqual( initialProperties.Where(p => p.Name != "Discriminator"), actualProperties.Where(p => p.Name != "Discriminator")); - Assert.Equal(initialKeys, pickle.GetKeys(), + Assert.Equal( + initialKeys, pickle.GetKeys(), (expected, actual) => { Fixture.TestHelpers.ModelAsserter.AssertEqual( @@ -179,7 +180,8 @@ public virtual void Can_set_and_remove_base_type() Fixture.TestHelpers.ModelAsserter.AssertEqual( initialProperties.Where(p => p.Name != "Discriminator"), actualProperties.Where(p => p.Name != "Discriminator")); - Assert.Equal(initialKeys, ingredient.GetKeys(), + Assert.Equal( + initialKeys, ingredient.GetKeys(), (expected, actual) => { Fixture.TestHelpers.ModelAsserter.AssertEqual( diff --git a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.ManyToMany.cs b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.ManyToMany.cs index 0264ca3532c..1681985a01f 100644 --- a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.ManyToMany.cs +++ b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.ManyToMany.cs @@ -728,7 +728,8 @@ public virtual void ForeignKeyAttribute_does_not_force_convention_join_table_inc Assert.Equal(3, model.GetEntityTypes().Count()); - Assert.Collection(model.GetEntityTypes(), + Assert.Collection( + model.GetEntityTypes(), e => { Assert.Equal("MotorArtMatching", e.ShortName()); @@ -748,7 +749,8 @@ public virtual void ForeignKeyAttribute_does_not_force_convention_join_table_inc e => { Assert.Equal("MotorArtXMotorBauartMatching", e.ShortName()); - Assert.Collection(e.GetForeignKeys(), + Assert.Collection( + e.GetForeignKeys(), k => { Assert.Equal("MotorArtMatching", k.PrincipalEntityType.ShortName()); @@ -800,7 +802,8 @@ public virtual void ForeignKeyAttribute_does_not_force_convention_join_table_inc Assert.Equal(3, model.GetEntityTypes().Count()); - Assert.Collection(model.GetEntityTypes(), + Assert.Collection( + model.GetEntityTypes(), e => { Assert.Equal("MotorArtMismatching", e.ShortName()); @@ -820,7 +823,8 @@ public virtual void ForeignKeyAttribute_does_not_force_convention_join_table_inc e => { Assert.Equal("MotorArtXMotorBauartMismatching", e.ShortName()); - Assert.Collection(e.GetForeignKeys(), + Assert.Collection( + e.GetForeignKeys(), k => { Assert.Equal("MotorArtMismatching", k.PrincipalEntityType.ShortName()); diff --git a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.ManyToOne.cs b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.ManyToOne.cs index 0746bb93847..2f33dcf9f0c 100644 --- a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.ManyToOne.cs +++ b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.ManyToOne.cs @@ -1902,7 +1902,6 @@ public virtual void Creates_relationship_on_existing_FK_is_using_different_princ Assert.Empty(dependentType.GetIndexes()); } - Assert.Equal( CoreStrings.AmbiguousOneToOneRelationship( existingFk.DeclaringEntityType.DisplayName() + "." + existingFk.DependentToPrincipal.Name, diff --git a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.NonGeneric.cs b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.NonGeneric.cs index 1cea14c05df..ccd94bd3435 100644 --- a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.NonGeneric.cs +++ b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.NonGeneric.cs @@ -1,13 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Reflection; - namespace Microsoft.EntityFrameworkCore.ModelBuilding; public abstract partial class ModelBuilderTest { - public class NonGenericTestModelBuilder(ModelBuilderFixtureBase fixture, Action? configure) : TestModelBuilder(fixture, configure) + public class NonGenericTestModelBuilder(ModelBuilderFixtureBase fixture, Action? configure) + : TestModelBuilder(fixture, configure) { public override TestEntityTypeBuilder Entity() => new NonGenericTestEntityTypeBuilder(ModelBuilder.Entity(typeof(TEntity))); @@ -42,7 +41,8 @@ public override TestModelBuilder Ignore() } } - protected class NonGenericTestEntityTypeBuilder(EntityTypeBuilder entityTypeBuilder) : TestEntityTypeBuilder, IInfrastructure + protected class NonGenericTestEntityTypeBuilder(EntityTypeBuilder entityTypeBuilder) + : TestEntityTypeBuilder, IInfrastructure where TEntity : class { protected EntityTypeBuilder EntityTypeBuilder { get; } = entityTypeBuilder; @@ -525,7 +525,8 @@ public ComplexPropertyBuilder Instance => PropertyBuilder; } - protected class NonGenericTestDiscriminatorBuilder(DiscriminatorBuilder discriminatorBuilder) : TestDiscriminatorBuilder + protected class NonGenericTestDiscriminatorBuilder(DiscriminatorBuilder discriminatorBuilder) + : TestDiscriminatorBuilder { protected DiscriminatorBuilder DiscriminatorBuilder { get; } = discriminatorBuilder; @@ -548,8 +549,9 @@ public override TestDiscriminatorBuilder HasValue(string entityT => Wrap(DiscriminatorBuilder.HasValue(entityTypeName, value)); } - protected class NonGenericTestOwnedEntityTypeBuilder(OwnedEntityTypeBuilder ownedEntityTypeBuilder) : TestOwnedEntityTypeBuilder, - IInfrastructure + protected class NonGenericTestOwnedEntityTypeBuilder(OwnedEntityTypeBuilder ownedEntityTypeBuilder) + : TestOwnedEntityTypeBuilder, + IInfrastructure where TEntity : class { protected OwnedEntityTypeBuilder OwnedEntityTypeBuilder { get; } = ownedEntityTypeBuilder; @@ -558,7 +560,8 @@ public OwnedEntityTypeBuilder Instance => OwnedEntityTypeBuilder; } - protected class NonGenericTestPropertyBuilder(PropertyBuilder propertyBuilder) : TestPropertyBuilder, IInfrastructure + protected class NonGenericTestPropertyBuilder(PropertyBuilder propertyBuilder) + : TestPropertyBuilder, IInfrastructure { private PropertyBuilder PropertyBuilder { get; } = propertyBuilder; @@ -703,8 +706,9 @@ PropertyBuilder IInfrastructure.Instance => PropertyBuilder; } - protected class NonGenericTestPrimitiveCollectionBuilder(PrimitiveCollectionBuilder primitiveCollectionBuilder) : TestPrimitiveCollectionBuilder, - IInfrastructure + protected class NonGenericTestPrimitiveCollectionBuilder(PrimitiveCollectionBuilder primitiveCollectionBuilder) + : TestPrimitiveCollectionBuilder, + IInfrastructure { private PrimitiveCollectionBuilder PrimitiveCollectionBuilder { get; } = primitiveCollectionBuilder; @@ -915,7 +919,8 @@ ComplexTypePropertyBuilder IInfrastructure.Instance => PropertyBuilder; } - protected class NonGenericTestComplexTypePrimitiveCollectionBuilder(ComplexTypePrimitiveCollectionBuilder primitiveCollectionBuilder) : + protected class NonGenericTestComplexTypePrimitiveCollectionBuilder( + ComplexTypePrimitiveCollectionBuilder primitiveCollectionBuilder) : TestComplexTypePrimitiveCollectionBuilder, IInfrastructure { @@ -1023,7 +1028,8 @@ KeyBuilder IInfrastructure.Instance => KeyBuilder; } - protected class NonGenericTestIndexBuilder(IndexBuilder indexBuilder) : TestIndexBuilder, IInfrastructure + protected class NonGenericTestIndexBuilder(IndexBuilder indexBuilder) + : TestIndexBuilder, IInfrastructure { private IndexBuilder IndexBuilder { get; } = indexBuilder; @@ -1044,7 +1050,8 @@ IndexBuilder IInfrastructure.Instance } protected class - NonGenericTestReferenceNavigationBuilder(ReferenceNavigationBuilder referenceNavigationBuilder) : TestReferenceNavigationBuilder + NonGenericTestReferenceNavigationBuilder(ReferenceNavigationBuilder referenceNavigationBuilder) + : TestReferenceNavigationBuilder where TEntity : class where TRelatedEntity : class { @@ -1071,7 +1078,8 @@ public override TestReferenceReferenceBuilder WithOne( navigationExpression?.GetMemberAccess().GetSimpleMemberName())); } - protected class NonGenericTestCollectionNavigationBuilder(CollectionNavigationBuilder collectionNavigationBuilder) + protected class NonGenericTestCollectionNavigationBuilder( + CollectionNavigationBuilder collectionNavigationBuilder) : TestCollectionNavigationBuilder where TEntity : class where TRelatedEntity : class @@ -1143,7 +1151,8 @@ public override TestReferenceCollectionBuilder OnDelete } protected class - NonGenericTestReferenceReferenceBuilder(ReferenceReferenceBuilder referenceReferenceBuilder) : TestReferenceReferenceBuilder + NonGenericTestReferenceReferenceBuilder(ReferenceReferenceBuilder referenceReferenceBuilder) + : TestReferenceReferenceBuilder where TEntity : class where TRelatedEntity : class { @@ -1187,7 +1196,8 @@ public override TestReferenceReferenceBuilder OnDelete( => Wrap(ReferenceReferenceBuilder.OnDelete(deleteBehavior)); } - protected class NonGenericTestCollectionCollectionBuilder(CollectionCollectionBuilder collectionCollectionBuilder) : + protected class NonGenericTestCollectionCollectionBuilder( + CollectionCollectionBuilder collectionCollectionBuilder) : TestCollectionCollectionBuilder where TLeftEntity : class where TRightEntity : class @@ -1482,11 +1492,21 @@ public override TestOwnedNavigationBuilder Ignore( public override TestIndexBuilder HasIndex(params string[] propertyNames) => new NonGenericTestIndexBuilder(OwnedNavigationBuilder.HasIndex(propertyNames)); + public override TestIndexBuilder HasIndex(string[] propertyNames, string name) + => new NonGenericTestIndexBuilder(OwnedNavigationBuilder.HasIndex(propertyNames, name)); + public override TestIndexBuilder HasIndex(Expression> indexExpression) => new NonGenericTestIndexBuilder( OwnedNavigationBuilder.HasIndex( indexExpression.GetMemberAccessList().Select(p => p.GetSimpleMemberName()).ToArray())); + public override TestIndexBuilder HasIndex( + Expression> indexExpression, + string name) + => new NonGenericTestIndexBuilder( + OwnedNavigationBuilder.HasIndex( + indexExpression.GetMemberAccessList().Select(p => p.GetSimpleMemberName()).ToArray(), name)); + public override TestOwnershipBuilder WithOwner(string? ownerReference) => new NonGenericTestOwnershipBuilder( OwnedNavigationBuilder.WithOwner(ownerReference)); diff --git a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.NonRelationship.cs b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.NonRelationship.cs index c46e75bc8c3..32cc4eb4675 100644 --- a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.NonRelationship.cs +++ b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.NonRelationship.cs @@ -468,7 +468,8 @@ public void ProcessModelInitialized( => modelBuilder.HasAnnotation("foo", "bar"); } - protected class TestDbSetFindingConvention(ProviderConventionSetBuilderDependencies dependencies) : DbSetFindingConvention(dependencies) + protected class TestDbSetFindingConvention(ProviderConventionSetBuilderDependencies dependencies) + : DbSetFindingConvention(dependencies) { public override void ProcessModelInitialized( IConventionModelBuilder modelBuilder, @@ -1397,7 +1398,7 @@ public virtual void Can_set_sentinel_for_properties() { b.Property(e => e.Up).HasSentinel(1); b.Property(e => e.Down).HasSentinel("100"); - b.Property("Charm").HasSentinel((sbyte)-1); + b.Property("Charm").HasSentinel(-1); b.Property("Strange").HasSentinel(""); b.Property("Top").HasSentinel(77); b.Property("Bottom").HasSentinel(null); @@ -1425,7 +1426,8 @@ public virtual void Setting_sentinel_throws_for_null_on_nonnullable() { b.Property("Top").Metadata.Sentinel = 77D; b.Property("Charm").Metadata.Sentinel = EnumerablePartitionerOptions.NoBuffering; - Assert.Equal(CoreStrings.IncompatibleSentinelValue("null", nameof(Quarks), nameof(Quarks.Up), "int"), + Assert.Equal( + CoreStrings.IncompatibleSentinelValue("null", nameof(Quarks), nameof(Quarks.Up), "int"), Assert.Throws(() => b.Property(e => e.Up).Metadata.Sentinel = null).Message); }); } @@ -1438,8 +1440,10 @@ public virtual void Setting_sentinel_throws_for_noncompatible() modelBuilder.Entity( b => { - Assert.Equal(CoreStrings.IncompatibleSentinelValue("System.Byte[]", nameof(Quarks), nameof(Quarks.Up), "int"), - Assert.Throws(() => b.Property(e => e.Up).Metadata.Sentinel = Array.Empty()).Message); + Assert.Equal( + CoreStrings.IncompatibleSentinelValue("System.Byte[]", nameof(Quarks), nameof(Quarks.Up), "int"), + Assert.Throws(() => b.Property(e => e.Up).Metadata.Sentinel = Array.Empty()) + .Message); }); } @@ -2753,7 +2757,7 @@ public virtual void Can_set_sentinel_for_primitive_collections() b.PrimitiveCollection(e => e.Up).HasSentinel(null); b.PrimitiveCollection(e => e.Down).HasSentinel(new ObservableCollection()); b.PrimitiveCollection("Charm").HasSentinel([]); - b.PrimitiveCollection>("Strange").HasSentinel(new List { }); + b.PrimitiveCollection>("Strange").HasSentinel(new List()); b.PrimitiveCollection("Top").HasSentinel([77]); b.PrimitiveCollection>("Bottom").HasSentinel(new List { "" }); }); @@ -2765,8 +2769,8 @@ public virtual void Can_set_sentinel_for_primitive_collections() Assert.Null(entityType.FindProperty("Up")!.Sentinel); Assert.Equal(new ObservableCollection(), entityType.FindProperty("Down")!.Sentinel); Assert.Equal(Array.Empty(), entityType.FindProperty("Charm")!.Sentinel); - Assert.Equal(new List { }, entityType.FindProperty("Strange")!.Sentinel); - Assert.Equal(new int[] { 77 }, entityType.FindProperty("Top")!.Sentinel); + Assert.Equal(new List(), entityType.FindProperty("Strange")!.Sentinel); + Assert.Equal(new[] { 77 }, entityType.FindProperty("Top")!.Sentinel); Assert.Equal(new List { "" }, entityType.FindProperty("Bottom")!.Sentinel); } @@ -2913,22 +2917,23 @@ public virtual void PrimitiveCollectionBuilder_methods_can_be_chained() => CreateModelBuilder() .Entity() .PrimitiveCollection(e => e.Up) - .ElementType(t => t - .HasAnnotation("B", "C") - .HasConversion(typeof(long)) - .HasConversion(new CastingConverter()) - .HasConversion(typeof(long), typeof(CustomValueComparer)) - .HasConversion(typeof(long), new CustomValueComparer()) - .HasConversion(new CastingConverter()) - .HasConversion(new CastingConverter(), new CustomValueComparer()) - .HasConversion() - .HasConversion(new CustomValueComparer()) - .HasConversion>() - .HasMaxLength(2) - .HasPrecision(1) - .HasPrecision(1, 2) - .IsRequired() - .IsUnicode()) + .ElementType( + t => t + .HasAnnotation("B", "C") + .HasConversion(typeof(long)) + .HasConversion(new CastingConverter()) + .HasConversion(typeof(long), typeof(CustomValueComparer)) + .HasConversion(typeof(long), new CustomValueComparer()) + .HasConversion(new CastingConverter()) + .HasConversion(new CastingConverter(), new CustomValueComparer()) + .HasConversion() + .HasConversion(new CustomValueComparer()) + .HasConversion>() + .HasMaxLength(2) + .HasPrecision(1) + .HasPrecision(1, 2) + .IsRequired() + .IsUnicode()) .IsRequired() .IsRequired(false) .HasAnnotation("A", "V") @@ -3107,7 +3112,8 @@ public virtual void Element_types_can_be_made_required() b.PrimitiveCollection(e => e.Down).ElementType().IsRequired(false); b.PrimitiveCollection>("Charm").ElementType().IsRequired(); b.PrimitiveCollection>("Strange").ElementType().IsRequired(); - b.PrimitiveCollection>("Stranger").ElementType().IsRequired(); // Still optional since no NRT metadata available + b.PrimitiveCollection>("Stranger").ElementType() + .IsRequired(); // Still optional since no NRT metadata available }); var entityType = modelBuilder.FinalizeModel().FindEntityType(typeof(CollectionQuarks))!; @@ -3282,11 +3288,13 @@ public virtual void Conversion_on_base_property_prevents_primitive_collection() { var modelBuilder = CreateModelBuilder(); modelBuilder.Entity(); - modelBuilder.Entity(b => - { - b.Property(c => c.Down).HasConversion(gs => string.Join(',', gs!), - s => new ObservableCollection(s.Split(',', StringSplitOptions.RemoveEmptyEntries))); - }); + modelBuilder.Entity( + b => + { + b.Property(c => c.Down).HasConversion( + gs => string.Join(',', gs!), + s => new ObservableCollection(s.Split(',', StringSplitOptions.RemoveEmptyEntries))); + }); var model = modelBuilder.FinalizeModel(); @@ -3299,13 +3307,16 @@ public virtual void Conversion_on_base_property_prevents_primitive_collection() public virtual void Conversion_on_base_property_prevents_primitive_collection_when_base_first() { var modelBuilder = CreateModelBuilder(); - modelBuilder.Entity(b => - { - b.Property(c => c.Down).HasConversion(gs => string.Join(',', gs!), - s => new ObservableCollection(s.Split(',', StringSplitOptions.RemoveEmptyEntries))); - }); + modelBuilder.Entity( + b => + { + b.Property(c => c.Down).HasConversion( + gs => string.Join(',', gs!), + s => new ObservableCollection(s.Split(',', StringSplitOptions.RemoveEmptyEntries))); + }); - var property = (IProperty)modelBuilder.Model.FindEntityType(typeof(CollectionQuarks))!.FindProperty(nameof(CollectionQuarks.Down))!; + var property = + (IProperty)modelBuilder.Model.FindEntityType(typeof(CollectionQuarks))!.FindProperty(nameof(CollectionQuarks.Down))!; Assert.False(property.IsPrimitiveCollection); modelBuilder.Entity(); diff --git a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.OneToMany.cs b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.OneToMany.cs index e570cb25769..a72255fd709 100644 --- a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.OneToMany.cs +++ b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.OneToMany.cs @@ -2546,12 +2546,13 @@ public virtual void Non_nullable_FK_can_be_made_optional_separately() public virtual void Nullable_FK_overrides_NRT_navigation() { var modelBuilder = CreateModelBuilder(); - modelBuilder.Entity(eb => - { - eb.Property(d => d.PrincipalEntityId); - eb.Ignore(d => d.Nav); - eb.HasOne(d => d.Nav).WithMany(p => p.InverseNav); - }); + modelBuilder.Entity( + eb => + { + eb.Property(d => d.PrincipalEntityId); + eb.Ignore(d => d.Nav); + eb.HasOne(d => d.Nav).WithMany(p => p.InverseNav); + }); var model = modelBuilder.FinalizeModel(); diff --git a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.OwnedTypes.cs b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.OwnedTypes.cs index 32c2f2f2c40..e8371d55489 100644 --- a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.OwnedTypes.cs +++ b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.OwnedTypes.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable InconsistentNaming + namespace Microsoft.EntityFrameworkCore.ModelBuilding; #nullable disable @@ -445,6 +446,9 @@ public virtual void Can_configure_owned_type_collection() .Ignore(o => o.Details); entityBuilder.Property("foo"); entityBuilder.HasIndex("foo"); + entityBuilder.HasIndex(["foo"], "Foo2"); + entityBuilder.HasIndex(o => new { o.CustomerId }); + entityBuilder.HasIndex(o => new { o.CustomerId }, "Customer2"); entityBuilder.HasKey(o => o.AnotherCustomerId); entityBuilder.WithOwner(o => o.Customer) .HasPrincipalKey(c => c.AlternateKey); @@ -462,17 +466,25 @@ public virtual void Can_configure_owned_type_collection() Assert.Null(owner.FindProperty("foo")); Assert.Equal(nameof(Order.AnotherCustomerId), owned.FindPrimaryKey().Properties.Single().Name); + var unnamedIndexes = owned.GetIndexes().Where(i => i.Name == null).ToList(); if (Fixture.ForeignKeysHaveIndexes) { - Assert.Equal(2, owned.GetIndexes().Count()); - Assert.Equal("CustomerAlternateKey", owned.GetIndexes().First().Properties.Single().Name); - } - else - { - Assert.Single(owned.GetIndexes()); + var fkIndex = unnamedIndexes.Single(i => i.Properties.Contains(ownership.Properties.Single())); + Assert.Equal("CustomerAlternateKey", fkIndex.Properties.Single().Name); + unnamedIndexes.Remove(fkIndex); } - Assert.Equal("foo", owned.GetIndexes().Last().Properties.Single().Name); + Assert.Equal(2, unnamedIndexes.Count()); + Assert.Equal(nameof(Order.CustomerId), unnamedIndexes.First().Properties.Single().Name); + Assert.Equal("foo", unnamedIndexes.Last().Properties.Single().Name); + + var namedIndexes = owned.GetIndexes().Where(i => i.Name != null).ToList(); + Assert.Equal(2, namedIndexes.Count()); + Assert.Equal(nameof(Order.CustomerId), namedIndexes.First().Properties.Single().Name); + Assert.Equal("Customer2", namedIndexes.First().Name); + Assert.Equal("foo", namedIndexes.Last().Properties.Single().Name); + Assert.Equal("Foo2", namedIndexes.Last().Name); + Assert.Equal(PropertyAccessMode.FieldDuringConstruction, owned.GetPropertyAccessMode()); Assert.Equal(ChangeTrackingStrategy.ChangedNotifications, owned.GetChangeTrackingStrategy()); @@ -587,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] @@ -1113,11 +1131,12 @@ public virtual void Can_map_derived_of_owned_type_first() } [ConditionalFact] - public virtual void Can_configure_relationship_with_PK_ValueConverter() + public virtual void Can_configure_relationship_with_PK_ValueConverter_shadow_FK() { var modelBuilder = CreateModelBuilder(); - modelBuilder.Entity().Property(x => x.Id) + modelBuilder.Entity() + .Property(x => x.Id) .HasConversion(x => x.Id, x => new CustomId { Id = x }); modelBuilder.Entity() @@ -1126,8 +1145,7 @@ public virtual void Can_configure_relationship_with_PK_ValueConverter() modelBuilder.Entity() .OwnsOne(q => q.Value) - .Property(x => x.CategoryId) - .HasConversion(x => x.Id, x => new CustomId { Id = x }); + .Property(x => x.CategoryId); var model = modelBuilder.FinalizeModel(); @@ -1143,14 +1161,45 @@ public virtual void Can_configure_relationship_with_PK_ValueConverter() var category = model.FindEntityType(typeof(ValueCategory)); Assert.Null(category.FindProperty("TempId")); - var barNavigation = owned.GetDeclaredNavigations().Single(n => !n.ForeignKey.IsOwnership); - Assert.Same(category, barNavigation.TargetEntityType); - var fkProperty = barNavigation.ForeignKey.Properties.Single(); + var categoryNavigation = owned.GetDeclaredNavigations().Single(n => !n.ForeignKey.IsOwnership); + Assert.Same(category, categoryNavigation.TargetEntityType); + var fkProperty = categoryNavigation.ForeignKey.Properties.Single(); Assert.Equal("CategoryId", fkProperty.Name); Assert.Equal(3, model.GetEntityTypes().Count()); } + [ConditionalFact] + public virtual void Can_configure_relationship_with_PK_ValueConverter() + { + var modelBuilder = CreateModelBuilder(); + + modelBuilder.Entity(eb => + { + eb.Property(x => x.Id) + .HasConversion(x => x.Id, x => new CustomId { Id = x }); + eb.OwnsOne(q => q.Value) + .WithOwner() + .HasForeignKey(q => q.CategoryId); + }); + + modelBuilder.Ignore(); + + var model = modelBuilder.FinalizeModel(); + + var result = model.FindEntityType(typeof(QueryResult)); + Assert.Null(result.FindProperty("TempId")); + + var owned = result.GetDeclaredNavigations().Single().TargetEntityType; + Assert.Null(owned.FindProperty("TempId")); + + var ownedPkProperty = owned.FindPrimaryKey().Properties.Single(); + Assert.NotNull(ownedPkProperty.GetValueConverter()); + + Assert.DoesNotContain(owned.GetDeclaredNavigations(), n => !n.ForeignKey.IsOwnership); + Assert.Equal(2, model.GetEntityTypes().Count()); + } + [ConditionalFact] public virtual void Throws_on_FK_matching_two_relationships() { @@ -1617,9 +1666,7 @@ protected class DepartmentId public DepartmentId() { } public DepartmentId(int value) - { - Value = value; - } + => Value = value; public int Value { get; } } @@ -1635,15 +1682,16 @@ public virtual void Can_configure_property_and_owned_entity_of_same_type() { var modelBuilder = CreateModelBuilder(); - modelBuilder.Entity(b => - { - b.Property(d => d.Id) - .HasConversion( - id => id.Value, - value => new DepartmentId(value)); + modelBuilder.Entity( + b => + { + b.Property(d => d.Id) + .HasConversion( + id => id.Value, + value => new DepartmentId(value)); - b.OwnsMany(d => d.DepartmentIds); - }); + b.OwnsMany(d => d.DepartmentIds); + }); modelBuilder.Entity() .OwnsMany(o => o.DepartmentIds); @@ -1672,15 +1720,16 @@ public virtual void Can_configure_owned_entity_and_property_of_same_type() modelBuilder.Entity() .OwnsMany(o => o.DepartmentIds); - modelBuilder.Entity(b => - { - b.Property(d => d.Id) - .HasConversion( - id => id.Value, - value => new DepartmentId(value)); + modelBuilder.Entity( + b => + { + b.Property(d => d.Id) + .HasConversion( + id => id.Value, + value => new DepartmentId(value)); - b.OwnsMany(d => d.DepartmentIds); - }); + b.OwnsMany(d => d.DepartmentIds); + }); var model = modelBuilder.FinalizeModel(); @@ -2022,22 +2071,23 @@ public virtual void PrimitiveCollectionBuilder_methods_can_be_chained() .Entity() .OwnsOne(e => e.CollectionQuarks) .PrimitiveCollection(e => e.Up) - .ElementType(t => t - .HasAnnotation("B", "C") - .HasConversion(typeof(long)) - .HasConversion(new CastingConverter()) - .HasConversion(typeof(long), typeof(CustomValueComparer)) - .HasConversion(typeof(long), new CustomValueComparer()) - .HasConversion(new CastingConverter()) - .HasConversion(new CastingConverter(), new CustomValueComparer()) - .HasConversion() - .HasConversion(new CustomValueComparer()) - .HasConversion>() - .HasMaxLength(2) - .HasPrecision(1) - .HasPrecision(1, 2) - .IsRequired() - .IsUnicode()) + .ElementType( + t => t + .HasAnnotation("B", "C") + .HasConversion(typeof(long)) + .HasConversion(new CastingConverter()) + .HasConversion(typeof(long), typeof(CustomValueComparer)) + .HasConversion(typeof(long), new CustomValueComparer()) + .HasConversion(new CastingConverter()) + .HasConversion(new CastingConverter(), new CustomValueComparer()) + .HasConversion() + .HasConversion(new CustomValueComparer()) + .HasConversion>() + .HasMaxLength(2) + .HasPrecision(1) + .HasPrecision(1, 2) + .IsRequired() + .IsUnicode()) .IsRequired() .HasAnnotation("A", "V") .IsConcurrencyToken() @@ -2060,22 +2110,23 @@ public virtual void PrimitiveCollectionBuilder_methods_can_be_chained_on_collect .Entity() .OwnsMany(e => e.Orders) .PrimitiveCollection>("List") - .ElementType(t => t - .HasAnnotation("B", "C") - .HasConversion(typeof(long)) - .HasConversion(new CastingConverter()) - .HasConversion(typeof(long), typeof(CustomValueComparer)) - .HasConversion(typeof(long), new CustomValueComparer()) - .HasConversion(new CastingConverter()) - .HasConversion(new CastingConverter(), new CustomValueComparer()) - .HasConversion() - .HasConversion(new CustomValueComparer()) - .HasConversion>() - .HasMaxLength(2) - .HasPrecision(1) - .HasPrecision(1, 2) - .IsRequired() - .IsUnicode()) + .ElementType( + t => t + .HasAnnotation("B", "C") + .HasConversion(typeof(long)) + .HasConversion(new CastingConverter()) + .HasConversion(typeof(long), typeof(CustomValueComparer)) + .HasConversion(typeof(long), new CustomValueComparer()) + .HasConversion(new CastingConverter()) + .HasConversion(new CastingConverter(), new CustomValueComparer()) + .HasConversion() + .HasConversion(new CustomValueComparer()) + .HasConversion>() + .HasMaxLength(2) + .HasPrecision(1) + .HasPrecision(1, 2) + .IsRequired() + .IsUnicode()) .IsRequired() .HasAnnotation("A", "V") .IsConcurrencyToken() @@ -2106,6 +2157,7 @@ private class CustomValueGeneratorFactory : ValueGeneratorFactory public override ValueGenerator Create(IProperty property, ITypeBase entityType) => new CustomValueGenerator(); } + private class CustomValueComparer() : ValueComparer(false); } } diff --git a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.TestModel.cs b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.TestModel.cs index 483deaa4c5e..1af3de98e34 100644 --- a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.TestModel.cs +++ b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.TestModel.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Collections; using System.Collections.ObjectModel; using System.ComponentModel; using System.ComponentModel.DataAnnotations; @@ -784,9 +785,12 @@ protected class Value public ValueCategory? Category { get; set; } } - protected class CustomId + protected class CustomId : IEnumerable { public int Id { get; set; } + + public IEnumerator GetEnumerator() => throw new NotImplementedException(); + IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); } protected class ValueCategory @@ -1108,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; } } @@ -1185,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/ModelBuilding/ModelBuilderTest.cs b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.cs index da145a8e973..1664aa0fb16 100644 --- a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.cs +++ b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.cs @@ -44,8 +44,12 @@ protected TestModelBuilder HobNobBuilder() public abstract class ModelBuilderFixtureBase { public abstract TestHelpers TestHelpers { get; } - public virtual DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) => builder; - public virtual IServiceCollection AddServices(IServiceCollection services) => services; + + public virtual DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) + => builder; + + public virtual IServiceCollection AddServices(IServiceCollection services) + => services; public virtual bool ForeignKeysHaveIndexes => true; @@ -57,7 +61,7 @@ protected TestModelBuilder(ModelBuilderFixtureBase fixture, Action l == DbLoggerCategory.Model.Validation.Name); ValidationLogger = new DiagnosticsLogger( ValidationLoggerFactory, @@ -82,6 +86,9 @@ protected TestModelBuilder(ModelBuilderFixtureBase fixture, Action builder.EnableSensitiveDataLogging(false); + public virtual IMutableModel Model => ModelBuilder.Model; @@ -931,8 +938,14 @@ public abstract TestOwnedNavigationBuilder Ignore( Expression> propertyExpression); public abstract TestIndexBuilder HasIndex(params string[] propertyNames); + public abstract TestIndexBuilder HasIndex(string[] propertyNames, string name); + public abstract TestIndexBuilder HasIndex(Expression> indexExpression); + public abstract TestIndexBuilder HasIndex( + Expression> indexExpression, + string name); + public abstract TestOwnershipBuilder WithOwner(string? ownerReference); public abstract TestOwnershipBuilder WithOwner( diff --git a/test/EFCore.Specification.Tests/MonsterFixupTestBase.cs b/test/EFCore.Specification.Tests/MonsterFixupTestBase.cs index 91244c56db7..590ec78737d 100644 --- a/test/EFCore.Specification.Tests/MonsterFixupTestBase.cs +++ b/test/EFCore.Specification.Tests/MonsterFixupTestBase.cs @@ -10,7 +10,7 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public abstract class MonsterFixupTestBase : IClassFixture, IDisposable +public abstract class MonsterFixupTestBase : IClassFixture, IAsyncLifetime where TFixture : MonsterFixupTestBase.MonsterFixupFixtureBase, new() { protected MonsterFixupTestBase(TFixture fixture) @@ -1405,8 +1405,11 @@ protected Task CreateAndSeedDatabase(Func seed) protected MonsterContext CreateContext() => Fixture.CreateContext(Options); - public virtual void Dispose() - => TestStore.Dispose(); + public Task InitializeAsync() + => Task.CompletedTask; + + public virtual async Task DisposeAsync() + => await TestStore.DisposeAsync(); public abstract class MonsterFixupFixtureBase : ServiceProviderFixtureBase { diff --git a/test/EFCore.Specification.Tests/MusicStoreTestBase.cs b/test/EFCore.Specification.Tests/MusicStoreTestBase.cs index 7844c568cc9..61a70c887e6 100644 --- a/test/EFCore.Specification.Tests/MusicStoreTestBase.cs +++ b/test/EFCore.Specification.Tests/MusicStoreTestBase.cs @@ -327,7 +327,7 @@ await context.Database.CreateExecutionStrategy().ExecuteAsync( } [ConditionalFact] - public virtual async void Music_store_project_to_mapped_entity() + public virtual async Task Music_store_project_to_mapped_entity() { using var context = CreateContext(); await context.Database.CreateExecutionStrategy().ExecuteAsync( diff --git a/test/EFCore.Specification.Tests/NonSharedModelTestBase.cs b/test/EFCore.Specification.Tests/NonSharedModelTestBase.cs index 7f8f924020e..3d49751a8a8 100644 --- a/test/EFCore.Specification.Tests/NonSharedModelTestBase.cs +++ b/test/EFCore.Specification.Tests/NonSharedModelTestBase.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable VirtualMemberCallInConstructor + namespace Microsoft.EntityFrameworkCore; public abstract class NonSharedModelTestBase : IAsyncLifetime diff --git a/test/EFCore.Specification.Tests/OverzealousInitializationTestBase.cs b/test/EFCore.Specification.Tests/OverzealousInitializationTestBase.cs index 0d3d0d435c3..fa0a9fc57c6 100644 --- a/test/EFCore.Specification.Tests/OverzealousInitializationTestBase.cs +++ b/test/EFCore.Specification.Tests/OverzealousInitializationTestBase.cs @@ -33,7 +33,7 @@ public virtual void Fixup_ignores_eagerly_initialized_reference_navs() private static readonly Artist[] _artists = [ - new() { Id = 1, Name = "Freddie" }, new() { Id = 2, Name = "Kendrick" }, new() { Id = 3, Name = "Jarvis" } + new Artist { Id = 1, Name = "Freddie" }, new Artist { Id = 2, Name = "Kendrick" }, new Artist { Id = 3, Name = "Jarvis" } ]; protected class Album diff --git a/test/EFCore.Specification.Tests/PropertyValuesTestBase.cs b/test/EFCore.Specification.Tests/PropertyValuesTestBase.cs index 25cfa814fd3..2709a3d6932 100644 --- a/test/EFCore.Specification.Tests/PropertyValuesTestBase.cs +++ b/test/EFCore.Specification.Tests/PropertyValuesTestBase.cs @@ -2749,29 +2749,31 @@ protected override Task SeedAsync(PoolableDbContext context) Assert.True((bool)joinEntry.Entity["InitializedCalled"]); } - context.Add(new Supplier33307 - { - Name = "Foo", - Address = new() + context.Add( + new Supplier33307 { - Street = "One", - Altitude = Math.PI, - Number = 42, - }, - Foo = "F" - }); + Name = "Foo", + Address = new Address33307 + { + Street = "One", + Altitude = Math.PI, + Number = 42, + }, + Foo = "F" + }); - context.Add(new Customer33307 - { - Name = "Bar", - Address = new() + context.Add( + new Customer33307 { - Street = "Two", - Altitude = Math.E, - Number = 42, - }, - Bar = 11 - }); + Name = "Bar", + Address = new Address33307 + { + Street = "Two", + Altitude = Math.E, + Number = 42, + }, + Bar = 11 + }); return context.SaveChangesAsync(); } diff --git a/test/EFCore.Specification.Tests/Query/AdHocAdvancedMappingsQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/AdHocAdvancedMappingsQueryTestBase.cs index dcba2641818..c14b2cdecc0 100644 --- a/test/EFCore.Specification.Tests/Query/AdHocAdvancedMappingsQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/AdHocAdvancedMappingsQueryTestBase.cs @@ -24,7 +24,8 @@ public virtual async Task Setting_IsUnicode_generates_unicode_literal_in_SQL() var query = context.Set().Where(xx => xx.Nombre.Contains("lla")).ToList(); } - private class Context9582(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context9582(DbContextOptions options) : DbContext(options) { protected override void OnModelCreating(ModelBuilder modelBuilder) { @@ -82,7 +83,8 @@ public virtual async Task Projecting_correlated_collection_along_with_non_mapped } } - private class Context11835(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context11835(DbContextOptions options) : DbContext(options) { public DbSet Blogs { get; set; } public DbSet Posts { get; set; } @@ -144,7 +146,8 @@ from c in grouping.DefaultIfEmpty() Assert.Equal(2, result.Count); } - private class Context15684(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context15684(DbContextOptions options) : DbContext(options) { public DbSet Categories { get; set; } public DbSet Products { get; set; } @@ -238,9 +241,12 @@ public virtual async Task Expression_tree_constructed_via_interface_works() } } - private class Context17276(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context17276(DbContextOptions options) : DbContext(options) { + // ReSharper disable once UnusedAutoPropertyAccessor.Local public DbSet RemovableEntities { get; set; } + // ReSharper disable once UnusedAutoPropertyAccessor.Local public DbSet Parents { get; set; } public static List List(IQueryable query) @@ -311,7 +317,8 @@ public virtual async Task Double_convert_interface_created_expression_tree() Assert.Equal(1, query); } - private class Context17794(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context17794(DbContextOptions options) : DbContext(options) { public DbSet Offers { get; set; } public DbSet OfferActions { get; set; } @@ -407,7 +414,8 @@ public virtual async Task Casts_are_removed_from_expression_tree_when_redundant( } } - private class Context18087(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context18087(DbContextOptions options) : DbContext(options) { public DbSet MockEntities { get; set; } @@ -453,7 +461,8 @@ public virtual async Task Can_query_hierarchy_with_non_nullable_property_on_deri Assert.Equal(3, query.Count); } - private class Context18346(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context18346(DbContextOptions options) : DbContext(options) { public DbSet Businesses { get; set; } @@ -575,7 +584,8 @@ public virtual async Task Query_generates_correct_timespan_parameter_definition( _ = context.Entities.Where(x => x.TimeSpan == parameter).Select(e => e.TimeSpan).FirstOrDefault(); } - private class Context26742(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context26742(DbContextOptions options) : DbContext(options) { public DbSet Entities { get; set; } diff --git a/test/EFCore.Specification.Tests/Query/AdHocComplexTypeQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/AdHocComplexTypeQueryTestBase.cs index 6712d2f03fe..9dd81de6853 100644 --- a/test/EFCore.Specification.Tests/Query/AdHocComplexTypeQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/AdHocComplexTypeQueryTestBase.cs @@ -4,7 +4,6 @@ namespace Microsoft.EntityFrameworkCore.Query; // ReSharper disable ClassNeverInstantiated.Local - public abstract class AdHocComplexTypeQueryTestBase : NonSharedModelTestBase { #region 33449 @@ -18,11 +17,11 @@ public virtual async Task Complex_type_equals_parameter_with_nested_types_with_p context.AddRange( new Context33449.EntityType { - ComplexContainer = new() + ComplexContainer = new Context33449.ComplexContainer { Id = 1, - Containee1 = new() { Id = 2 }, - Containee2 = new() { Id = 3 } + Containee1 = new Context33449.ComplexContainee1 { Id = 2 }, + Containee2 = new Context33449.ComplexContainee2 { Id = 3 } } }); return context.SaveChangesAsync(); @@ -33,8 +32,8 @@ public virtual async Task Complex_type_equals_parameter_with_nested_types_with_p var container = new Context33449.ComplexContainer { Id = 1, - Containee1 = new() { Id = 2 }, - Containee2 = new() { Id = 3 } + Containee1 = new Context33449.ComplexContainee1 { Id = 2 }, + Containee2 = new Context33449.ComplexContainee2 { Id = 3 } }; _ = await context.Set().Where(b => b.ComplexContainer == container).SingleAsync(); @@ -43,11 +42,12 @@ public virtual async Task Complex_type_equals_parameter_with_nested_types_with_p private class Context33449(DbContextOptions options) : DbContext(options) { protected override void OnModelCreating(ModelBuilder modelBuilder) - => modelBuilder.Entity().ComplexProperty(b => b.ComplexContainer, x => - { - x.ComplexProperty(c => c.Containee1); - x.ComplexProperty(c => c.Containee2); - }); + => modelBuilder.Entity().ComplexProperty( + b => b.ComplexContainer, x => + { + x.ComplexProperty(c => c.Containee1); + x.ComplexProperty(c => c.Containee2); + }); public class EntityType { diff --git a/test/EFCore.Specification.Tests/Query/AdHocManyToManyQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/AdHocManyToManyQueryTestBase.cs index 7221edef55c..5db2b2bc962 100644 --- a/test/EFCore.Specification.Tests/Query/AdHocManyToManyQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/AdHocManyToManyQueryTestBase.cs @@ -27,7 +27,8 @@ from organisation in context.Organisations.Where(o => o.OrganisationUsers.Any()) Assert.Equal(2, users.Count); } - private class MyContext7973(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class MyContext7973(DbContextOptions options) : DbContext(options) { public DbSet Users { get; set; } public DbSet Organisations { get; set; } diff --git a/test/EFCore.Specification.Tests/Query/AdHocMiscellaneousQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/AdHocMiscellaneousQueryTestBase.cs index e217ab475cc..220abaad95e 100644 --- a/test/EFCore.Specification.Tests/Query/AdHocMiscellaneousQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/AdHocMiscellaneousQueryTestBase.cs @@ -41,7 +41,8 @@ public virtual async Task First_FirstOrDefault_ix_async() } } - private class Context603(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context603(DbContextOptions options) : DbContext(options) { public DbSet Products { get; set; } @@ -87,7 +88,8 @@ from custPC in custPCTmp.DefaultIfEmpty() Assert.True(results[3].CustomerName != results[4].CustomerName); } - private class Context6901(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context6901(DbContextOptions options) : DbContext(options) { protected override void OnModelCreating(ModelBuilder modelBuilder) { @@ -218,7 +220,8 @@ public virtual async Task Shadow_property_with_inheritance() } } - private class Context6986(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context6986(DbContextOptions options) : DbContext(options) { public DbSet Contacts { get; set; } public DbSet EmployerContacts { get; set; } @@ -238,18 +241,15 @@ public async Task SeedAsync() Contacts.AddRange( new ServiceOperatorContact { - UserName = "service.operator@esoterix.co.uk", - ServiceOperator = ServiceOperators.OrderBy(o => o.Id).First() + UserName = "service.operator@esoterix.co.uk", ServiceOperator = ServiceOperators.OrderBy(o => o.Id).First() }, new EmployerContact { - UserName = "uwe@esoterix.co.uk", - Employer = Employers.OrderBy(e => e.Id).First(e => e.Name == "UWE") + UserName = "uwe@esoterix.co.uk", Employer = Employers.OrderBy(e => e.Id).First(e => e.Name == "UWE") }, new EmployerContact { - UserName = "hp@esoterix.co.uk", - Employer = Employers.OrderBy(e => e.Id).First(e => e.Name == "Hewlett Packard") + UserName = "hp@esoterix.co.uk", Employer = Employers.OrderBy(e => e.Id).First(e => e.Name == "Hewlett Packard") }, new Contact { UserName = "noroles@esoterix.co.uk" }); @@ -308,7 +308,8 @@ public virtual async Task Inlined_dbcontext_is_not_leaking() } } - private class Context7222(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context7222(DbContextOptions options) : DbContext(options) { public DbSet Blogs { get; set; } @@ -348,7 +349,8 @@ public virtual async Task Discriminator_type_is_handled_correctly() } } - private class Context7359(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context7359(DbContextOptions options) : DbContext(options) { public DbSet Products { get; set; } @@ -393,7 +395,8 @@ public virtual async Task New_instances_in_projection_are_not_shared_across_resu Assert.Equal(new[] { "First", "Second", "Third" }, list.Select(dto => dto.Title)); } - private class Context7983(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context7983(DbContextOptions options) : DbContext(options) { public DbSet Blogs { get; set; } public DbSet Posts { get; set; } @@ -483,7 +486,8 @@ public virtual async Task Enum_has_flag_does_not_apply_explicit_cast_for_non_con } } - private class Context8538(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context8538(DbContextOptions options) : DbContext(options) { public DbSet Entities { get; set; } @@ -671,7 +675,8 @@ public virtual async Task Explicitly_compiled_query_does_not_add_cache_entry() } } - private class Context8909(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context8909(DbContextOptions options) : DbContext(options) { public DbSet Entities { get; set; } @@ -711,7 +716,8 @@ public virtual async Task Conditional_expression_with_conditions_does_not_collap Assert.Single(query.Where(t => t.Processing == false)); } - private class Context9468(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context9468(DbContextOptions options) : DbContext(options) { public DbSet Carts { get; set; } @@ -755,7 +761,8 @@ public virtual async Task QueryBuffer_requirement_is_computed_when_querying_base Assert.Equal(typeof(Context11104.Derived1), derived1.GetType()); } - private class Context11104(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context11104(DbContextOptions options) : DbContext(options) { public DbSet Bases { get; set; } @@ -814,7 +821,8 @@ public virtual async Task Average_with_cast() Assert.Equal(prices.Average(e => e.NullableDecimalColumn), context.Prices.Average(e => e.NullableDecimalColumn)); } - private class Context11885(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context11885(DbContextOptions options) : DbContext(options) { public DbSet Prices { get; set; } @@ -912,7 +920,8 @@ public virtual async Task Parameterless_ctor_on_inner_DTO_gets_called_for_every_ Assert.False(ReferenceEquals(results[2].Inner, results[3].Inner)); } - private class Context12274(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context12274(DbContextOptions options) : DbContext(options) { public DbSet Entities { get; set; } @@ -977,7 +986,8 @@ public virtual async Task Union_and_insert_works_correctly_together() } } - private class Context12549(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context12549(DbContextOptions options) : DbContext(options) { public DbSet Tables1 { get; set; } public DbSet Tables2 { get; set; } @@ -1014,7 +1024,8 @@ public virtual async Task Repeated_parameters_in_generated_query_sql() Assert.Single(equalQuery); } - private class Context15215(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context15215(DbContextOptions options) : DbContext(options) { public DbSet Autos { get; set; } public DbSet EqualAutos { get; set; } @@ -1169,7 +1180,8 @@ public virtual async Task Operators_combine_nullability_of_entity_shapers() } } - private class Context19253(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context19253(DbContextOptions options) : DbContext(options) { public DbSet As { get; set; } public DbSet Bs { get; set; } @@ -1306,7 +1318,8 @@ public virtual async Task Null_check_removal_in_ternary_maintain_appropriate_cas : query.ToList(); } - private class Context21770(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context21770(DbContextOptions options) : DbContext(options) { public DbSet IceCreams { get; set; } public DbSet Foods { get; set; } @@ -1368,8 +1381,8 @@ public class Food #region 22841 - [ConditionalFact] - public async virtual Task SaveChangesAsync_accepts_changes_with_ConfigureAwait_true() + [ConditionalFact(Skip = "Issue #34727 - flaky test")] + public virtual async Task SaveChangesAsync_accepts_changes_with_ConfigureAwait_true() { var contextFactory = await InitializeAsync(); @@ -1404,7 +1417,8 @@ public async virtual Task SaveChangesAsync_accepts_changes_with_ConfigureAwait_t Assert.True(isMySyncContext); } - private class Context22841(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context22841(DbContextOptions options) : DbContext(options) { protected override void OnModelCreating(ModelBuilder modelBuilder) => modelBuilder @@ -1452,7 +1466,8 @@ public virtual async Task Bool_discriminator_column_works(bool async) Assert.Equal(2, authors.Count); } - private class Context24657(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context24657(DbContextOptions options) : DbContext(options) { public DbSet Authors { get; set; } @@ -1486,17 +1501,13 @@ public abstract class Blog public class DevBlog : Blog { public DevBlog() - { - IsPhotoBlog = false; - } + => IsPhotoBlog = false; } public class PhotoBlog : Blog { public PhotoBlog() - { - IsPhotoBlog = true; - } + => IsPhotoBlog = true; public int NumberOfPhotos { get; set; } } @@ -1581,7 +1592,8 @@ public virtual async Task Unwrap_convert_node_over_projection_when_translating_c : query.ToList(); } - private class Context26593(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context26593(DbContextOptions options) : DbContext(options) { public DbSet Users { get; set; } public DbSet Groups { get; set; } @@ -1640,8 +1652,7 @@ public virtual async Task GroupBy_aggregate_on_right_side_of_join(bool async) o => o.OrderId, (o, g) => new { - Key = o, - IsPending = g.Max(y => y.ShippingDate == null && y.CancellationDate == null ? o : (o - 10000000)) + Key = o, IsPending = g.Max(y => y.ShippingDate == null && y.CancellationDate == null ? o : (o - 10000000)) }) .OrderBy(e => e.Key); @@ -1654,7 +1665,8 @@ public virtual async Task GroupBy_aggregate_on_right_side_of_join(bool async) : query.ToList(); } - private class Context26587(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context26587(DbContextOptions options) : DbContext(options) { public DbSet OrderItems { get; set; } @@ -1695,7 +1707,8 @@ public virtual async Task Enum_with_value_converter_matching_take_value(bool asy : query.ToList(); } - private class Context26472(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context26472(DbContextOptions options) : DbContext(options) { public virtual DbSet Orders { get; set; } public virtual DbSet OrderItems { get; set; } @@ -1801,7 +1814,8 @@ public virtual async Task Aggregate_over_subquery_in_group_by_projection(bool as }); } - private class Context27083(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context27083(DbContextOptions options) : DbContext(options) { public DbSet TimeSheets { get; set; } public DbSet Customers { get; set; } @@ -1900,8 +1914,7 @@ group t.Id by t.Value into tg select new { - A = tg.Key, - B = context.Tables.Where(t => t.Value == tg.Max() * 6).Max(t => (int?)t.Id), + A = tg.Key, B = context.Tables.Where(t => t.Value == tg.Max() * 6).Max(t => (int?)t.Id), }; var orders = async @@ -1935,7 +1948,8 @@ select tg.Sum() + tg2.Sum() : query.ToList(); } - private class Context27094(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context27094(DbContextOptions options) : DbContext(options) { public DbSet Tables { get; set; } @@ -1999,16 +2013,15 @@ public virtual async Task SelectMany_where_Select(bool async) Assert.Single(result); } - private class Context26744(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context26744(DbContextOptions options) : DbContext(options) { public DbSet Parents { get; set; } public Task SeedAsync() { - Add( - new Parent { Children = [new() { SomeInteger = 1, SomeOtherNullableDateTime = new DateTime(2000, 11, 18) }] }); - - Add(new Parent { Children = [new() { SomeInteger = 1, }] }); + Add(new Parent { Children = [new Child { SomeInteger = 1, SomeOtherNullableDateTime = new DateTime(2000, 11, 18) }] }); + Add(new Parent { Children = [new Child { SomeInteger = 1, }] }); return SaveChangesAsync(); } @@ -2052,7 +2065,8 @@ from c in grouping.DefaultIfEmpty() Assert.Empty(result); } - private class Context27343(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context27343(DbContextOptions options) : DbContext(options) { public DbSet Parents { get; set; } @@ -2109,7 +2123,8 @@ orderby dcv.ParcelNumber : jsonLookup.ToList(); } - private class Context28039(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context28039(DbContextOptions options) : DbContext(options) { public DbSet IndexDatas { get; set; } public DbSet TableDatas { get; set; } @@ -2155,20 +2170,19 @@ public virtual async Task Filter_on_nested_DTO_with_interface_gets_simplified_co var query = await context.Customers .Select( - m => new Context31961.CustomerDto() + m => new Context31961.CustomerDto { Id = m.Id, CompanyId = m.CompanyId, Company = m.Company != null - ? new Context31961.CompanyDto() + ? new Context31961.CompanyDto { Id = m.Company.Id, CompanyName = m.Company.CompanyName, CountryId = m.Company.CountryId, - Country = new Context31961.CountryDto() + Country = new Context31961.CountryDto { - Id = m.Company.Country.Id, - CountryName = m.Company.Country.CountryName, + Id = m.Company.Country.Id, CountryName = m.Company.Country.CountryName, }, } : null, @@ -2177,7 +2191,8 @@ public virtual async Task Filter_on_nested_DTO_with_interface_gets_simplified_co .ToListAsync(); } - private class Context31961(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context31961(DbContextOptions options) : DbContext(options) { public DbSet Customers { get; set; } diff --git a/test/EFCore.Specification.Tests/Query/AdHocNavigationsQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/AdHocNavigationsQueryTestBase.cs index 3ab439edd39..e078a525e00 100644 --- a/test/EFCore.Specification.Tests/Query/AdHocNavigationsQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/AdHocNavigationsQueryTestBase.cs @@ -79,7 +79,8 @@ public virtual async Task ThenInclude_with_interface_navigations() } } - private class Context3409(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context3409(DbContextOptions options) : DbContext(options) { public DbSet Parents { get; set; } public DbSet Children { get; set; } @@ -201,8 +202,7 @@ protected class Context3758(DbContextOptions options) : DbContext(options) public DbSet Orders { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) - { - modelBuilder.Entity( + => modelBuilder.Entity( b => { b.HasMany(e => e.Orders1).WithOne().HasForeignKey("CustomerId1"); @@ -210,7 +210,6 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) b.HasMany(e => e.Orders3).WithOne().HasForeignKey("CustomerId3"); b.HasMany(e => e.Orders4).WithOne().HasForeignKey("CustomerId4"); }); - } public Task SeedAsync() { @@ -313,7 +312,8 @@ public virtual async Task Reference_include_on_derived_type_with_sibling_works() } } - private class Context7312(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context7312(DbContextOptions options) : DbContext(options) { public DbSet Proposals { get; set; } public DbSet ProposalCustoms { get; set; } @@ -387,7 +387,8 @@ public virtual async Task Include_collection_optional_reference_collection() } } - private class Context9038(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context9038(DbContextOptions options) : DbContext(options) { public DbSet People { get; set; } @@ -493,7 +494,8 @@ public virtual async Task Include_with_order_by_on_interface_key() } } - private class Context10635(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context10635(DbContextOptions options) : DbContext(options) { public DbSet Parents { get; set; } public DbSet Children { get; set; } @@ -570,7 +572,8 @@ public virtual async Task Collection_without_setter_materialized_correctly() }).ToList()); } - private class Context11923(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context11923(DbContextOptions options) : DbContext(options) { public DbSet Blogs { get; set; } public DbSet Posts { get; set; } @@ -760,7 +763,8 @@ public virtual async Task Let_multiple_references_with_reference_to_outer() } } - private class Context12456(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context12456(DbContextOptions options) : DbContext(options) { public DbSet Activities { get; set; } public DbSet CompetitionSeasons { get; set; } @@ -841,7 +845,8 @@ public virtual async Task Include_collection_with_OfType_base() } } - private class Context12582(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context12582(DbContextOptions options) : DbContext(options) { public DbSet Employees { get; set; } public DbSet Devices { get; set; } @@ -903,7 +908,8 @@ public virtual async Task Correlated_collection_correctly_associates_entities_wi Assert.Single(result[0].Comments); } - private class Context12748(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context12748(DbContextOptions options) : DbContext(options) { public DbSet Blogs { get; set; } public DbSet Comments { get; set; } @@ -1010,7 +1016,8 @@ public virtual async Task SelectMany_and_collection_in_projection_in_FirstOrDefa }).SingleOrDefault(); } - private class Context20813(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context20813(DbContextOptions options) : DbContext(options) { public DbSet Orders { get; set; } @@ -1088,7 +1095,8 @@ public virtual async Task Using_explicit_interface_implementation_as_navigation_ var result = context.Books.Where(b => b.Id == 1).Select(projection).SingleOrDefault(); } - private class Context21768(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context21768(DbContextOptions options) : DbContext(options) { public DbSet Books { get; set; } public DbSet BookCovers { get; set; } @@ -1274,10 +1282,7 @@ public Task SeedAsync() { Add(new PrincipalOneToOne { Dependent = new DependentOneToOne() }); Add( - new PrincipalOneToMany - { - Dependents = [new(), new()] - }); + new PrincipalOneToMany { Dependents = [new DependentOneToMany(), new DependentOneToMany()] }); return SaveChangesAsync(); } @@ -1431,12 +1436,12 @@ public virtual async Task Walking_back_include_tree_is_not_allowed_4() } } - private class Context23674(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context23674(DbContextOptions options) : DbContext(options) { protected override void OnModelCreating(ModelBuilder modelBuilder) => modelBuilder.Entity(); - public class Principal { public int Id { get; set; } @@ -1516,7 +1521,8 @@ public virtual async Task Projection_with_multiple_includes_and_subquery_with_se .FirstOrDefaultAsync(x => x.Id == id); } - private class Context23676(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context23676(DbContextOptions options) : DbContext(options) { public DbSet Persons { get; set; } diff --git a/test/EFCore.Specification.Tests/Query/ComplexNavigationsCollectionsQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/ComplexNavigationsCollectionsQueryTestBase.cs index e1ce7bcb771..7c18447c42f 100644 --- a/test/EFCore.Specification.Tests/Query/ComplexNavigationsCollectionsQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/ComplexNavigationsCollectionsQueryTestBase.cs @@ -2533,17 +2533,18 @@ public virtual Task Final_GroupBy_property_entity_Include_reference_multiple(boo public virtual Task Project_collection_and_nested_conditional(bool async) => AssertQuery( async, - ss => ss.Set().OrderBy(x => x.Id).Select(x => new - { - Collection = x.OneToMany_Optional1.OrderBy(xx => xx.Id).Select(xx => xx.Name).ToList(), - Condition = x.Id == 1 - ? "01" - : x.Id == 2 - ? "02" - : x.Id == 3 - ? "03" - : null - }).Where(x => x.Condition == "02"), + ss => ss.Set().OrderBy(x => x.Id).Select( + x => new + { + Collection = x.OneToMany_Optional1.OrderBy(xx => xx.Id).Select(xx => xx.Name).ToList(), + Condition = x.Id == 1 + ? "01" + : x.Id == 2 + ? "02" + : x.Id == 3 + ? "03" + : null + }).Where(x => x.Condition == "02"), assertOrder: true, elementAsserter: (e, a) => { diff --git a/test/EFCore.Specification.Tests/Query/ComplexNavigationsQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/ComplexNavigationsQueryTestBase.cs index 4c79717d07b..a9eb2f70f43 100644 --- a/test/EFCore.Specification.Tests/Query/ComplexNavigationsQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/ComplexNavigationsQueryTestBase.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.CodeDom.Compiler; using Microsoft.EntityFrameworkCore.TestModels.ComplexNavigationsModel; #pragma warning disable RCS1155 // Use StringComparison when comparing strings. @@ -1727,18 +1726,18 @@ public virtual Task Required_navigation_on_a_subquery_with_First_in_predicate(bo .Where( l1 => EF.Property( ss.Set().OrderBy(l2i => l2i.Id).First().OneToOne_Required_FK_Inverse2, "Name") - == "L1 10" || - EF.Property( + == "L1 10" + || EF.Property( ss.Set().OrderBy(l2i => l2i.Id).First().OneToOne_Required_FK_Inverse2, "Name") == "L1 01")); - //=> AssertQuery( - // async, - // ss => ss.Set() - // .Where(l2o => l2o.Id == 7) - // .Where( - // l1 => EF.Property( - // ss.Set().OrderBy(l2i => l2i.Id).First().OneToOne_Required_FK_Inverse2, "Name") - // == "L1 10")); + //=> AssertQuery( + // async, + // ss => ss.Set() + // .Where(l2o => l2o.Id == 7) + // .Where( + // l1 => EF.Property( + // ss.Set().OrderBy(l2i => l2i.Id).First().OneToOne_Required_FK_Inverse2, "Name") + // == "L1 10")); [ConditionalTheory] [MemberData(nameof(IsAsyncData))] @@ -2204,8 +2203,9 @@ public virtual Task Where_on_multilevel_reference_in_subquery_with_outer_project => AssertQuery( async, ss => ss.Set() - .Where(l3 => l3.OneToMany_Required_Inverse3.OneToOne_Required_FK_Inverse2.Name == "L1 10" - || l3.OneToMany_Required_Inverse3.OneToOne_Required_FK_Inverse2.Name == "L1 01") + .Where( + l3 => l3.OneToMany_Required_Inverse3.OneToOne_Required_FK_Inverse2.Name == "L1 10" + || l3.OneToMany_Required_Inverse3.OneToOne_Required_FK_Inverse2.Name == "L1 01") .OrderBy(l3 => l3.Level2_Required_Id) .Skip(0) .Take(10) @@ -2237,8 +2237,7 @@ join l2 in ss.Set() } equals new { - A = EF.Property(l2, "Level1_Optional_Id"), - B = EF.Property(l2, "OneToMany_Optional_Self_Inverse2Id") + A = EF.Property(l2, "Level1_Optional_Id"), B = EF.Property(l2, "OneToMany_Optional_Self_Inverse2Id") } select l1); @@ -3296,8 +3295,7 @@ public virtual Task Member_over_null_check_ternary_and_nested_dto_type(bool asyn ? null : new Level2Dto { - Id = l1.OneToOne_Optional_FK1.Id, - Name = l1.OneToOne_Optional_FK1.Name, + Id = l1.OneToOne_Optional_FK1.Id, Name = l1.OneToOne_Optional_FK1.Name, } }) .OrderBy(e => e.Level2.Name) @@ -3435,8 +3433,7 @@ public virtual Task Composite_key_join_on_groupby_aggregate_projecting_only_grou o => new { o.Id, Condition = true }, i => new { - Id = i.Key, - Condition = i.Sum > 10, + Id = i.Key, Condition = i.Sum > 10, }, (o, i) => i.Key)); @@ -3451,8 +3448,7 @@ public virtual Task Composite_key_join_on_groupby_aggregate_projecting_only_grou o => new { o.Id, Condition = false }, i => new { - Id = i.Key, - Condition = i.Sum <= 10, + Id = i.Key, Condition = i.Sum <= 10, }, (o, i) => i.Key)); @@ -3757,8 +3753,7 @@ public virtual Task Project_shadow_properties8(bool async) ss => from x in ss.Set() select new { - x.Id, - InheritanceLeaf2Id = EF.Property(x, "InheritanceLeaf2Id"), + x.Id, InheritanceLeaf2Id = EF.Property(x, "InheritanceLeaf2Id"), }, elementSorter: e => e.Id); @@ -3965,9 +3960,10 @@ from l3 in grouping2.Where(x => x.Id != prm) public virtual Task Multiple_optional_navs_should_not_deadlock(bool async) => AssertCount( async, - ss => ss.Set().Where(x => x.OneToMany_Optional_Inverse2 != null - && x.OneToMany_Optional_Inverse2.Name.Contains("L1 01") - || x.OneToOne_Optional_FK_Inverse2 != null + ss => ss.Set().Where( + x => x.OneToMany_Optional_Inverse2 != null + && x.OneToMany_Optional_Inverse2.Name.Contains("L1 01") + || x.OneToOne_Optional_FK_Inverse2 != null && x.OneToOne_Optional_FK_Inverse2.Name.Contains("L1 01"))); [ConditionalTheory] @@ -4015,18 +4011,21 @@ public virtual Task Null_check_removal_applied_recursively_complex(bool async) public virtual Task Correlated_projection_with_first(bool async) => AssertQuery( async, - ss => ss.Set().Select(x => new - { - x.Id, - Results = x.OneToMany_Optional1.OrderBy(xx => xx.Id).First().OneToMany_Optional2.Select(xx => xx.OneToOne_Required_FK3.Id) - }), - ss => ss.Set().Select(x => new - { - x.Id, - Results = x.OneToMany_Optional1.OrderBy(xx => xx.Id).Any() - ? x.OneToMany_Optional1.OrderBy(xx => xx.Id).First().OneToMany_Optional2.Select(xx => xx.OneToOne_Required_FK3.Id) - : new List() - }), + ss => ss.Set().Select( + x => new + { + x.Id, + Results = x.OneToMany_Optional1.OrderBy(xx => xx.Id).First().OneToMany_Optional2 + .Select(xx => xx.OneToOne_Required_FK3.Id) + }), + ss => ss.Set().Select( + x => new + { + x.Id, + Results = x.OneToMany_Optional1.OrderBy(xx => xx.Id).Any() + ? x.OneToMany_Optional1.OrderBy(xx => xx.Id).First().OneToMany_Optional2.Select(xx => xx.OneToOne_Required_FK3.Id) + : new List() + }), elementSorter: e => e.Id, elementAsserter: (e, a) => { @@ -4039,23 +4038,26 @@ public virtual Task Correlated_projection_with_first(bool async) public virtual Task Max_in_multi_level_nested_subquery(bool async) => AssertQuery( async, - ss => ss.Set().OrderBy(l1 => l1.Id).Take(2).Select(x => new - { - x.Id, - LevelTwos = x.OneToMany_Optional1.AsQueryable().Select(xx => new + ss => ss.Set().OrderBy(l1 => l1.Id).Take(2).Select( + x => new { - xx.Id, - LevelThree = new - { - xx.OneToOne_Required_FK2.Id, - LevelFour = new + x.Id, + LevelTwos = x.OneToMany_Optional1.AsQueryable().Select( + xx => new { - xx.OneToOne_Required_FK2.OneToOne_Required_FK3.Id, - Result = (xx.OneToOne_Required_FK2.OneToMany_Optional3.Max(xxx => (int?)xxx.Id) ?? 0) > 1 - } - } - }).ToList() - }), + xx.Id, + LevelThree = new + { + xx.OneToOne_Required_FK2.Id, + LevelFour = new + { + xx.OneToOne_Required_FK2.OneToOne_Required_FK3.Id, + Result = (xx.OneToOne_Required_FK2.OneToMany_Optional3.Max(xxx => (int?)xxx.Id) ?? 0) + > 1 + } + } + }).ToList() + }), elementSorter: e => e.Id, elementAsserter: (e, a) => { @@ -4078,20 +4080,17 @@ public virtual Task Max_in_multi_level_nested_subquery(bool async) public virtual Task Multiple_select_many_in_projection(bool async) => AssertQuery( async, - ss => ss.Set().Select(x => new - { - x.Id, - Collection = x.OneToMany_Optional1 - .SelectMany(xx => xx.OneToMany_Optional2) - .OrderBy(xx => xx.Id).Take(12) - .Select(xx => new - { - xx.Id, - RefId = xx.OneToOne_Optional_FK3.Id - }).ToList(), - Count = x.OneToMany_Optional1 - .SelectMany(xx => xx.OneToMany_Optional2).Count(xx => xx.Name != "") - }), + ss => ss.Set().Select( + x => new + { + x.Id, + Collection = x.OneToMany_Optional1 + .SelectMany(xx => xx.OneToMany_Optional2) + .OrderBy(xx => xx.Id).Take(12) + .Select(xx => new { xx.Id, RefId = xx.OneToOne_Optional_FK3.Id }).ToList(), + Count = x.OneToMany_Optional1 + .SelectMany(xx => xx.OneToMany_Optional2).Count(xx => xx.Name != "") + }), elementSorter: e => e.Id, elementAsserter: (e, a) => { @@ -4113,18 +4112,15 @@ public virtual Task Multiple_select_many_in_projection(bool async) public virtual Task Single_select_many_in_projection_with_take(bool async) => AssertQuery( async, - ss => ss.Set().Select(x => new - { - x.Id, - Collection = x.OneToMany_Optional1 - .SelectMany(xx => xx.OneToMany_Optional2) - .OrderBy(xx => xx.Id).Take(12) - .Select(xx => new - { - xx.Id, - RefId = xx.OneToOne_Optional_FK3.Id - }).ToList(), - }), + ss => ss.Set().Select( + x => new + { + x.Id, + Collection = x.OneToMany_Optional1 + .SelectMany(xx => xx.OneToMany_Optional2) + .OrderBy(xx => xx.Id).Take(12) + .Select(xx => new { xx.Id, RefId = xx.OneToOne_Optional_FK3.Id }).ToList(), + }), elementSorter: e => e.Id, elementAsserter: (e, a) => { diff --git a/test/EFCore.Specification.Tests/Query/ComplexNavigationsSharedTypeQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/ComplexNavigationsSharedTypeQueryTestBase.cs index f8431bf9861..1c7c4db433d 100644 --- a/test/EFCore.Specification.Tests/Query/ComplexNavigationsSharedTypeQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/ComplexNavigationsSharedTypeQueryTestBase.cs @@ -70,7 +70,8 @@ public override Task Project_shadow_properties9(bool async) public override async Task Null_check_removal_applied_recursively_complex(bool async) { - var message = (await Assert.ThrowsAsync(() => base.Null_check_removal_applied_recursively_complex(async))).Message; + var message = + (await Assert.ThrowsAsync(() => base.Null_check_removal_applied_recursively_complex(async))).Message; Assert.Equal(CoreStrings.IncludeOnNonEntity("x => x.OneToMany_Required_Inverse3"), message); } diff --git a/test/EFCore.Specification.Tests/Query/ComplexTypeQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/ComplexTypeQueryTestBase.cs index c052448915d..51a6f55d5bd 100644 --- a/test/EFCore.Specification.Tests/Query/ComplexTypeQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/ComplexTypeQueryTestBase.cs @@ -10,9 +10,7 @@ public abstract class ComplexTypeQueryTestBase : QueryTestBase fixture.ListLoggerFactory.Clear(); [ConditionalTheory] [MemberData(nameof(IsAsyncData))] @@ -322,12 +320,11 @@ public virtual Task Filter_on_property_inside_nested_struct_complex_type_after_s [ConditionalTheory] [MemberData(nameof(IsAsyncData))] public virtual Task Filter_on_required_property_inside_required_struct_complex_type_on_optional_navigation(bool async) - { - return AssertQuery( + => AssertQuery( async, ss => ss.Set().Where(cg => cg.OptionalCustomer!.ShippingAddress.ZipCode != 07728), - ss => ss.Set().Where(cg => cg.OptionalCustomer == null || cg.OptionalCustomer.ShippingAddress.ZipCode != 07728)); - } + ss => ss.Set() + .Where(cg => cg.OptionalCustomer == null || cg.OptionalCustomer.ShippingAddress.ZipCode != 07728)); [ConditionalTheory] [MemberData(nameof(IsAsyncData))] @@ -679,10 +676,11 @@ public virtual Task Union_of_same_entity_with_nested_complex_type_projected_twic from c2 in ss.Set() orderby c1.Id, c2.Id select new { c1, c2 }) - .Union(from c1 in ss.Set() - from c2 in ss.Set() - orderby c1.Id, c2.Id - select new { c1, c2 }) + .Union( + from c1 in ss.Set() + from c2 in ss.Set() + orderby c1.Id, c2.Id + select new { c1, c2 }) .OrderBy(x => x.c1.Id).ThenBy(x => x.c2.Id) .Take(50) .Select(x => new { x.c1, x.c2 }), @@ -702,10 +700,11 @@ public virtual Task Union_of_same_entity_with_nested_complex_type_projected_twic from c2 in ss.Set() orderby c1.Id, c2.Id select new { c1, c2 }) - .Union(from c1 in ss.Set() - from c2 in ss.Set() - orderby c1.Id, c2.Id - select new { c1, c2 }) + .Union( + from c1 in ss.Set() + from c2 in ss.Set() + orderby c1.Id, c2.Id + select new { c1, c2 }) .OrderBy(x => x.c1.Id).ThenBy(x => x.c2.Id) .Take(50) .Select(x => new { x.c1, x.c2 }) @@ -729,10 +728,11 @@ public virtual Task Union_of_same_nested_complex_type_projected_twice_with_pushd from c2 in ss.Set() orderby c1.Id, c2.Id select new { BA1 = c1.BillingAddress, BA2 = c2.BillingAddress }) - .Union(from c1 in ss.Set() - from c2 in ss.Set() - orderby c1.Id, c2.Id - select new { BA1 = c1.BillingAddress, BA2 = c2.BillingAddress }) + .Union( + from c1 in ss.Set() + from c2 in ss.Set() + orderby c1.Id, c2.Id + select new { BA1 = c1.BillingAddress, BA2 = c2.BillingAddress }) .OrderBy(x => x.BA1.ZipCode).ThenBy(x => x.BA2.ZipCode) .Take(50) .Select(x => new { x.BA1, x.BA2 }), @@ -752,10 +752,11 @@ public virtual Task Union_of_same_nested_complex_type_projected_twice_with_doubl from c2 in ss.Set() orderby c1.Id, c2.Id select new { BA1 = c1.BillingAddress, BA2 = c2.BillingAddress }) - .Union(from c1 in ss.Set() - from c2 in ss.Set() - orderby c1.Id, c2.Id - select new { BA1 = c1.BillingAddress, BA2 = c2.BillingAddress }) + .Union( + from c1 in ss.Set() + from c2 in ss.Set() + orderby c1.Id, c2.Id + select new { BA1 = c1.BillingAddress, BA2 = c2.BillingAddress }) .OrderBy(x => x.BA1.ZipCode).ThenBy(x => x.BA2.ZipCode) .Take(50) .Select(x => new { x.BA1, x.BA2 }) @@ -775,14 +776,15 @@ from c2 in ss.Set() public virtual Task Same_entity_with_complex_type_projected_twice_with_pushdown_as_part_of_another_projection(bool async) => AssertQuery( async, - ss => ss.Set().Select(x => new - { - x.Id, - Complex = (from c1 in ss.Set() - from c2 in ss.Set() - orderby c1.Id, c2.Id descending - select new { One = c1, Two = c2 }).FirstOrDefault() - }), + ss => ss.Set().Select( + x => new + { + x.Id, + Complex = (from c1 in ss.Set() + from c2 in ss.Set() + orderby c1.Id, c2.Id descending + select new { One = c1, Two = c2 }).FirstOrDefault() + }), elementSorter: e => e.Id, elementAsserter: (e, a) => { @@ -796,14 +798,15 @@ from c2 in ss.Set() public virtual Task Same_complex_type_projected_twice_with_pushdown_as_part_of_another_projection(bool async) => AssertQuery( async, - ss => ss.Set().Select(x => new - { - x.Id, - Complex = (from c1 in ss.Set() - from c2 in ss.Set() - orderby c1.Id, c2.Id descending - select new { One = c1.BillingAddress, Two = c2.BillingAddress }).FirstOrDefault() - }), + ss => ss.Set().Select( + x => new + { + x.Id, + Complex = (from c1 in ss.Set() + from c2 in ss.Set() + orderby c1.Id, c2.Id descending + select new { One = c1.BillingAddress, Two = c2.BillingAddress }).FirstOrDefault() + }), elementSorter: e => e.Id, elementAsserter: (e, a) => { diff --git a/test/EFCore.Specification.Tests/Query/FilteredQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/FilteredQueryTestBase.cs index f8c14e5afaf..f3549470a7d 100644 --- a/test/EFCore.Specification.Tests/Query/FilteredQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/FilteredQueryTestBase.cs @@ -54,7 +54,8 @@ public Task AssertFilteredQueryScalar( bool assertEmpty = false, [CallerMemberName] string testMethodName = null) where TResult : struct - => QueryAsserter.AssertQueryScalar(actualQuery, expectedQuery, asserter, assertOrder, assertEmpty, async, testMethodName, filteredQuery: true); + => QueryAsserter.AssertQueryScalar( + actualQuery, expectedQuery, asserter, assertOrder, assertEmpty, async, testMethodName, filteredQuery: true); protected Task AssertFilteredCount( bool async, diff --git a/test/EFCore.Specification.Tests/Query/FunkyDataQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/FunkyDataQueryTestBase.cs index bab811541e9..bb78977da6e 100644 --- a/test/EFCore.Specification.Tests/Query/FunkyDataQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/FunkyDataQueryTestBase.cs @@ -539,7 +539,6 @@ public virtual Task String_FirstOrDefault_and_LastOrDefault(bool async) AssertEqual(e.last, a.last); }); - [ConditionalTheory] // #32432 [MemberData(nameof(IsAsyncData))] public virtual Task String_Contains_and_StartsWith_with_same_parameter(bool async) diff --git a/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs index fb245ad579c..ec8180be84c 100644 --- a/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs @@ -683,8 +683,7 @@ public virtual Task Select_enum_has_flag(bool async) .Select( b => new { - hasFlagTrue = b.Rank.HasFlag(MilitaryRank.Corporal), - hasFlagFalse = b.Rank.HasFlag(MilitaryRank.Sergeant) + hasFlagTrue = b.Rank.HasFlag(MilitaryRank.Corporal), hasFlagFalse = b.Rank.HasFlag(MilitaryRank.Sergeant) })); [ConditionalTheory] @@ -1136,11 +1135,11 @@ public virtual Task Where_compare_anonymous_types(bool async) ss => from g in ss.Set() from o in ss.Set().OfType() where new - { - Name = g.LeaderNickname, - Squad = g.LeaderSquadId, - Five = 5 - } + { + Name = g.LeaderNickname, + Squad = g.LeaderSquadId, + Five = 5 + } == new { Name = o.Nickname, @@ -2846,7 +2845,7 @@ public virtual Task Comparing_two_collection_navigations_composite_key(bool asyn async, ss => from g1 in ss.Set() from g2 in ss.Set() - // ReSharper disable once PossibleUnintendedReferenceComparison + // ReSharper disable once PossibleUnintendedReferenceComparison where g1.Weapons == g2.Weapons orderby g1.Nickname select new { Nickname1 = g1.Nickname, Nickname2 = g2.Nickname }, @@ -5597,22 +5596,22 @@ public virtual Task Navigation_based_on_complex_expression3(bool async) public virtual async Task Navigation_based_on_complex_expression4(bool async) // Nav expansion. Issue #17782. => await Assert.ThrowsAsync( - () => AssertQuery( - async, - ss => from lc1 in ss.Set().Select(f => (f is LocustHorde) ? ((LocustHorde)f).Commander : null) - from lc2 in ss.Set().OfType() - select (lc1 ?? lc2).DefeatedBy)); + () => AssertQuery( + async, + ss => from lc1 in ss.Set().Select(f => (f is LocustHorde) ? ((LocustHorde)f).Commander : null) + from lc2 in ss.Set().OfType() + select (lc1 ?? lc2).DefeatedBy)); [ConditionalTheory] [MemberData(nameof(IsAsyncData))] public virtual async Task Navigation_based_on_complex_expression5(bool async) // Nav expansion. Issue #17782. => await Assert.ThrowsAsync( - () => AssertQuery( - async, - ss => from lc1 in ss.Set().OfType().Select(lh => lh.Commander) - join lc2 in ss.Set().OfType() on true equals true - select (lc1 ?? lc2).DefeatedBy)); + () => AssertQuery( + async, + ss => from lc1 in ss.Set().OfType().Select(lh => lh.Commander) + join lc2 in ss.Set().OfType() on true equals true + select (lc1 ?? lc2).DefeatedBy)); [ConditionalTheory] [MemberData(nameof(IsAsyncData))] @@ -6828,11 +6827,13 @@ public virtual Task FirstOrDefault_over_int_compared_to_zero(bool async) => AssertQuery( async, ss => ss.Set().Where(s => s.Name == "Delta") - .Where(s => s.Members - .Where(m => m.HasSoulPatch) - .OrderBy(m => m.FullName) - .Select(m => m.SquadId) - .FirstOrDefault() != 0) + .Where( + s => s.Members + .Where(m => m.HasSoulPatch) + .OrderBy(m => m.FullName) + .Select(m => m.SquadId) + .FirstOrDefault() + != 0) .Select(s => s.Name), elementSorter: e => e); @@ -8258,10 +8259,12 @@ public virtual Task Where_subquery_equality_to_null_with_composite_key(bool asyn public virtual Task Where_subquery_equality_to_null_with_composite_key_should_match_nulls(bool async) => AssertQuery( async, - ss => ss.Set().Where(s => s.Members - .Where(m => m.FullName == "Anthony Carmine") - .OrderBy(e => e.Nickname) - .FirstOrDefault() == null)); + ss => ss.Set().Where( + s => s.Members + .Where(m => m.FullName == "Anthony Carmine") + .OrderBy(e => e.Nickname) + .FirstOrDefault() + == null)); [ConditionalTheory] [MemberData(nameof(IsAsyncData))] @@ -8276,7 +8279,8 @@ public virtual Task Where_subquery_equality_to_null_without_composite_key(bool a public virtual Task Where_subquery_equality_to_null_without_composite_key_should_match_null(bool async) => AssertQuery( async, - ss => ss.Set().Where(s => s.Weapons.Where(w => w.Name == "Hammer of Dawn").OrderBy(e => e.Name).FirstOrDefault() == null)); + ss => ss.Set().Where( + s => s.Weapons.Where(w => w.Name == "Hammer of Dawn").OrderBy(e => e.Name).FirstOrDefault() == null)); [ConditionalTheory] [MemberData(nameof(IsAsyncData))] @@ -8477,12 +8481,12 @@ public virtual Task Find_underlying_property_after_GroupJoin_DefaultIfEmpty(bool async, ss => from g in ss.Set() join lc in ss.Set().OfType() - on g.Nickname equals lc.DefeatedByNickname into grouping + on g.Nickname equals lc.DefeatedByNickname into grouping from lc in grouping.DefaultIfEmpty() select new GearLocustLeaderDto { FullName = g.FullName, ThreatLevel = lc.ThreatLevel }, ss => from g in ss.Set() join lc in ss.Set().OfType() - on g.Nickname equals lc.DefeatedByNickname into grouping + on g.Nickname equals lc.DefeatedByNickname into grouping from lc in grouping.DefaultIfEmpty() select new GearLocustLeaderDto { FullName = g.FullName, ThreatLevel = lc != null ? lc.ThreatLevel : null }, elementSorter: e => (e.FullName, e.ThreatLevel), @@ -8548,7 +8552,12 @@ await AssertQuery( ss => from g in ss.Set().Include(x => x.Weapons) join o in ss.Set() on g.LeaderNickname equals o.Nickname into grouping from o in grouping.DefaultIfEmpty() - select new { One = 1, Result = o ?? (g ?? o), IsMarcus = g.Nickname == "Marcus" }, + select new + { + One = 1, + Result = o ?? (g ?? o), + IsMarcus = g.Nickname == "Marcus" + }, elementSorter: e => e.Result.Nickname, elementAsserter: (e, a) => { @@ -8568,7 +8577,12 @@ await AssertQuery( ss => from g in ss.Set() join o in ss.Set().Include(x => x.Weapons) on g.LeaderNickname equals o.Nickname into grouping from o in grouping.DefaultIfEmpty() - select new { One = 1, Two = o, Result = o ?? (g ?? o) }, + select new + { + One = 1, + Two = o, + Result = o ?? (g ?? o) + }, elementSorter: e => e.Result.Nickname, elementAsserter: (e, a) => { @@ -8627,7 +8641,6 @@ await AssertQuery( ss => ss.Set().Where(x => keys.Contains(ammoTypes.Contains(x.AmmunitionType) ? key : key))); } - [ConditionalTheory] [MemberData(nameof(IsAsyncData))] // Issue #33330 public virtual Task Non_string_concat_uses_appropriate_type_mapping(bool async) diff --git a/test/EFCore.Specification.Tests/Query/JsonQueryFixtureBase.cs b/test/EFCore.Specification.Tests/Query/JsonQueryFixtureBase.cs index db55c4a6700..de2bc86c787 100644 --- a/test/EFCore.Specification.Tests/Query/JsonQueryFixtureBase.cs +++ b/test/EFCore.Specification.Tests/Query/JsonQueryFixtureBase.cs @@ -335,6 +335,7 @@ public static void AssertOwnedRoot(JsonOwnedRoot expected, JsonOwnedRoot actual) public static void AssertOwnedBranch(JsonOwnedBranch expected, JsonOwnedBranch actual) { + Assert.Equal(expected.Id, actual.Id); Assert.Equal(expected.Date, actual.Date); Assert.Equal(expected.Fraction, actual.Fraction); Assert.Equal(expected.Enum, actual.Enum); @@ -651,7 +652,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con }); } - protected override string StoreName { get; } = "JsonQueryTest"; + protected override string StoreName + => "JsonQueryTest"; public override JsonQueryContext CreateContext() { diff --git a/test/EFCore.Specification.Tests/Query/JsonQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/JsonQueryTestBase.cs index 2aebccf72a6..b7cfe2ae3ce 100644 --- a/test/EFCore.Specification.Tests/Query/JsonQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/JsonQueryTestBase.cs @@ -302,8 +302,7 @@ public virtual Task Basic_json_projection_enum_inside_json_entity(bool async) ss => ss.Set().Select( x => new { - x.Id, - x.OwnedReferenceRoot.OwnedReferenceBranch.Enum, + x.Id, x.OwnedReferenceRoot.OwnedReferenceBranch.Enum, }), elementSorter: e => e.Id, elementAsserter: (e, a) => @@ -320,8 +319,7 @@ public virtual Task Json_projection_enum_with_custom_conversion(bool async) ss => ss.Set().Select( x => new { - x.Id, - x.OwnedReferenceRoot.Enum, + x.Id, x.OwnedReferenceRoot.Enum, }), elementSorter: e => e.Id, elementAsserter: (e, a) => @@ -1109,7 +1107,8 @@ public virtual Task Json_collection_index_in_predicate_nested_mix(bool async) return AssertQuery( async, ss => ss.Set().Where( - x => x.OwnedCollectionRoot[1].OwnedCollectionBranch[prm].OwnedCollectionLeaf[x.Id - 1].SomethingSomething == "e1_c2_c1_c1")); + x => x.OwnedCollectionRoot[1].OwnedCollectionBranch[prm].OwnedCollectionLeaf[x.Id - 1].SomethingSomething + == "e1_c2_c1_c1")); } [ConditionalTheory] @@ -1443,8 +1442,7 @@ public virtual Task Json_branch_collection_distinct_and_other_collection(bool as .Select( x => new { - First = x.OwnedReferenceRoot.OwnedCollectionBranch.Distinct().ToList(), - Second = x.EntityCollection.ToList() + First = x.OwnedReferenceRoot.OwnedCollectionBranch.Distinct().ToList(), Second = x.EntityCollection.ToList() }) .AsNoTracking(), assertOrder: true, @@ -1825,8 +1823,7 @@ public virtual Task Json_collection_index_in_projection_when_owner_is_present_mi ss => ss.Set().Select( x => new { - x, - CollectionElement = x.OwnedCollectionRoot[1].OwnedCollectionBranch[prm], + x, CollectionElement = x.OwnedCollectionRoot[1].OwnedCollectionBranch[prm], }).AsNoTracking(), elementSorter: e => e.x.Id, elementAsserter: (e, a) => @@ -1847,8 +1844,7 @@ public virtual Task Json_collection_index_in_projection_when_owner_is_not_presen ss => ss.Set().Select( x => new { - x.Id, - CollectionElement = x.OwnedCollectionRoot[1].OwnedCollectionBranch[prm], + x.Id, CollectionElement = x.OwnedCollectionRoot[1].OwnedCollectionBranch[prm], }).AsNoTracking(), elementSorter: e => e.Id, elementAsserter: (e, a) => @@ -2586,8 +2582,7 @@ public virtual Task Json_predicate_on_string_Y_N_converted_to_bool(bool async) [ConditionalTheory] [MemberData(nameof(IsAsyncData))] public virtual Task Json_projection_collection_element_and_reference_AsNoTrackingWithIdentityResolution(bool async) - { - return AssertQuery( + => AssertQuery( async, ss => ss.Set().Select( x => new @@ -2603,42 +2598,29 @@ public virtual Task Json_projection_collection_element_and_reference_AsNoTrackin AssertEqual(e.CollectionElement, a.CollectionElement); AssertEqual(e.Reference, a.Reference); }); - } [ConditionalTheory] [MemberData(nameof(IsAsyncData))] public virtual Task Json_projection_nothing_interesting_AsNoTrackingWithIdentityResolution(bool async) - { - return AssertQuery( + => AssertQuery( async, ss => ss.Set().Select( - x => new - { - x.Id, - x.Name - }).AsNoTrackingWithIdentityResolution(), + x => new { x.Id, x.Name }).AsNoTrackingWithIdentityResolution(), elementSorter: e => e.Id); - } [ConditionalTheory] [MemberData(nameof(IsAsyncData))] public virtual Task Json_projection_owner_entity_AsNoTrackingWithIdentityResolution(bool async) - { - return AssertQuery( + => AssertQuery( async, ss => ss.Set().Select( - x => new - { - x.Id, - x - }).AsNoTrackingWithIdentityResolution(), + x => new { x.Id, x }).AsNoTrackingWithIdentityResolution(), elementSorter: e => e.Id, elementAsserter: (e, a) => { AssertEqual(e.Id, a.Id); AssertEqual(e.x, a.x); }); - } [ConditionalTheory] [MemberData(nameof(IsAsyncData))] @@ -2672,7 +2654,9 @@ public virtual Task Json_nested_collection_anonymous_projection_of_primitives_in [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual Task Json_projection_second_element_through_collection_element_constant_projected_after_owner_nested_AsNoTrackingWithIdentityResolution(bool async) + public virtual Task + Json_projection_second_element_through_collection_element_constant_projected_after_owner_nested_AsNoTrackingWithIdentityResolution( + bool async) => AssertQuery( async, ss => ss.Set().Select( @@ -2714,7 +2698,9 @@ public virtual Task Json_projection_reference_collection_and_collection_element_ [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual Task Json_projection_second_element_through_collection_element_parameter_correctly_projected_after_owner_nested_AsNoTrackingWithIdentityResolution(bool async) + public virtual Task + Json_projection_second_element_through_collection_element_parameter_correctly_projected_after_owner_nested_AsNoTrackingWithIdentityResolution( + bool async) { var prm = 1; @@ -2738,14 +2724,15 @@ public virtual Task Json_projection_second_element_through_collection_element_pa [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual Task Json_projection_only_second_element_through_collection_element_constant_projected_nested_AsNoTrackingWithIdentityResolution(bool async) + public virtual Task + Json_projection_only_second_element_through_collection_element_constant_projected_nested_AsNoTrackingWithIdentityResolution( + bool async) => AssertQuery( async, ss => ss.Set().Select( x => new { - x.Id, - Element = x.OwnedReferenceRoot.OwnedCollectionBranch[0].OwnedCollectionLeaf[1], + x.Id, Element = x.OwnedReferenceRoot.OwnedCollectionBranch[0].OwnedCollectionLeaf[1], }).AsNoTrackingWithIdentityResolution(), elementSorter: e => e.Id, elementAsserter: (e, a) => @@ -2756,7 +2743,9 @@ public virtual Task Json_projection_only_second_element_through_collection_eleme [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual Task Json_projection_only_second_element_through_collection_element_parameter_projected_nested_AsNoTrackingWithIdentityResolution(bool async) + public virtual Task + Json_projection_only_second_element_through_collection_element_parameter_projected_nested_AsNoTrackingWithIdentityResolution( + bool async) { var prm1 = 0; var prm2 = 1; @@ -2766,8 +2755,7 @@ public virtual Task Json_projection_only_second_element_through_collection_eleme ss => ss.Set().Select( x => new { - x.Id, - Element = x.OwnedReferenceRoot.OwnedCollectionBranch[prm1].OwnedCollectionLeaf[prm2], + x.Id, Element = x.OwnedReferenceRoot.OwnedCollectionBranch[prm1].OwnedCollectionLeaf[prm2], }).AsNoTrackingWithIdentityResolution(), elementSorter: e => e.Id, elementAsserter: (e, a) => @@ -2779,9 +2767,10 @@ public virtual Task Json_projection_only_second_element_through_collection_eleme [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual Task Json_projection_second_element_through_collection_element_constant_different_values_projected_before_owner_nested_AsNoTrackingWithIdentityResolution(bool async) - { - return AssertQuery( + public virtual Task + Json_projection_second_element_through_collection_element_constant_different_values_projected_before_owner_nested_AsNoTrackingWithIdentityResolution( + bool async) + => AssertQuery( async, ss => ss.Set().Select( x => new @@ -2797,13 +2786,11 @@ public virtual Task Json_projection_second_element_through_collection_element_co AssertEqual(e.Duplicate, a.Duplicate); AssertCollection(e.Original, a.Original, ordered: true); }); - } [ConditionalTheory] [MemberData(nameof(IsAsyncData))] public virtual Task Json_projection_nested_collection_and_element_correct_order_AsNoTrackingWithIdentityResolution(bool async) - { - return AssertQuery( + => AssertQuery( async, ss => ss.Set().Select( x => new @@ -2819,11 +2806,12 @@ public virtual Task Json_projection_nested_collection_and_element_correct_order_ AssertCollection(e.Original, a.Original, ordered: true); AssertEqual(e.Duplicate, a.Duplicate); }); - } [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual Task Json_projection_nested_collection_element_using_parameter_and_the_owner_in_correct_order_AsNoTrackingWithIdentityResolution(bool async) + public virtual Task + Json_projection_nested_collection_element_using_parameter_and_the_owner_in_correct_order_AsNoTrackingWithIdentityResolution( + bool async) { var prm = 0; return AssertQuery( @@ -2847,8 +2835,7 @@ public virtual Task Json_projection_nested_collection_element_using_parameter_an [ConditionalTheory] [MemberData(nameof(IsAsyncData))] public virtual Task Json_projection_second_element_projected_before_owner_as_well_as_root_AsNoTrackingWithIdentityResolution(bool async) - { - return AssertQuery( + => AssertQuery( async, ss => ss.Set().Select( x => new @@ -2865,11 +2852,11 @@ public virtual Task Json_projection_second_element_projected_before_owner_as_wel AssertEqual(e.Original, a.Original); AssertEqual(e.Duplicate, a.Duplicate); }); - } [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual Task Json_projection_second_element_projected_before_owner_nested_as_well_as_root_AsNoTrackingWithIdentityResolution(bool async) + public virtual Task Json_projection_second_element_projected_before_owner_nested_as_well_as_root_AsNoTrackingWithIdentityResolution( + bool async) => AssertQuery( async, ss => ss.Set().Select( diff --git a/test/EFCore.Specification.Tests/Query/NonSharedPrimitiveCollectionsQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/NonSharedPrimitiveCollectionsQueryTestBase.cs index 168c491f486..a49d0f9dc8d 100644 --- a/test/EFCore.Specification.Tests/Query/NonSharedPrimitiveCollectionsQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/NonSharedPrimitiveCollectionsQueryTestBase.cs @@ -223,8 +223,18 @@ public virtual async Task Project_collection_from_entity_type_with_owned() seed: context => { context.AddRange( - new TestEntityWithOwned { Id = 1, Ints = [1, 2], Owned = new Owned { Foo = 0 } }, - new TestEntityWithOwned { Id = 2, Ints = [3, 4], Owned = new Owned { Foo = 1 } }); + new TestEntityWithOwned + { + Id = 1, + Ints = [1, 2], + Owned = new Owned { Foo = 0 } + }, + new TestEntityWithOwned + { + Id = 2, + Ints = [3, 4], + Owned = new Owned { Foo = 1 } + }); return context.SaveChangesAsync(); }); diff --git a/test/EFCore.Specification.Tests/Query/NorthwindCompiledQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/NorthwindCompiledQueryTestBase.cs index 17450108311..f83e32ebcf6 100644 --- a/test/EFCore.Specification.Tests/Query/NorthwindCompiledQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/NorthwindCompiledQueryTestBase.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.EntityFrameworkCore.TestModels.Northwind; -using Xunit.Sdk; // ReSharper disable AccessToModifiedClosure // ReSharper disable InconsistentNaming diff --git a/test/EFCore.Specification.Tests/Query/NorthwindFunctionsQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/NorthwindFunctionsQueryTestBase.cs index e34aaf66c39..39af9e8322f 100644 --- a/test/EFCore.Specification.Tests/Query/NorthwindFunctionsQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/NorthwindFunctionsQueryTestBase.cs @@ -88,25 +88,29 @@ public virtual Task String_StartsWith_with_StringComparison_OrdinalIgnoreCase(bo [MemberData(nameof(IsAsyncData))] public virtual async Task String_StartsWith_with_StringComparison_unsupported(bool async) { - await AssertTranslationFailed(() => - AssertQuery( - async, - ss => ss.Set().Where(c => c.CompanyName.StartsWith("Qu", StringComparison.CurrentCulture)))); - - await AssertTranslationFailed(() => - AssertQuery( - async, - ss => ss.Set().Where(c => c.ContactName.Contains("M", StringComparison.CurrentCultureIgnoreCase)))); - - await AssertTranslationFailed(() => - AssertQuery( - async, - ss => ss.Set().Where(c => c.ContactName.Contains("Qu", StringComparison.InvariantCulture)))); - - await AssertTranslationFailed(() => - AssertQuery( - async, - ss => ss.Set().Where(c => c.ContactName.Contains("Qu", StringComparison.InvariantCultureIgnoreCase)))); + await AssertTranslationFailed( + () => + AssertQuery( + async, + ss => ss.Set().Where(c => c.CompanyName.StartsWith("Qu", StringComparison.CurrentCulture)))); + + await AssertTranslationFailed( + () => + AssertQuery( + async, + ss => ss.Set().Where(c => c.ContactName.Contains("M", StringComparison.CurrentCultureIgnoreCase)))); + + await AssertTranslationFailed( + () => + AssertQuery( + async, + ss => ss.Set().Where(c => c.ContactName.Contains("Qu", StringComparison.InvariantCulture)))); + + await AssertTranslationFailed( + () => + AssertQuery( + async, + ss => ss.Set().Where(c => c.ContactName.Contains("Qu", StringComparison.InvariantCultureIgnoreCase)))); } #endregion String.StartsWith @@ -171,25 +175,29 @@ public virtual Task String_EndsWith_with_StringComparison_OrdinalIgnoreCase(bool [MemberData(nameof(IsAsyncData))] public virtual async Task String_EndsWith_with_StringComparison_unsupported(bool async) { - await AssertTranslationFailed(() => - AssertQuery( - async, - ss => ss.Set().Where(c => c.ContactName.EndsWith("Qu", StringComparison.CurrentCulture)))); - - await AssertTranslationFailed(() => - AssertQuery( - async, - ss => ss.Set().Where(c => c.ContactName.Contains("M", StringComparison.CurrentCultureIgnoreCase)))); - - await AssertTranslationFailed(() => - AssertQuery( - async, - ss => ss.Set().Where(c => c.ContactName.Contains("Qu", StringComparison.InvariantCulture)))); - - await AssertTranslationFailed(() => - AssertQuery( - async, - ss => ss.Set().Where(c => c.ContactName.Contains("Qu", StringComparison.InvariantCultureIgnoreCase)))); + await AssertTranslationFailed( + () => + AssertQuery( + async, + ss => ss.Set().Where(c => c.ContactName.EndsWith("Qu", StringComparison.CurrentCulture)))); + + await AssertTranslationFailed( + () => + AssertQuery( + async, + ss => ss.Set().Where(c => c.ContactName.Contains("M", StringComparison.CurrentCultureIgnoreCase)))); + + await AssertTranslationFailed( + () => + AssertQuery( + async, + ss => ss.Set().Where(c => c.ContactName.Contains("Qu", StringComparison.InvariantCulture)))); + + await AssertTranslationFailed( + () => + AssertQuery( + async, + ss => ss.Set().Where(c => c.ContactName.Contains("Qu", StringComparison.InvariantCultureIgnoreCase)))); } #endregion String.EndsWith @@ -258,25 +266,29 @@ public virtual Task String_Contains_with_StringComparison_OrdinalIgnoreCase(bool [MemberData(nameof(IsAsyncData))] public virtual async Task String_Contains_with_StringComparison_unsupported(bool async) { - await AssertTranslationFailed(() => - AssertQuery( - async, - ss => ss.Set().Where(c => c.ContactName.Contains("M", StringComparison.CurrentCulture)))); - - await AssertTranslationFailed(() => - AssertQuery( - async, - ss => ss.Set().Where(c => c.ContactName.Contains("M", StringComparison.CurrentCultureIgnoreCase)))); - - await AssertTranslationFailed(() => - AssertQuery( - async, - ss => ss.Set().Where(c => c.ContactName.Contains("M", StringComparison.InvariantCulture)))); - - await AssertTranslationFailed(() => - AssertQuery( - async, - ss => ss.Set().Where(c => c.ContactName.Contains("M", StringComparison.InvariantCultureIgnoreCase)))); + await AssertTranslationFailed( + () => + AssertQuery( + async, + ss => ss.Set().Where(c => c.ContactName.Contains("M", StringComparison.CurrentCulture)))); + + await AssertTranslationFailed( + () => + AssertQuery( + async, + ss => ss.Set().Where(c => c.ContactName.Contains("M", StringComparison.CurrentCultureIgnoreCase)))); + + await AssertTranslationFailed( + () => + AssertQuery( + async, + ss => ss.Set().Where(c => c.ContactName.Contains("M", StringComparison.InvariantCulture)))); + + await AssertTranslationFailed( + () => + AssertQuery( + async, + ss => ss.Set().Where(c => c.ContactName.Contains("M", StringComparison.InvariantCultureIgnoreCase)))); } #endregion String.Contains @@ -350,7 +362,8 @@ public virtual Task String_Join_with_predicate(bool async) .Select( g => new { - City = g.Key, Customers = string.Join("|", g.Where(e => e.ContactName.Length > 10).Select(e => e.CustomerID)) + City = g.Key, + Customers = string.Join("|", g.Where(e => e.ContactName.Length > 10).Select(e => e.CustomerID)) }), elementSorter: x => x.City, elementAsserter: (e, a) => diff --git a/test/EFCore.Specification.Tests/Query/NorthwindGroupByQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/NorthwindGroupByQueryTestBase.cs index 0e97440fa69..ee4db2c2cbd 100644 --- a/test/EFCore.Specification.Tests/Query/NorthwindGroupByQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/NorthwindGroupByQueryTestBase.cs @@ -2543,8 +2543,7 @@ public virtual Task GroupBy_group_Distinct_Select_Distinct_aggregate(bool async) g => new { - g.Key, - Max = g.Distinct().Select(e => e.OrderDate).Distinct().Max(), + g.Key, Max = g.Distinct().Select(e => e.OrderDate).Distinct().Max(), }), elementSorter: e => e.Key); @@ -2559,8 +2558,7 @@ public virtual Task GroupBy_group_Where_Select_Distinct_aggregate(bool async) g => new { - g.Key, - Max = g.Where(e => e.OrderDate.HasValue).Select(e => e.OrderDate).Distinct().Max(), + g.Key, Max = g.Where(e => e.OrderDate.HasValue).Select(e => e.OrderDate).Distinct().Max(), }), elementSorter: e => e.Key); @@ -2760,6 +2758,15 @@ public virtual Task Final_GroupBy_property_entity_projecting_collection_and_sing AssertEqual(ee.LastOrder, aa.LastOrder); })); + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Final_GroupBy_TagWith(bool async) + => AssertQuery( + async, + ss => ss.Set().TagWith("foo").GroupBy(c => c.City), + elementSorter: e => e.Key, + elementAsserter: (e, a) => AssertGrouping(e, a)); + #endregion #region GroupByWithoutAggregate diff --git a/test/EFCore.Specification.Tests/Query/NorthwindMiscellaneousQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/NorthwindMiscellaneousQueryTestBase.cs index 286ee9ef5f5..248bd260ce1 100644 --- a/test/EFCore.Specification.Tests/Query/NorthwindMiscellaneousQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/NorthwindMiscellaneousQueryTestBase.cs @@ -718,8 +718,7 @@ public virtual Task Ternary_should_not_evaluate_both_sides_with_parameter(bool a o => new { // ReSharper disable SimplifyConditionalTernaryExpression - Data1 = param != null ? o.OrderDate == param.Value : true, - Data2 = param == null ? true : o.OrderDate == param.Value + Data1 = param != null ? o.OrderDate == param.Value : true, Data2 = param == null ? true : o.OrderDate == param.Value // ReSharper restore SimplifyConditionalTernaryExpression })); } @@ -2496,6 +2495,33 @@ public virtual Task OrderByDescending_ThenByDescending(bool async) .Select(c => c.City), assertOrder: true); + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Select_Order(bool async) + => AssertQuery( + async, + ss => ss.Set().Select(c => c.CustomerID).Order(), + ss => ss.Set().Select(c => c.CustomerID).Order(StringComparer.Ordinal), + assertOrder: true); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Select_OrderDescending(bool async) + => AssertQuery( + async, + ss => ss.Set().Select(c => c.CustomerID).OrderDescending(), + ss => ss.Set().Select(c => c.CustomerID).OrderDescending(StringComparer.Ordinal), + assertOrder: true); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Where_Order_First(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(c => c.Orders.Order().First().OrderID == 10248).Select(c => c.CustomerID), + ss => ss.Set().AsEnumerable().Where(c => c.Orders.OrderBy(o => o.OrderID).FirstOrDefault()?.OrderID == 10248) + .Select(c => c.CustomerID).AsQueryable()); + [ConditionalTheory] [MemberData(nameof(IsAsyncData))] public virtual Task OrderBy_ThenBy_Any(bool async) @@ -3281,15 +3307,12 @@ public virtual Task Where_bitwise_binary_or(bool async) async, ss => ss.Set().Where(o => (o.OrderID | 10248) == 10248)); - [ConditionalTheory] [MemberData(nameof(IsAsyncData))] public virtual Task Where_bitwise_binary_xor(bool async) - { - return AssertQuery( + => AssertQuery( async, ss => ss.Set().Where(o => (o.OrderID ^ 1) == 10249)); - } [ConditionalTheory] [MemberData(nameof(IsAsyncData))] diff --git a/test/EFCore.Specification.Tests/Query/NorthwindQueryTaggingQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/NorthwindQueryTaggingQueryTestBase.cs index 1a8af0cf610..4a533a56233 100644 --- a/test/EFCore.Specification.Tests/Query/NorthwindQueryTaggingQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/NorthwindQueryTaggingQueryTestBase.cs @@ -148,6 +148,8 @@ var customer Assert.NotNull(customer); } + // See also NorthwindGroupByQueryTestBase.Final_GroupBy_TagWith + protected NorthwindContext CreateContext() => Fixture.CreateContext(); } diff --git a/test/EFCore.Specification.Tests/Query/NorthwindSelectQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/NorthwindSelectQueryTestBase.cs index 688f697b7ba..f7c619d7c6d 100644 --- a/test/EFCore.Specification.Tests/Query/NorthwindSelectQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/NorthwindSelectQueryTestBase.cs @@ -771,7 +771,7 @@ public virtual Task Select_conditional_drops_false(bool async) ? o.OrderID : false ? 0 - : -o.OrderID ); + : -o.OrderID); [ConditionalTheory] [MemberData(nameof(IsAsyncData))] @@ -783,7 +783,7 @@ public virtual Task Select_conditional_terminates_at_true(bool async) ? o.OrderID : true ? 0 - : -o.OrderID ); + : -o.OrderID); [ConditionalTheory] [MemberData(nameof(IsAsyncData))] @@ -1548,7 +1548,8 @@ public virtual Task Select_with_complex_expression_that_can_be_funcletized(bool => AssertQueryScalar( async, ss => ss.Set().Where(c => c.CustomerID == "ALFKI").Select(c => (int?)c.Region.IndexOf("")), - ss => ss.Set().Where(c => c.CustomerID == "ALFKI").Select(c => c.Region == null ? default(int?) : c.Region.IndexOf("")), + ss => ss.Set().Where(c => c.CustomerID == "ALFKI") + .Select(c => c.Region == null ? default(int?) : c.Region.IndexOf("")), assertOrder: true); [ConditionalTheory] @@ -2483,16 +2484,18 @@ public virtual Task Set_operation_in_pending_collection(bool async) async, ss => ss.Set() .OrderBy(x => x.CustomerID) - .Select(x => new - { - OrderIds = (from o1 in ss.Set() - where o1.CustomerID == x.CustomerID - select o1.OrderID) - .Union(from o2 in ss.Set() - where o2.CustomerID == x.CustomerID - select o2.OrderID) - .ToList() - }).Take(5), + .Select( + x => new + { + OrderIds = (from o1 in ss.Set() + where o1.CustomerID == x.CustomerID + select o1.OrderID) + .Union( + from o2 in ss.Set() + where o2.CustomerID == x.CustomerID + select o2.OrderID) + .ToList() + }).Take(5), assertOrder: true, elementAsserter: (e, a) => AssertCollection(e.OrderIds, a.OrderIds, elementSorter: ee => ee)); } diff --git a/test/EFCore.Specification.Tests/Query/NorthwindWhereQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/NorthwindWhereQueryTestBase.cs index f63d63faea2..c1de5a6b834 100644 --- a/test/EFCore.Specification.Tests/Query/NorthwindWhereQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/NorthwindWhereQueryTestBase.cs @@ -10,7 +10,6 @@ namespace Microsoft.EntityFrameworkCore.Query; // ReSharper disable ConvertToConstant.Local // ReSharper disable RedundantBoolCompare // ReSharper disable InconsistentNaming - public abstract class NorthwindWhereQueryTestBase(TFixture fixture) : QueryTestBase(fixture) where TFixture : NorthwindQueryFixtureBase, new() { @@ -1463,11 +1462,9 @@ public virtual Task Where_ternary_boolean_condition_with_false_as_result_false(b [ConditionalTheory] [MemberData(nameof(IsAsyncData))] public virtual Task Where_ternary_boolean_condition_negated(bool async) - { - return AssertQuery( + => AssertQuery( async, ss => ss.Set().Where(p => !(p.UnitsInStock >= 20 ? false : true))); - } [ConditionalTheory] [MemberData(nameof(IsAsyncData))] @@ -1556,7 +1553,7 @@ public virtual Task Where_compare_null(bool async) public virtual Task Where_compare_null_with_cast_to_object(bool async) => AssertQuery( async, - ss => ss.Set().Where(c => (object)c.Region == null)); + ss => ss.Set().Where(c => c.Region == null)); [ConditionalTheory] [MemberData(nameof(IsAsyncData))] @@ -1653,7 +1650,6 @@ public virtual Task Where_subquery_FirstOrDefault_compared_to_entity(bool async) async, ss => ss.Set().Where( c => c.Orders.OrderBy(o => o.OrderID).FirstOrDefault() == new Order { OrderID = 10276 }), - ss => ss.Set().Where( c => c.Orders.OrderBy(o => o.OrderID).FirstOrDefault().OrderID == 10276)); diff --git a/test/EFCore.Specification.Tests/Query/OwnedEntityQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/OwnedEntityQueryTestBase.cs index 57b319b2181..25b210961c9 100644 --- a/test/EFCore.Specification.Tests/Query/OwnedEntityQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/OwnedEntityQueryTestBase.cs @@ -42,7 +42,8 @@ public virtual async Task Include_collection_for_entity_with_owned_type_works() } } - private class Context9202(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context9202(DbContextOptions options) : DbContext(options) { public DbSet Movies { get; set; } public DbSet Actors { get; set; } @@ -113,7 +114,8 @@ public virtual async Task Multilevel_owned_entities_determine_correct_nullabilit await context.SaveChangesAsync(); } - private class Context13079(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context13079(DbContextOptions options) : DbContext(options) { public virtual DbSet BaseEntities { get; set; } @@ -182,7 +184,8 @@ public virtual async Task Correlated_subquery_with_owned_navigation_being_compar } } - private class Context13157(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context13157(DbContextOptions options) : DbContext(options) { public virtual DbSet Partners { get; set; } @@ -297,13 +300,19 @@ public Task SeedAsync() { SecondValueObjects = [ - new() + new SecondValueObject { FourthValueObject = - new FourthValueObject { FifthValueObjects = [new() { AnyValue = 10 }] }, + new FourthValueObject { FifthValueObjects = [new FifthValueObject { AnyValue = 10 }] }, ThirdValueObjects = [ - new() { FourthValueObject = new FourthValueObject { FifthValueObjects = [new() { AnyValue = 20 }] } } + new ThirdValueObject + { + FourthValueObject = new FourthValueObject + { + FifthValueObjects = [new FifthValueObject { AnyValue = 20 }] + } + } ] } ] @@ -363,8 +372,7 @@ public virtual async Task Projecting_correlated_collection_property_for_owned_en var query = context.Warehouses.Select( x => new Context18582.WarehouseModel { - WarehouseCode = x.WarehouseCode, - DestinationCountryCodes = x.DestinationCountries.Select(c => c.CountryCode).ToArray() + WarehouseCode = x.WarehouseCode, DestinationCountryCodes = x.DestinationCountries.Select(c => c.CountryCode).ToArray() }).AsNoTracking(); var result = async @@ -376,7 +384,8 @@ public virtual async Task Projecting_correlated_collection_property_for_owned_en Assert.True(new[] { "US", "CA" }.SequenceEqual(warehouseModel.DestinationCountryCodes)); } - private class Context18582(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context18582(DbContextOptions options) : DbContext(options) { public DbSet Warehouses { get; set; } @@ -441,7 +450,8 @@ public virtual async Task Accessing_scalar_property_in_derived_type_projection_d Assert.Equal("A", Assert.Single(result).OtherEntityData); } - private class Context19138(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context19138(DbContextOptions options) : DbContext(options) { public DbSet BaseEntities { get; set; } public DbSet OtherEntities { get; set; } @@ -523,7 +533,8 @@ public virtual async Task Multiple_single_result_in_projection_containing_owned_ x.Type, }; - private class Context20277(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context20277(DbContextOptions options) : DbContext(options) { public DbSet Entities => Set(); @@ -595,7 +606,8 @@ public virtual async Task Can_auto_include_navigation_from_model() } } - private class Context21540(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context21540(DbContextOptions options) : DbContext(options) { public DbSet Parents { get; set; } @@ -624,7 +636,7 @@ public Task SeedAsync() OwnedReference = new Owned(), Collection = [ - new(), new() + new Collection(), new Collection() ] } }; @@ -693,7 +705,8 @@ public virtual async Task Nested_owned_required_dependents_are_materialized() Assert.Equal(12345, result.Contact.Address.Zip); } - private class Context21807(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context21807(DbContextOptions options) : DbContext(options) { protected override void OnModelCreating(ModelBuilder modelBuilder) => modelBuilder.Entity( @@ -751,13 +764,13 @@ public virtual async Task OwnsMany_correlated_projection(bool async) var results = await context.Contacts.Select( contact => new Context22089.ContactDto { - Id = contact.Id, - Names = contact.Names.Select(name => new Context22089.NameDto()).ToArray() + Id = contact.Id, Names = contact.Names.Select(name => new Context22089.NameDto()).ToArray() }) .ToListAsync(); } - private class Context22089(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context22089(DbContextOptions options) : DbContext(options) { public DbSet Contacts { get; set; } @@ -816,7 +829,8 @@ public virtual async Task Projecting_owned_collection_and_aggregate(bool async) : query.ToList(); } - private class Context24133(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context24133(DbContextOptions options) : DbContext(options) { protected override void OnModelCreating(ModelBuilder modelBuilder) => modelBuilder.Entity( diff --git a/test/EFCore.Specification.Tests/Query/OwnedQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/OwnedQueryTestBase.cs index bf8d2404c7e..51f16b590f5 100644 --- a/test/EFCore.Specification.Tests/Query/OwnedQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/OwnedQueryTestBase.cs @@ -12,9 +12,7 @@ public abstract class OwnedQueryTestBase : QueryTestBase { protected OwnedQueryTestBase(TFixture fixture) : base(fixture) - { - fixture.ListLoggerFactory.Clear(); - } + => fixture.ListLoggerFactory.Clear(); [ConditionalTheory] // Issue #26257 [MemberData(nameof(IsAsyncData))] @@ -25,8 +23,7 @@ public virtual async Task Can_query_owner_with_different_owned_types_having_same await context.AddAsync( new HeliumBalloon { - Id = Guid.NewGuid().ToString(), - Gas = new Helium(), + Id = Guid.NewGuid().ToString(), Gas = new Helium(), }); await context.AddAsync(new HydrogenBalloon { Id = Guid.NewGuid().ToString(), Gas = new Hydrogen() }); @@ -989,7 +986,9 @@ public virtual Task FirstOrDefault_over_owned_collection(bool async) => AssertQuery( async, ss => ss.Set().Where(p => ((DateTime)p.Orders.FirstOrDefault(o => o.Id > -20)["OrderDate"]).Year == 2018), - ss => ss.Set().Where(p => p.Orders.FirstOrDefault(o => o.Id > -20) != null && ((DateTime)p.Orders.FirstOrDefault(o => o.Id > -20)["OrderDate"]).Year == 2018)); + ss => ss.Set().Where( + p => p.Orders.FirstOrDefault(o => o.Id > -20) != null + && ((DateTime)p.Orders.FirstOrDefault(o => o.Id > -20)["OrderDate"]).Year == 2018)); [ConditionalTheory] [MemberData(nameof(IsAsyncData))] @@ -1742,13 +1741,13 @@ private static IReadOnlyList CreateStars() Name = "Sol", Composition = [ - new() + new Element { Id = "H", Name = "Hydrogen", StarId = 1 }, - new() + new Element { Id = "He", Name = "Helium", @@ -1868,7 +1867,7 @@ private static IReadOnlyList CreateOwnedPeople() Id = -10, Client = ownedPerson1, ["OrderDate"] = Convert.ToDateTime("2018-07-11 10:01:41"), - Details = [new() { Detail = "Discounted Order" }, new() { Detail = "Full Price Order" }] + Details = [new OrderDetail { Detail = "Discounted Order" }, new OrderDetail { Detail = "Full Price Order" }] }; var order2 = new Order @@ -1885,7 +1884,7 @@ private static IReadOnlyList CreateOwnedPeople() Id = -20, Client = ownedPerson2, ["OrderDate"] = Convert.ToDateTime("2015-05-25 20:35:48"), - Details = [new() { Detail = "Internal Order" }] + Details = [new OrderDetail { Detail = "Internal Order" }] }; ownedPerson2.Orders = new List { order3 }; @@ -1894,7 +1893,7 @@ private static IReadOnlyList CreateOwnedPeople() Id = -30, Client = ownedPerson3, ["OrderDate"] = Convert.ToDateTime("2014-11-10 04:32:42"), - Details = [new() { Detail = "Bulk Order" }] + Details = [new OrderDetail { Detail = "Bulk Order" }] }; ownedPerson3.Orders = new List { order4 }; diff --git a/test/EFCore.Specification.Tests/Query/PrimitiveCollectionsQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/PrimitiveCollectionsQueryTestBase.cs index 5b041cbfc25..2304ac3db4c 100644 --- a/test/EFCore.Specification.Tests/Query/PrimitiveCollectionsQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/PrimitiveCollectionsQueryTestBase.cs @@ -130,7 +130,14 @@ public virtual async Task Inline_collection_List_Contains_with_mixed_value_types await AssertQuery( async, - ss => ss.Set().Where(c => new List { 999, i, c.Id, c.Id + c.Int }.Contains(c.Int))); + ss => ss.Set().Where( + c => new List + { + 999, + i, + c.Id, + c.Id + c.Int + }.Contains(c.Int))); } [ConditionalTheory] @@ -159,7 +166,7 @@ public virtual async Task Inline_collection_Min_with_two_values(bool async) public virtual async Task Inline_collection_List_Min_with_two_values(bool async) => await AssertQuery( async, - ss => ss.Set().Where(c => new List() { 30, c.Int }.Min() == 30)); + ss => ss.Set().Where(c => new List { 30, c.Int }.Min() == 30)); [ConditionalTheory] [MemberData(nameof(IsAsyncData))] @@ -173,7 +180,7 @@ public virtual async Task Inline_collection_Max_with_two_values(bool async) public virtual async Task Inline_collection_List_Max_with_two_values(bool async) => await AssertQuery( async, - ss => ss.Set().Where(c => new List() { 30, c.Int }.Max() == 30)); + ss => ss.Set().Where(c => new List { 30, c.Int }.Max() == 30)); [ConditionalTheory] [MemberData(nameof(IsAsyncData))] @@ -194,7 +201,14 @@ public virtual async Task Inline_collection_List_Min_with_three_values(bool asyn await AssertQuery( async, - ss => ss.Set().Where(c => new List() { 30, c.Int, i }.Min() == 25)); + ss => ss.Set().Where( + c => new List + { + 30, + c.Int, + i + }.Min() + == 25)); } [ConditionalTheory] @@ -216,7 +230,14 @@ public virtual async Task Inline_collection_List_Max_with_three_values(bool asyn await AssertQuery( async, - ss => ss.Set().Where(c => new List { 30, c.Int, i }.Max() == 35)); + ss => ss.Set().Where( + c => new List + { + 30, + c.Int, + i + }.Max() + == 35)); } [ConditionalTheory] @@ -287,6 +308,22 @@ public virtual Task Inline_collection_with_single_parameter_element_Count(bool a ss => ss.Set().Where(c => new[] { i }.Count(i => i > c.Id) == 1)); } + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Inline_collection_Contains_with_EF_Parameter(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(c => EF.Parameter(new[] { 2, 999, 1000 }).Contains(c.Id)), + ss => ss.Set().Where(c => new[] { 2, 999, 1000 }.Contains(c.Id))); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Inline_collection_Count_with_column_predicate_with_EF_Parameter(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(c => EF.Parameter(new[] { 2, 999, 1000 }).Count(i => i > c.Id) == 2), + ss => ss.Set().Where(c => new[] { 2, 999, 1000 }.Count(i => i > c.Id) == 2)); + [ConditionalTheory] [MemberData(nameof(IsAsyncData))] public virtual Task Parameter_collection_Count(bool async) @@ -316,7 +353,7 @@ await AssertQuery( [MemberData(nameof(IsAsyncData))] public virtual async Task Parameter_collection_HashSet_of_ints_Contains_int(bool async) { - var ints = new HashSet() { 10, 999 }; + var ints = new HashSet { 10, 999 }; await AssertQuery( async, @@ -660,8 +697,24 @@ public virtual Task Inline_collection_value_index_Column(bool async) public virtual Task Inline_collection_List_value_index_Column(bool async) => AssertQuery( async, - ss => ss.Set().Where(c => new List() { 1, c.Int, 3 }[c.Int] == 1), - ss => ss.Set().Where(c => (c.Int <= 2 ? new List() { 1, c.Int, 3 }[c.Int] : -1) == 1)); + ss => ss.Set().Where( + c => new List + { + 1, + c.Int, + 3 + }[c.Int] + == 1), + ss => ss.Set().Where( + c => (c.Int <= 2 + ? new List + { + 1, + c.Int, + 3 + }[c.Int] + : -1) + == 1)); // The JsonScalarExpression (ints[c.Int]) should get inferred from the column on the other side (c.Int), and that should propagate to // ints @@ -872,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) @@ -1155,8 +1219,7 @@ public virtual Task Project_empty_collection_of_nullables_and_collection_only_co ss => ss.Set().OrderBy(x => x.Id).Select( x => new { - Empty = x.NullableInts.Where(x => false).ToList(), - OnlyNull = x.NullableInts.Where(x => x == null).ToList(), + Empty = x.NullableInts.Where(x => false).ToList(), OnlyNull = x.NullableInts.Where(x => x == null).ToList(), }), assertOrder: true, elementAsserter: (e, a) => @@ -1226,7 +1289,8 @@ public virtual Task Project_inline_collection_with_Union(bool async) x => new { x.Id, - Values = new[] { x.String }.Union(ss.Set().OrderBy(xx => xx.Id).Select(xx => xx.String)).ToList() + Values = new[] { x.String } + .Union(ss.Set().OrderBy(xx => xx.Id).Select(xx => xx.String)).ToList() }) .OrderBy(x => x.Id), elementAsserter: (e, a) => @@ -1246,7 +1310,8 @@ public virtual Task Project_inline_collection_with_Concat(bool async) x => new { x.Id, - Values = new[] { x.String }.Concat(ss.Set().OrderBy(xx => xx.Id).Select(xx => xx.String)).ToList() + Values = new[] { x.String } + .Concat(ss.Set().OrderBy(xx => xx.Id).Select(xx => xx.String)).ToList() }) .OrderBy(x => x.Id), elementAsserter: (e, a) => @@ -1375,9 +1440,7 @@ public class PrimitiveCollectionsData : ISetSource public IReadOnlyList PrimitiveArrayEntities { get; } public PrimitiveCollectionsData(PrimitiveCollectionsContext? context = null) - { - PrimitiveArrayEntities = CreatePrimitiveArrayEntities(); - } + => PrimitiveArrayEntities = CreatePrimitiveArrayEntities(); public IQueryable Set() where TEntity : class @@ -1407,7 +1470,7 @@ private static IReadOnlyList CreatePrimitiveArrayEnt Strings = ["1", "10"], DateTimes = [ - new(2020, 1, 1, 12, 30, 0, DateTimeKind.Utc), new(2020, 1, 10, 12, 30, 0, DateTimeKind.Utc) + new DateTime(2020, 1, 1, 12, 30, 0, DateTimeKind.Utc), new DateTime(2020, 1, 10, 12, 30, 0, DateTimeKind.Utc) ], Bools = [true, false], Enums = [MyEnum.Value1, MyEnum.Value2], @@ -1428,9 +1491,9 @@ private static IReadOnlyList CreatePrimitiveArrayEnt Strings = ["1", "11", "111"], DateTimes = [ - new(2020, 1, 1, 12, 30, 0, DateTimeKind.Utc), - new(2020, 1, 11, 12, 30, 0, DateTimeKind.Utc), - new(2020, 1, 31, 12, 30, 0, DateTimeKind.Utc) + new DateTime(2020, 1, 1, 12, 30, 0, DateTimeKind.Utc), + new DateTime(2020, 1, 11, 12, 30, 0, DateTimeKind.Utc), + new DateTime(2020, 1, 31, 12, 30, 0, DateTimeKind.Utc) ], Bools = [false], Enums = [MyEnum.Value2, MyEnum.Value3], @@ -1451,11 +1514,11 @@ private static IReadOnlyList CreatePrimitiveArrayEnt Strings = ["1", "10", "10", "1", "1"], DateTimes = [ - new(2020, 1, 1, 12, 30, 0, DateTimeKind.Utc), - new(2020, 1, 10, 12, 30, 0, DateTimeKind.Utc), - new(2020, 1, 1, 12, 30, 0, DateTimeKind.Utc), - new(2020, 1, 1, 12, 30, 0, DateTimeKind.Utc), - new(2020, 1, 10, 12, 30, 0, DateTimeKind.Utc) + new DateTime(2020, 1, 1, 12, 30, 0, DateTimeKind.Utc), + new DateTime(2020, 1, 10, 12, 30, 0, DateTimeKind.Utc), + new DateTime(2020, 1, 1, 12, 30, 0, DateTimeKind.Utc), + new DateTime(2020, 1, 1, 12, 30, 0, DateTimeKind.Utc), + new DateTime(2020, 1, 10, 12, 30, 0, DateTimeKind.Utc) ], Bools = [true, false], Enums = [MyEnum.Value1, MyEnum.Value2], @@ -1476,14 +1539,14 @@ private static IReadOnlyList CreatePrimitiveArrayEnt Strings = ["1", "11", "111", "11"], DateTimes = [ - new(2020, 1, 1, 12, 30, 0, DateTimeKind.Utc), - new(2020, 1, 11, 12, 30, 0, DateTimeKind.Utc), - new(2020, 1, 1, 12, 30, 0, DateTimeKind.Utc), - new(2020, 1, 11, 12, 30, 0, DateTimeKind.Utc), - new(2020, 1, 31, 12, 30, 0, DateTimeKind.Utc), - new(2020, 1, 1, 12, 30, 0, DateTimeKind.Utc), - new(2020, 1, 31, 12, 30, 0, DateTimeKind.Utc), - new(2020, 1, 31, 12, 30, 0, DateTimeKind.Utc) + new DateTime(2020, 1, 1, 12, 30, 0, DateTimeKind.Utc), + new DateTime(2020, 1, 11, 12, 30, 0, DateTimeKind.Utc), + new DateTime(2020, 1, 1, 12, 30, 0, DateTimeKind.Utc), + new DateTime(2020, 1, 11, 12, 30, 0, DateTimeKind.Utc), + new DateTime(2020, 1, 31, 12, 30, 0, DateTimeKind.Utc), + new DateTime(2020, 1, 1, 12, 30, 0, DateTimeKind.Utc), + new DateTime(2020, 1, 31, 12, 30, 0, DateTimeKind.Utc), + new DateTime(2020, 1, 31, 12, 30, 0, DateTimeKind.Utc) ], Bools = [false], Enums = [MyEnum.Value2, MyEnum.Value3], @@ -1505,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/Query/QueryTestBase.cs b/test/EFCore.Specification.Tests/Query/QueryTestBase.cs index 6515b7c61bb..3b7f268f4be 100644 --- a/test/EFCore.Specification.Tests/Query/QueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/QueryTestBase.cs @@ -8,14 +8,20 @@ namespace Microsoft.EntityFrameworkCore.Query; public abstract class QueryTestBase : IClassFixture where TFixture : class, IQueryFixtureBase, new() { + private readonly Lazy _queryAsserterCache; + protected QueryTestBase(TFixture fixture) { Fixture = fixture; - QueryAsserter = CreateQueryAsserter(fixture); + + _queryAsserterCache = new Lazy(CreateQueryAsserter); } protected TFixture Fixture { get; } - protected QueryAsserter QueryAsserter { get; } + protected QueryAsserter QueryAsserter => _queryAsserterCache.Value; + + private QueryAsserter CreateQueryAsserter() + => CreateQueryAsserter(Fixture); protected virtual QueryAsserter CreateQueryAsserter(TFixture fixture) => new( @@ -77,7 +83,8 @@ public Task AssertQueryScalar( bool assertEmpty = false, [CallerMemberName] string testMethodName = "") where TResult : struct - => TestOutputWrapper(() => QueryAsserter.AssertQueryScalar(actualQuery, expectedQuery, asserter, assertOrder, assertEmpty, async, testMethodName)); + => TestOutputWrapper( + () => QueryAsserter.AssertQueryScalar(actualQuery, expectedQuery, asserter, assertOrder, assertEmpty, async, testMethodName)); public Task AssertQueryScalar( bool async, @@ -98,7 +105,8 @@ public Task AssertQueryScalar( bool assertEmpty = false, [CallerMemberName] string testMethodName = "") where TResult : struct - => TestOutputWrapper(() => QueryAsserter.AssertQueryScalar(actualQuery, expectedQuery, asserter, assertOrder, assertEmpty, async, testMethodName)); + => TestOutputWrapper( + () => QueryAsserter.AssertQueryScalar(actualQuery, expectedQuery, asserter, assertOrder, assertEmpty, async, testMethodName)); protected Task AssertSingleResult( bool async, @@ -216,7 +224,8 @@ protected Task AssertFirst( Expression> actualPredicate, Expression> expectedPredicate, Action? asserter = null) - => TestOutputWrapper(() => QueryAsserter.AssertFirst(actualQuery, expectedQuery, actualPredicate, expectedPredicate, asserter, async)); + => TestOutputWrapper( + () => QueryAsserter.AssertFirst(actualQuery, expectedQuery, actualPredicate, expectedPredicate, asserter, async)); protected Task AssertFirstOrDefault( bool async, @@ -246,7 +255,8 @@ protected Task AssertFirstOrDefault( Expression> actualPredicate, Expression> expectedPredicate, Action? asserter = null) - => TestOutputWrapper(() => QueryAsserter.AssertFirstOrDefault(actualQuery, expectedQuery, actualPredicate, expectedPredicate, asserter, async)); + => TestOutputWrapper( + () => QueryAsserter.AssertFirstOrDefault(actualQuery, expectedQuery, actualPredicate, expectedPredicate, asserter, async)); protected Task AssertSingle( bool async, @@ -275,7 +285,8 @@ protected Task AssertSingle( Expression> actualPredicate, Expression> expectedPredicate, Action? asserter = null) - => TestOutputWrapper(() => QueryAsserter.AssertSingle(actualQuery, expectedQuery, actualPredicate, expectedPredicate, asserter, async)); + => TestOutputWrapper( + () => QueryAsserter.AssertSingle(actualQuery, expectedQuery, actualPredicate, expectedPredicate, asserter, async)); protected Task AssertSingleOrDefault( bool async, @@ -304,7 +315,8 @@ protected Task AssertSingleOrDefault( Expression> actualPredicate, Expression> expectedPredicate, Action? asserter = null) - => TestOutputWrapper(() => QueryAsserter.AssertSingleOrDefault(actualQuery, expectedQuery, actualPredicate, expectedPredicate, asserter, async)); + => TestOutputWrapper( + () => QueryAsserter.AssertSingleOrDefault(actualQuery, expectedQuery, actualPredicate, expectedPredicate, asserter, async)); protected Task AssertLast( bool async, @@ -333,7 +345,8 @@ protected Task AssertLast( Expression> actualPredicate, Expression> expectedPredicate, Action? asserter = null) - => TestOutputWrapper(() => QueryAsserter.AssertLast(actualQuery, expectedQuery, actualPredicate, expectedPredicate, asserter, async)); + => TestOutputWrapper( + () => QueryAsserter.AssertLast(actualQuery, expectedQuery, actualPredicate, expectedPredicate, asserter, async)); protected Task AssertLastOrDefault( bool async, @@ -362,7 +375,8 @@ protected Task AssertLastOrDefault( Expression> actualPredicate, Expression> expectedPredicate, Action? asserter = null) - => TestOutputWrapper(() => QueryAsserter.AssertLastOrDefault(actualQuery, expectedQuery, actualPredicate, expectedPredicate, asserter, async)); + => TestOutputWrapper( + () => QueryAsserter.AssertLastOrDefault(actualQuery, expectedQuery, actualPredicate, expectedPredicate, asserter, async)); protected Task AssertCount( bool async, @@ -906,7 +920,8 @@ protected Task AssertAverage( Expression> actualSelector, Expression> expectedSelector, Action? asserter = null) - => TestOutputWrapper(() => QueryAsserter.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async)); + => TestOutputWrapper( + () => QueryAsserter.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async)); protected Task AssertAverage( bool async, @@ -922,7 +937,8 @@ protected Task AssertAverage( Expression> actualSelector, Expression> expectedSelector, Action? asserter = null) - => TestOutputWrapper(() => QueryAsserter.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async)); + => TestOutputWrapper( + () => QueryAsserter.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async)); protected Task AssertAverage( bool async, @@ -938,7 +954,8 @@ protected Task AssertAverage( Expression> actualSelector, Expression> expectedSelector, Action? asserter = null) - => TestOutputWrapper(() => QueryAsserter.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async)); + => TestOutputWrapper( + () => QueryAsserter.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async)); protected Task AssertAverage( bool async, @@ -954,7 +971,8 @@ protected Task AssertAverage( Expression> actualSelector, Expression> expectedSelector, Action? asserter = null) - => TestOutputWrapper(() => QueryAsserter.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async)); + => TestOutputWrapper( + () => QueryAsserter.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async)); protected Task AssertAverage( bool async, @@ -970,7 +988,8 @@ protected Task AssertAverage( Expression> actualSelector, Expression> expectedSelector, Action? asserter = null) - => TestOutputWrapper(() => QueryAsserter.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async)); + => TestOutputWrapper( + () => QueryAsserter.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async)); protected Task AssertAverage( bool async, @@ -986,7 +1005,8 @@ protected Task AssertAverage( Expression> actualSelector, Expression> expectedSelector, Action? asserter = null) - => TestOutputWrapper(() => QueryAsserter.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async)); + => TestOutputWrapper( + () => QueryAsserter.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async)); protected Task AssertAverage( bool async, @@ -1002,7 +1022,8 @@ protected Task AssertAverage( Expression> actualSelector, Expression> expectedSelector, Action? asserter = null) - => TestOutputWrapper(() => QueryAsserter.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async)); + => TestOutputWrapper( + () => QueryAsserter.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async)); protected Task AssertAverage( bool async, @@ -1018,7 +1039,8 @@ protected Task AssertAverage( Expression> actualSelector, Expression> expectedSelector, Action? asserter = null) - => TestOutputWrapper(() => QueryAsserter.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async)); + => TestOutputWrapper( + () => QueryAsserter.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async)); protected Task AssertAverage( bool async, @@ -1034,7 +1056,8 @@ protected Task AssertAverage( Expression> actualSelector, Expression> expectedSelector, Action? asserter = null) - => TestOutputWrapper(() => QueryAsserter.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async)); + => TestOutputWrapper( + () => QueryAsserter.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async)); protected Task AssertAverage( bool async, @@ -1050,7 +1073,8 @@ protected Task AssertAverage( Expression> actualSelector, Expression> expectedSelector, Action? asserter = null) - => TestOutputWrapper(() => QueryAsserter.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async)); + => TestOutputWrapper( + () => QueryAsserter.AssertAverage(actualQuery, expectedQuery, actualSelector, expectedSelector, asserter, async)); #endregion diff --git a/test/EFCore.Specification.Tests/Query/SpatialQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/SpatialQueryTestBase.cs index bfbc4e04319..b97821604b2 100644 --- a/test/EFCore.Specification.Tests/Query/SpatialQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/SpatialQueryTestBase.cs @@ -282,7 +282,8 @@ public virtual Task LineString_Count(bool async) [MemberData(nameof(IsAsyncData))] public virtual Task CoveredBy(bool async) { - var polygon = Fixture.GeometryFactory.CreatePolygon([new(-1, -1), new(2, -1), new(2, 2), new(-1, 2), new(-1, -1)]); + var polygon = Fixture.GeometryFactory.CreatePolygon( + [new Coordinate(-1, -1), new Coordinate(2, -1), new Coordinate(2, 2), new Coordinate(-1, 2), new Coordinate(-1, -1)]); return AssertQuery( async, @@ -309,7 +310,7 @@ public virtual Task Covers(bool async) [MemberData(nameof(IsAsyncData))] public virtual Task Crosses(bool async) { - var lineString = Fixture.GeometryFactory.CreateLineString([new(0.5, -0.5), new(0.5, 0.5)]); + var lineString = Fixture.GeometryFactory.CreateLineString([new Coordinate(0.5, -0.5), new Coordinate(0.5, 0.5)]); return AssertQuery( async, @@ -323,7 +324,8 @@ public virtual Task Crosses(bool async) [MemberData(nameof(IsAsyncData))] public virtual Task Difference(bool async) { - var polygon = Fixture.GeometryFactory.CreatePolygon([new(0, 0), new(1, 0), new(1, 1), new(0, 0)]); + var polygon = Fixture.GeometryFactory.CreatePolygon( + [new Coordinate(0, 0), new Coordinate(1, 0), new Coordinate(1, 1), new Coordinate(0, 0)]); return AssertQuery( async, @@ -725,7 +727,8 @@ public virtual Task InteriorPoint(bool async) [MemberData(nameof(IsAsyncData))] public virtual Task Intersection(bool async) { - var polygon = Fixture.GeometryFactory.CreatePolygon([new(0, 0), new(1, 0), new(1, 1), new(0, 0)]); + var polygon = Fixture.GeometryFactory.CreatePolygon( + [new Coordinate(0, 0), new Coordinate(1, 0), new Coordinate(1, 1), new Coordinate(0, 0)]); return AssertQuery( async, @@ -744,7 +747,7 @@ public virtual Task Intersection(bool async) [MemberData(nameof(IsAsyncData))] public virtual Task Intersects(bool async) { - var lineString = Fixture.GeometryFactory.CreateLineString([new(0.5, -0.5), new(0.5, 0.5)]); + var lineString = Fixture.GeometryFactory.CreateLineString([new Coordinate(0.5, -0.5), new Coordinate(0.5, 0.5)]); return AssertQuery( async, @@ -943,7 +946,8 @@ public virtual Task OgcGeometryType(bool async) [MemberData(nameof(IsAsyncData))] public virtual Task Overlaps(bool async) { - var polygon = Fixture.GeometryFactory.CreatePolygon([new(0, 0), new(1, 0), new(1, 1), new(0, 0)]); + var polygon = Fixture.GeometryFactory.CreatePolygon( + [new Coordinate(0, 0), new Coordinate(1, 0), new Coordinate(1, 1), new Coordinate(0, 0)]); return AssertQuery( async, @@ -984,7 +988,8 @@ public virtual Task PointOnSurface(bool async) [MemberData(nameof(IsAsyncData))] public virtual Task Relate(bool async) { - var polygon = Fixture.GeometryFactory.CreatePolygon([new(0, 0), new(1, 0), new(1, 1), new(0, 0)]); + var polygon = Fixture.GeometryFactory.CreatePolygon( + [new Coordinate(0, 0), new Coordinate(1, 0), new Coordinate(1, 1), new Coordinate(0, 0)]); return AssertQuery( async, @@ -1034,7 +1039,8 @@ public virtual Task StartPoint(bool async) [MemberData(nameof(IsAsyncData))] public virtual Task SymmetricDifference(bool async) { - var polygon = Fixture.GeometryFactory.CreatePolygon([new(0, 0), new(1, 0), new(1, 1), new(0, 0)]); + var polygon = Fixture.GeometryFactory.CreatePolygon( + [new Coordinate(0, 0), new Coordinate(1, 0), new Coordinate(1, 1), new Coordinate(0, 0)]); return AssertQuery( async, @@ -1081,7 +1087,8 @@ public virtual Task ToText(bool async) [MemberData(nameof(IsAsyncData))] public virtual Task Touches(bool async) { - var polygon = Fixture.GeometryFactory.CreatePolygon([new(0, 1), new(1, 0), new(1, 1), new(0, 1)]); + var polygon = Fixture.GeometryFactory.CreatePolygon( + [new Coordinate(0, 1), new Coordinate(1, 0), new Coordinate(1, 1), new Coordinate(0, 1)]); return AssertQuery( async, @@ -1095,7 +1102,8 @@ public virtual Task Touches(bool async) [MemberData(nameof(IsAsyncData))] public virtual Task Union(bool async) { - var polygon = Fixture.GeometryFactory.CreatePolygon([new(0, 0), new(1, 0), new(1, 1), new(0, 0)]); + var polygon = Fixture.GeometryFactory.CreatePolygon( + [new Coordinate(0, 0), new Coordinate(1, 0), new Coordinate(1, 1), new Coordinate(0, 0)]); return AssertQuery( async, @@ -1139,7 +1147,8 @@ public virtual Task Union_void(bool async) [MemberData(nameof(IsAsyncData))] public virtual Task Within(bool async) { - var polygon = Fixture.GeometryFactory.CreatePolygon([new(-1, -1), new(2, -1), new(2, 2), new(-1, 2), new(-1, -1)]); + var polygon = Fixture.GeometryFactory.CreatePolygon( + [new Coordinate(-1, -1), new Coordinate(2, -1), new Coordinate(2, 2), new Coordinate(-1, 2), new Coordinate(-1, -1)]); return AssertQuery( async, @@ -1234,7 +1243,7 @@ public virtual Task IsEmpty_not_equal_to_null(bool async) [MemberData(nameof(IsAsyncData))] public virtual async Task Intersects_equal_to_null(bool async) { - var lineString = Fixture.GeometryFactory.CreateLineString([new(0.5, -0.5), new(0.5, 0.5)]); + var lineString = Fixture.GeometryFactory.CreateLineString([new Coordinate(0.5, -0.5), new Coordinate(0.5, 0.5)]); await AssertQueryScalar( async, @@ -1255,7 +1264,7 @@ await AssertQueryScalar( [MemberData(nameof(IsAsyncData))] public virtual async Task Intersects_not_equal_to_null(bool async) { - var lineString = Fixture.GeometryFactory.CreateLineString([new(0.5, -0.5), new(0.5, 0.5)]); + var lineString = Fixture.GeometryFactory.CreateLineString([new Coordinate(0.5, -0.5), new Coordinate(0.5, 0.5)]); await AssertQueryScalar( async, diff --git a/test/EFCore.Specification.Tests/Scaffolding/CompiledModelTestBase.cs b/test/EFCore.Specification.Tests/Scaffolding/CompiledModelTestBase.cs index 34abe7ad7d3..29a7f138fb7 100644 --- a/test/EFCore.Specification.Tests/Scaffolding/CompiledModelTestBase.cs +++ b/test/EFCore.Specification.Tests/Scaffolding/CompiledModelTestBase.cs @@ -43,10 +43,11 @@ public virtual Task SimpleModel() Assert.Equal(1, stored.GetId()); Assert.Equal("one", stored.GetData()); }, - options: new CompiledModelCodeGenerationOptions { UseNullableReferenceTypes = true }, + options: new CompiledModelCodeGenerationOptions { UseNullableReferenceTypes = true, ForNativeAot = true }, additionalSourceFiles: [ - new("DbContextModelStub.cs", + new ScaffoldedFile( + "DbContextModelStub.cs", """ using Microsoft.EntityFrameworkCore.Metadata; using static TestNamespace.DbContextModel.Dummy; @@ -75,32 +76,21 @@ public static class Dummy Assert.NotNull(model); }); + [ConditionalFact] + public virtual Task No_NativeAOT() + => BigModel(false); + [ConditionalFact] public virtual Task BigModel() + => BigModel(true); + + protected virtual Task BigModel(bool forNativeAot, [CallerMemberName] string testName = "") => Test( modelBuilder => BuildBigModel(modelBuilder, jsonColumns: false), model => AssertBigModel(model, jsonColumns: false), - async c => - { - var principalDerived = new PrincipalDerived> - { - AlternateId = new Guid(), - Dependent = new DependentBase(1), - Owned = new OwnedType(c) - }; - - var principalBase = c.Model.FindEntityType(typeof(PrincipalBase))!; - var principalId = principalBase.FindProperty(nameof(PrincipalBase.Id))!; - if (principalId.ValueGenerated == ValueGenerated.Never) - { - principalDerived.Id = 10; - } - - c.Add(principalDerived); - - await c.SaveChangesAsync(); - }, - options: new CompiledModelCodeGenerationOptions { UseNullableReferenceTypes = true }); + UseBigModel, + options: new CompiledModelCodeGenerationOptions { UseNullableReferenceTypes = true, ForNativeAot = forNativeAot }, + testName: testName); protected virtual void BuildBigModel(ModelBuilder modelBuilder, bool jsonColumns) { @@ -324,7 +314,8 @@ protected virtual void AssertBigModel(IModel model, bool jsonColumns) var principalAlternateKey = principalBase.GetKeys().Single(k => k.Properties.Count == 1 && principalId == k.Properties.Single()); Assert.False(principalAlternateKey.IsPrimaryKey()); - var principalKey = principalBase.GetKeys().Single(k => k.Properties.Count == 2 && k.Properties.SequenceEqual([principalId, principalAlternateId])); + var principalKey = principalBase.GetKeys() + .Single(k => k.Properties.Count == 2 && k.Properties.SequenceEqual([principalId, principalAlternateId])); Assert.True(principalKey.IsPrimaryKey()); Assert.Equal([principalAlternateKey, principalKey], principalId.GetContainingKeys()); @@ -502,7 +493,7 @@ protected virtual void AssertBigModel(IModel model, bool jsonColumns) Assert.Same(dependentNavigation.Inverse, dependentForeignKey.DependentToPrincipal); Assert.Same(dependentNavigation, dependentForeignKey.PrincipalToDependent); Assert.Equal(DeleteBehavior.ClientNoAction, dependentForeignKey.DeleteBehavior); - Assert.Equal(new[] { "PrincipalId", "PrincipalAlternateId" }, dependentForeignKey.Properties.Select(p => p.Name)); + Assert.Equal(["PrincipalId", "PrincipalAlternateId"], dependentForeignKey.Properties.Select(p => p.Name)); Assert.Same(principalKey, dependentForeignKey.PrincipalKey); var dependentBase = dependentNavigation.TargetEntityType; @@ -517,7 +508,7 @@ protected virtual void AssertBigModel(IModel model, bool jsonColumns) var dependentForeignKeyProperty = dependentBaseForeignKey.Properties.Single(); Assert.Equal( - new[] { dependentBaseForeignKey, dependentForeignKey }, dependentForeignKeyProperty.GetContainingForeignKeys()); + [dependentBaseForeignKey, dependentForeignKey], dependentForeignKeyProperty.GetContainingForeignKeys()); var dependentDerived = dependentBase.GetDerivedTypes().Single(); Assert.Equal(Enum1.Two, dependentDerived.GetDiscriminatorValue()); @@ -553,32 +544,50 @@ protected virtual void AssertBigModel(IModel model, bool jsonColumns) Assert.Equal(3, dependentMoney.GetScale()); Assert.Equal( - new[] { derivedSkipNavigation.ForeignKey, collectionOwnership, dependentForeignKey }, + [derivedSkipNavigation.ForeignKey, collectionOwnership, dependentForeignKey], principalDerived.GetDeclaredReferencingForeignKeys()); } + protected virtual async Task UseBigModel(DbContext context) + { + var principalDerived = new PrincipalDerived> + { + AlternateId = new Guid(), + Dependent = new DependentBase(1), + Owned = new OwnedType(context) + }; + + var principalBase = context.Model.FindEntityType(typeof(PrincipalBase))!; + var principalId = principalBase.FindProperty(nameof(PrincipalBase.Id))!; + if (principalId.ValueGenerated == ValueGenerated.Never) + { + principalDerived.Id = 10; + } + + context.Add(principalDerived); + + await context.SaveChangesAsync(); + } + [ConditionalFact] public virtual Task ComplexTypes() => Test( BuildComplexTypesModel, AssertComplexTypes, - c => + async c => { - // Blocked by https://github.com/dotnet/runtime/issues/102792 - //c.Set>>().Add( - // new PrincipalDerived> - // { - // Id = 1, - // AlternateId = new Guid(), - // Dependent = new DependentBase(1), - // Owned = new OwnedType(c) { Principal = new PrincipalBase() } - // }); - - //c.SaveChanges(); - - return Task.CompletedTask; + c.Set>>().Add( + new PrincipalDerived> + { + Id = 1, + AlternateId = new Guid(), + Dependent = new DependentBase(1), + Owned = new OwnedType(c) { Principal = new PrincipalBase() } + }); + + await c.SaveChangesAsync(); }, - options: new CompiledModelCodeGenerationOptions { UseNullableReferenceTypes = true }); + options: new CompiledModelCodeGenerationOptions { UseNullableReferenceTypes = true, ForNativeAot = true }); protected virtual void BuildComplexTypesModel(ModelBuilder modelBuilder) { @@ -608,11 +617,12 @@ protected virtual void BuildComplexTypesModel(ModelBuilder modelBuilder) .HasPrecision(3, 2) .HasAnnotation("foo", "bar"); eb.Ignore(e => e.Context); - eb.ComplexProperty(o => o.Principal, cb => - { - cb.IsRequired(); - cb.Property("FlagsEnum2"); - }); + eb.ComplexProperty( + o => o.Principal, cb => + { + cb.IsRequired(); + cb.Property("FlagsEnum2"); + }); }); }); @@ -631,7 +641,7 @@ protected virtual void AssertComplexTypes(IModel model) var complexProperty = principalBase.GetComplexProperties().Single(); Assert.Equal( - new[] { "goo" }, + ["goo"], complexProperty.GetAnnotations().Select(a => a.Name)); Assert.Equal(nameof(PrincipalBase.Owned), complexProperty.Name); Assert.False(complexProperty.IsCollection); @@ -795,10 +805,11 @@ public override Guid FromJsonTyped(ref Utf8JsonReaderManager manager, object? ex public override void ToJsonTyped(Utf8JsonWriter writer, Guid value) => writer.WriteStringValue(value); - private readonly Expression> _ctorLambda = () => new(); + private readonly Expression> _ctorLambda = () => new MyJsonGuidReaderWriter(); /// - public override Expression ConstructorExpression => _ctorLambda.Body; + public override Expression ConstructorExpression + => _ctorLambda.Body; } public class ManyTypes @@ -1150,9 +1161,7 @@ public OwnedType() } public OwnedType(DbContext context) - { - Context = context; - } + => Context = context; public DbContext? Context { @@ -1350,7 +1359,7 @@ protected virtual Task Test( using var context = contextFactory.CreateContext(); var model = context.GetService().Model; - options ??= new CompiledModelCodeGenerationOptions(); + options ??= new CompiledModelCodeGenerationOptions { ForNativeAot = true }; options.ModelNamespace ??= "TestNamespace"; options.ContextType ??= context.GetType(); @@ -1396,7 +1405,8 @@ protected virtual Task Test( if (useContext != null) { ListLoggerFactory.Clear(); - await TestStore.InitializeAsync(ServiceProvider, contextFactory.CreateContext); + var testStore = await TestStore.InitializeAsync(ServiceProvider, contextFactory.CreateContext); + await using var _ = testStore; using var compiledModelContext = (await CreateContextFactory( onConfiguring: options => @@ -1422,8 +1432,7 @@ private IModel CompileModel( { var build = new BuildSource { - Sources = scaffoldedFiles.ToDictionary(f => f.Path, f => f.Code), - NullableReferenceTypes = options.UseNullableReferenceTypes + Sources = scaffoldedFiles.ToDictionary(f => f.Path, f => f.Code), NullableReferenceTypes = options.UseNullableReferenceTypes }; AddReferences(build); diff --git a/test/EFCore.Specification.Tests/ServiceProviderFixtureBase.cs b/test/EFCore.Specification.Tests/ServiceProviderFixtureBase.cs index 1dc3a839f92..fad50c8c89c 100644 --- a/test/EFCore.Specification.Tests/ServiceProviderFixtureBase.cs +++ b/test/EFCore.Specification.Tests/ServiceProviderFixtureBase.cs @@ -16,10 +16,8 @@ public ListLoggerFactory ListLoggerFactory => _listLoggerFactory ??= (ListLoggerFactory)ServiceProvider.GetRequiredService(); protected ServiceProviderFixtureBase() - { - ServiceProvider = AddServices(TestStoreFactory.AddProviderServices(new ServiceCollection())) + => ServiceProvider = AddServices(TestStoreFactory.AddProviderServices(new ServiceCollection())) .BuildServiceProvider(validateScopes: true); - } public DbContextOptions CreateOptions(TestStore testStore) => AddOptions(testStore.AddProviderOptions(new DbContextOptionsBuilder())) diff --git a/test/EFCore.Specification.Tests/SharedStoreFixtureBase.cs b/test/EFCore.Specification.Tests/SharedStoreFixtureBase.cs index 1ffad9e7362..6fed8e56418 100644 --- a/test/EFCore.Specification.Tests/SharedStoreFixtureBase.cs +++ b/test/EFCore.Specification.Tests/SharedStoreFixtureBase.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable VirtualMemberCallInConstructor + namespace Microsoft.EntityFrameworkCore; public abstract class SharedStoreFixtureBase : FixtureBase, IAsyncLifetime @@ -110,6 +111,6 @@ protected virtual Task CleanAsync(DbContext context) return Task.CompletedTask; } - public virtual Task DisposeAsync() - => TestStore.DisposeAsync(); + public virtual async Task DisposeAsync() + => await TestStore.DisposeAsync(); } diff --git a/test/EFCore.Specification.Tests/SpatialTestBase.cs b/test/EFCore.Specification.Tests/SpatialTestBase.cs index 7adbd529002..0198a8f39b4 100644 --- a/test/EFCore.Specification.Tests/SpatialTestBase.cs +++ b/test/EFCore.Specification.Tests/SpatialTestBase.cs @@ -38,14 +38,14 @@ public virtual void Values_arent_compared_by_reference() } [ConditionalFact] - public virtual async void Mutation_of_tracked_values_does_not_mutate_values_in_store() + public virtual async Task Mutation_of_tracked_values_does_not_mutate_values_in_store() { Point CreatePoint(double y = 2.2) => new(1.1, y, 3.3); Polygon CreatePolygon(double y = 2.2) => new( - new LinearRing([new(1.1, 2.2), new(2.2, y), new(2.2, 1.1), new(1.1, 2.2)])); + new LinearRing([new Coordinate(1.1, 2.2), new Coordinate(2.2, y), new Coordinate(2.2, 1.1), new Coordinate(1.1, 2.2)])); var id1 = Guid.NewGuid(); var id2 = Guid.NewGuid(); diff --git a/test/EFCore.Specification.Tests/TestModels/AspNetIdentity/IdentityDbContext``.cs b/test/EFCore.Specification.Tests/TestModels/AspNetIdentity/IdentityDbContext``.cs index c28553085b1..ef3b9628646 100644 --- a/test/EFCore.Specification.Tests/TestModels/AspNetIdentity/IdentityDbContext``.cs +++ b/test/EFCore.Specification.Tests/TestModels/AspNetIdentity/IdentityDbContext``.cs @@ -7,7 +7,7 @@ namespace Microsoft.EntityFrameworkCore.TestModels.AspNetIdentity; public abstract class IdentityDbContext : IdentityUserContext + TUserClaim, TUserLogin, TUserToken> where TUser : IdentityUser where TRole : IdentityRole where TKey : IEquatable diff --git a/test/EFCore.Specification.Tests/TestModels/AspNetIdentity/IdentityRole.cs b/test/EFCore.Specification.Tests/TestModels/AspNetIdentity/IdentityRole.cs index c43a32153e8..9756760e111 100644 --- a/test/EFCore.Specification.Tests/TestModels/AspNetIdentity/IdentityRole.cs +++ b/test/EFCore.Specification.Tests/TestModels/AspNetIdentity/IdentityRole.cs @@ -14,9 +14,7 @@ public IdentityRole() public IdentityRole(string roleName) : this() - { - Name = roleName; - } + => Name = roleName; public virtual TKey Id { get; set; } @@ -33,13 +31,9 @@ public override string ToString() public class IdentityRole : IdentityRole { public IdentityRole() - { - Id = Guid.NewGuid().ToString(); - } + => Id = Guid.NewGuid().ToString(); public IdentityRole(string roleName) : this() - { - Name = roleName; - } + => Name = roleName; } diff --git a/test/EFCore.Specification.Tests/TestModels/AspNetIdentity/IdentityUser.cs b/test/EFCore.Specification.Tests/TestModels/AspNetIdentity/IdentityUser.cs index f8b9367c08c..ab72e5e3945 100644 --- a/test/EFCore.Specification.Tests/TestModels/AspNetIdentity/IdentityUser.cs +++ b/test/EFCore.Specification.Tests/TestModels/AspNetIdentity/IdentityUser.cs @@ -13,7 +13,5 @@ public IdentityUser() public IdentityUser(string userName) : this() - { - UserName = userName; - } + => UserName = userName; } diff --git a/test/EFCore.Specification.Tests/TestModels/AspNetIdentity/IdentityUserContext.cs b/test/EFCore.Specification.Tests/TestModels/AspNetIdentity/IdentityUserContext.cs index 678a7baae84..652146b6cbd 100644 --- a/test/EFCore.Specification.Tests/TestModels/AspNetIdentity/IdentityUserContext.cs +++ b/test/EFCore.Specification.Tests/TestModels/AspNetIdentity/IdentityUserContext.cs @@ -27,8 +27,8 @@ protected IdentityUserContext() public virtual DbSet UserTokens { get; set; } private class PersonalDataConverter(IPersonalDataProtector protector) : ValueConverter( - s => protector.Protect(s), - s => protector.Unprotect(s)); + s => protector.Protect(s), + s => protector.Unprotect(s)); private class PersonalDataProtector : IPersonalDataProtector { diff --git a/test/EFCore.Specification.Tests/TestModels/AspNetIdentity/IdentityUser`.cs b/test/EFCore.Specification.Tests/TestModels/AspNetIdentity/IdentityUser`.cs index 359a8096737..7cd4adbcbc1 100644 --- a/test/EFCore.Specification.Tests/TestModels/AspNetIdentity/IdentityUser`.cs +++ b/test/EFCore.Specification.Tests/TestModels/AspNetIdentity/IdentityUser`.cs @@ -14,9 +14,7 @@ public IdentityUser() public IdentityUser(string userName) : this() - { - UserName = userName; - } + => UserName = userName; [PersonalData] public virtual TKey Id { get; set; } diff --git a/test/EFCore.Specification.Tests/TestModels/ChangedChangingMonsterContext.cs b/test/EFCore.Specification.Tests/TestModels/ChangedChangingMonsterContext.cs index c905c6ee252..2d40a347054 100644 --- a/test/EFCore.Specification.Tests/TestModels/ChangedChangingMonsterContext.cs +++ b/test/EFCore.Specification.Tests/TestModels/ChangedChangingMonsterContext.cs @@ -60,9 +60,7 @@ public class BackOrderLine : OrderLine, IBackOrderLine private DateTime _eta; public BackOrderLine() - { - ETA = DateTime.Now; - } + => ETA = DateTime.Now; public DateTime ETA { @@ -215,9 +213,7 @@ public class ComputerDetail : NotificationEntity, IComputerDetail private IComputer _computer; public ComputerDetail() - { - Dimensions = new Dimensions(); - } + => Dimensions = new Dimensions(); public int ComputerDetailId { @@ -560,9 +556,7 @@ public class License : NotificationEntity, ILicense private IDriver _driver; public License() - { - LicenseClass = "C"; - } + => LicenseClass = "C"; public string Name { @@ -684,9 +678,7 @@ public class OrderLine : NotificationEntity, IOrderLine private IProduct _product; public OrderLine() - { - Quantity = 1; - } + => Quantity = 1; public int OrderId { @@ -738,9 +730,7 @@ public class AnOrder : NotificationEntity, IAnOrder private ILogin _login; public AnOrder() - { - Concurrency = new ConcurrencyInfo(); - } + => Concurrency = new ConcurrencyInfo(); public void InitializeCollections() { @@ -1628,9 +1618,7 @@ public class Phone : NotificationEntity, IPhone private string _phoneNumber; public Phone() - { - Extension = "None"; - } + => Extension = "None"; public string PhoneNumber { diff --git a/test/EFCore.Specification.Tests/TestModels/ChangedOnlyMonsterContext.cs b/test/EFCore.Specification.Tests/TestModels/ChangedOnlyMonsterContext.cs index 87862a680ce..4f120f292a6 100644 --- a/test/EFCore.Specification.Tests/TestModels/ChangedOnlyMonsterContext.cs +++ b/test/EFCore.Specification.Tests/TestModels/ChangedOnlyMonsterContext.cs @@ -55,9 +55,7 @@ public class BackOrderLine : OrderLine, IBackOrderLine private DateTime _eta; public BackOrderLine() - { - ETA = DateTime.Now; - } + => ETA = DateTime.Now; public DateTime ETA { @@ -210,9 +208,7 @@ public class ComputerDetail : NotificationEntity, IComputerDetail private IComputer _computer; public ComputerDetail() - { - Dimensions = new Dimensions(); - } + => Dimensions = new Dimensions(); public int ComputerDetailId { @@ -555,9 +551,7 @@ public class License : NotificationEntity, ILicense private IDriver _driver; public License() - { - LicenseClass = "C"; - } + => LicenseClass = "C"; public string Name { @@ -679,9 +673,7 @@ public class OrderLine : NotificationEntity, IOrderLine private IProduct _product; public OrderLine() - { - Quantity = 1; - } + => Quantity = 1; public int OrderId { @@ -733,9 +725,7 @@ public class AnOrder : NotificationEntity, IAnOrder private ILogin _login; public AnOrder() - { - Concurrency = new ConcurrencyInfo(); - } + => Concurrency = new ConcurrencyInfo(); public void InitializeCollections() { @@ -1623,9 +1613,7 @@ public class Phone : NotificationEntity, IPhone private string _phoneNumber; public Phone() - { - Extension = "None"; - } + => Extension = "None"; public string PhoneNumber { diff --git a/test/EFCore.Specification.Tests/TestModels/ConcurrencyModel/F1Context.cs b/test/EFCore.Specification.Tests/TestModels/ConcurrencyModel/F1Context.cs index c962b5998c0..a76a389719b 100644 --- a/test/EFCore.Specification.Tests/TestModels/ConcurrencyModel/F1Context.cs +++ b/test/EFCore.Specification.Tests/TestModels/ConcurrencyModel/F1Context.cs @@ -15,17 +15,9 @@ public class F1Context(DbContextOptions options) : PoolableDbContext(options) public DbSet Fans { get; set; } public DbSet FanTpts { get; set; } public DbSet FanTpcs { get; set; } - public DbSet Circuits { get; set; } - public static Task SeedAsync(F1Context context) - { - AddEntities(context); - - return context.SaveChangesAsync(); - } - - private static void AddEntities(F1Context context) + public static void AddSeedData(F1Context context) { foreach (var engineSupplier in new List { diff --git a/test/EFCore.Specification.Tests/TestModels/ConcurrencyModel/Team.cs b/test/EFCore.Specification.Tests/TestModels/ConcurrencyModel/Team.cs index ba8b9009cf5..46da17ff84c 100644 --- a/test/EFCore.Specification.Tests/TestModels/ConcurrencyModel/Team.cs +++ b/test/EFCore.Specification.Tests/TestModels/ConcurrencyModel/Team.cs @@ -24,7 +24,8 @@ public class TeamProxy( int fastestLaps, int? gearboxId) : Team( loader, id, name, constructor, tire, principal, constructorsChampionships, driversChampionships, races, victories, poles, - fastestLaps, gearboxId), IF1Proxy + fastestLaps, gearboxId), + IF1Proxy { public bool CreatedCalled { get; set; } public bool InitializingCalled { get; set; } diff --git a/test/EFCore.Specification.Tests/TestModels/ConcurrencyModel/TestDriver.cs b/test/EFCore.Specification.Tests/TestModels/ConcurrencyModel/TestDriver.cs index 370e27453b6..d64f3c28ed3 100644 --- a/test/EFCore.Specification.Tests/TestModels/ConcurrencyModel/TestDriver.cs +++ b/test/EFCore.Specification.Tests/TestModels/ConcurrencyModel/TestDriver.cs @@ -40,7 +40,5 @@ private TestDriver( int fastestLaps, int teamId) : base(loader, id, name, carNumber, championships, races, wins, podiums, poles, fastestLaps, teamId) - { - Assert.IsType(this); - } + => Assert.IsType(this); } diff --git a/test/EFCore.Specification.Tests/TestModels/FunkyDataModel/FunkyDataData.cs b/test/EFCore.Specification.Tests/TestModels/FunkyDataModel/FunkyDataData.cs index 93a79228b89..302c6122f3f 100644 --- a/test/EFCore.Specification.Tests/TestModels/FunkyDataModel/FunkyDataData.cs +++ b/test/EFCore.Specification.Tests/TestModels/FunkyDataModel/FunkyDataData.cs @@ -12,9 +12,7 @@ public class FunkyDataData : ISetSource public IReadOnlyList FunkyCustomers { get; } private FunkyDataData() - { - FunkyCustomers = CreateFunkyCustomers(); - } + => FunkyCustomers = CreateFunkyCustomers(); public virtual IQueryable Set() where TEntity : class diff --git a/test/EFCore.Specification.Tests/TestModels/GearsOfWarModel/Gear.cs b/test/EFCore.Specification.Tests/TestModels/GearsOfWarModel/Gear.cs index c7c780c6d14..16be3003b19 100644 --- a/test/EFCore.Specification.Tests/TestModels/GearsOfWarModel/Gear.cs +++ b/test/EFCore.Specification.Tests/TestModels/GearsOfWarModel/Gear.cs @@ -10,9 +10,7 @@ namespace Microsoft.EntityFrameworkCore.TestModels.GearsOfWarModel; public class Gear { public Gear() - { - Weapons = new List(); - } + => Weapons = new List(); // composite key public string Nickname { get; set; } diff --git a/test/EFCore.Specification.Tests/TestModels/GearsOfWarModel/GearsOfWarData.cs b/test/EFCore.Specification.Tests/TestModels/GearsOfWarModel/GearsOfWarData.cs index 4e6b377e38a..4abffab963a 100644 --- a/test/EFCore.Specification.Tests/TestModels/GearsOfWarModel/GearsOfWarData.cs +++ b/test/EFCore.Specification.Tests/TestModels/GearsOfWarModel/GearsOfWarData.cs @@ -608,7 +608,8 @@ public static void WireUp( ((LocustHorde)factions[1]).Commander = ((LocustCommander)locustLeaders[5]); ((LocustHorde)factions[2]).Commander = ((LocustCommander)locustLeaders[6]); - locustHighCommands[0].Commanders = [ + locustHighCommands[0].Commanders = + [ (LocustCommander)locustLeaders[3], (LocustCommander)locustLeaders[5], (LocustCommander)locustLeaders[6], diff --git a/test/EFCore.Specification.Tests/TestModels/GearsOfWarModel/Officer.cs b/test/EFCore.Specification.Tests/TestModels/GearsOfWarModel/Officer.cs index 18a678ec6bc..57a83322825 100644 --- a/test/EFCore.Specification.Tests/TestModels/GearsOfWarModel/Officer.cs +++ b/test/EFCore.Specification.Tests/TestModels/GearsOfWarModel/Officer.cs @@ -6,9 +6,7 @@ namespace Microsoft.EntityFrameworkCore.TestModels.GearsOfWarModel; public class Officer : Gear { public Officer() - { - Reports = new List(); - } + => Reports = new List(); // 1 - many self reference public virtual ICollection Reports { get; set; } diff --git a/test/EFCore.Specification.Tests/TestModels/GearsOfWarModel/Squad.cs b/test/EFCore.Specification.Tests/TestModels/GearsOfWarModel/Squad.cs index e00a81bf681..aae303e17c9 100644 --- a/test/EFCore.Specification.Tests/TestModels/GearsOfWarModel/Squad.cs +++ b/test/EFCore.Specification.Tests/TestModels/GearsOfWarModel/Squad.cs @@ -8,9 +8,7 @@ namespace Microsoft.EntityFrameworkCore.TestModels.GearsOfWarModel; public class Squad { public Squad() - { - Members = new List(); - } + => Members = new List(); // non-auto generated key public int Id { get; set; } diff --git a/test/EFCore.Specification.Tests/TestModels/InheritanceRelationshipsModel/InheritanceRelationshipsData.cs b/test/EFCore.Specification.Tests/TestModels/InheritanceRelationshipsModel/InheritanceRelationshipsData.cs index 09b76e9e5dc..846c3072231 100644 --- a/test/EFCore.Specification.Tests/TestModels/InheritanceRelationshipsModel/InheritanceRelationshipsData.cs +++ b/test/EFCore.Specification.Tests/TestModels/InheritanceRelationshipsModel/InheritanceRelationshipsData.cs @@ -136,7 +136,7 @@ public static IReadOnlyList CreateBaseEntitie Name = "Base1", OwnedReferenceOnBase = new OwnedEntity { Name = "OROB1" }, OwnedCollectionOnBase = - [new() { Id = 1, Name = "OCOB11" }, new() { Id = 2, Name = "OCOB12" }], + [new OwnedEntity { Id = 1, Name = "OCOB11" }, new OwnedEntity { Id = 2, Name = "OCOB12" }], BaseCollectionOnBase = [], CollectionOnBase = [], }, @@ -145,7 +145,7 @@ public static IReadOnlyList CreateBaseEntitie Id = 2, Name = "Base2", OwnedReferenceOnBase = new OwnedEntity { Name = "OROB2" }, - OwnedCollectionOnBase = [new() { Id = 3, Name = "OCOB21" }], + OwnedCollectionOnBase = [new OwnedEntity { Id = 3, Name = "OCOB21" }], BaseCollectionOnBase = [], CollectionOnBase = [], }, @@ -163,10 +163,10 @@ public static IReadOnlyList CreateBaseEntitie Name = "Derived1(4)", OwnedReferenceOnBase = new OwnedEntity { Name = "OROB4" }, OwnedCollectionOnBase = - [new() { Id = 4, Name = "OCOB41" }, new() { Id = 5, Name = "OCOB42" }], + [new OwnedEntity { Id = 4, Name = "OCOB41" }, new OwnedEntity { Id = 5, Name = "OCOB42" }], OwnedReferenceOnDerived = new OwnedEntity { Name = "OROD4" }, OwnedCollectionOnDerived = - [new() { Id = 1, Name = "OCOD41" }, new() { Id = 2, Name = "OCOD42" }], + [new OwnedEntity { Id = 1, Name = "OCOD41" }, new OwnedEntity { Id = 2, Name = "OCOD42" }], BaseCollectionOnBase = [], BaseCollectionOnDerived = [], CollectionOnBase = [], @@ -178,9 +178,9 @@ public static IReadOnlyList CreateBaseEntitie Id = 5, Name = "Derived2(5)", OwnedReferenceOnBase = new OwnedEntity { Name = "OROB5" }, - OwnedCollectionOnBase = [new() { Id = 6, Name = "OCOB51" }], + OwnedCollectionOnBase = [new OwnedEntity { Id = 6, Name = "OCOB51" }], OwnedReferenceOnDerived = new OwnedEntity { Name = "OROD5" }, - OwnedCollectionOnDerived = [new() { Id = 3, Name = "OCOD51" }], + OwnedCollectionOnDerived = [new OwnedEntity { Id = 3, Name = "OCOD51" }], BaseCollectionOnBase = [], BaseCollectionOnDerived = [], CollectionOnBase = [], diff --git a/test/EFCore.Specification.Tests/TestModels/JsonQuery/AJsonEntityHasComplexChildForReferenceForReference.cs b/test/EFCore.Specification.Tests/TestModels/JsonQuery/AJsonEntityHasComplexChildForReferenceForReference.cs new file mode 100644 index 00000000000..6c626fdd858 --- /dev/null +++ b/test/EFCore.Specification.Tests/TestModels/JsonQuery/AJsonEntityHasComplexChildForReferenceForReference.cs @@ -0,0 +1,15 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.TestModels.JsonQuery; + +#nullable disable + +public class AJsonEntityHasComplexChildForReferenceForReference +{ + public int Id { get; set; } + public string Name { get; set; } + + public int? ParentId { get; set; } + public JsonEntityHasComplexChildForReference Parent { get; set; } +} diff --git a/test/EFCore.Specification.Tests/TestModels/JsonQuery/JsonEntityAllTypes.cs b/test/EFCore.Specification.Tests/TestModels/JsonQuery/JsonEntityAllTypes.cs index 157cd0ee3cd..1bc8effc7b3 100644 --- a/test/EFCore.Specification.Tests/TestModels/JsonQuery/JsonEntityAllTypes.cs +++ b/test/EFCore.Specification.Tests/TestModels/JsonQuery/JsonEntityAllTypes.cs @@ -15,11 +15,11 @@ public class JsonEntityAllTypes private Collection _testNullableEnumCollectionX = []; private Collection _testNullableEnumWithIntConverterCollectionX = [JsonEnum.Three]; - public List> TestInt64CollectionCollection { get; set; } = []; - public IReadOnlyList TestDoubleCollectionCollection { get; set; } = new List(); - public List[] TestSingleCollectionCollection { get; set; } = [[1.1f, 1.2f]]; - public bool[][] TestBooleanCollectionCollection { get; set; } = []; - public ObservableCollection> TestCharacterCollectionCollection { get; set; } = []; + public List> TestInt64CollectionCollection { get; set; } = []; + public IReadOnlyList TestDoubleCollectionCollection { get; set; } = new List(); + public List[] TestSingleCollectionCollection { get; set; } = [[1.1f, 1.2f]]; + public bool[][] TestBooleanCollectionCollection { get; set; } = []; + public ObservableCollection> TestCharacterCollectionCollection { get; set; } = []; public int Id { get; set; } public JsonOwnedAllTypes Reference { get; init; } @@ -40,9 +40,9 @@ public class JsonEntityAllTypes public decimal[] TestDecimalCollection { get; set; } public List TestDateTimeCollection { get; set; } public IList TestDateTimeOffsetCollection { get; set; } - public TimeSpan[] TestTimeSpanCollection { get; set; } = [new(1, 1, 1)]; + public TimeSpan[] TestTimeSpanCollection { get; set; } = [new TimeSpan(1, 1, 1)]; - public ReadOnlyCollection TestInt64Collection { get; set; } = new ReadOnlyCollection([]); + public ReadOnlyCollection TestInt64Collection { get; set; } = new([]); public IList TestDoubleCollection { get; set; } = new List(); public IReadOnlyList TestSingleCollection { get; set; } = [1.1f, 1.2f]; public IList TestBooleanCollection { get; set; } = new List { true }; diff --git a/test/EFCore.Specification.Tests/TestModels/JsonQuery/JsonEntityHasComplexChild.cs b/test/EFCore.Specification.Tests/TestModels/JsonQuery/JsonEntityHasComplexChild.cs new file mode 100644 index 00000000000..5903756f29d --- /dev/null +++ b/test/EFCore.Specification.Tests/TestModels/JsonQuery/JsonEntityHasComplexChild.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.TestModels.JsonQuery; + +#nullable disable + +public class JsonEntityHasComplexChild +{ + public int Id { get; set; } + public string Name { get; set; } + + public JsonEntityHasComplexChildForReference EntityReference { get; set; } +} diff --git a/test/EFCore.Specification.Tests/TestModels/JsonQuery/JsonEntityHasComplexChildForReference.cs b/test/EFCore.Specification.Tests/TestModels/JsonQuery/JsonEntityHasComplexChildForReference.cs new file mode 100644 index 00000000000..148e1b868e0 --- /dev/null +++ b/test/EFCore.Specification.Tests/TestModels/JsonQuery/JsonEntityHasComplexChildForReference.cs @@ -0,0 +1,18 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.TestModels.JsonQuery; + +#nullable disable + +public class JsonEntityHasComplexChildForReference +{ + public int Id { get; set; } + public string Name { get; set; } + + // A is required for sorting + public AJsonEntityHasComplexChildForReferenceForReference AEntityReference { get; set; } + + public int? ParentId { get; set; } + public JsonEntityHasComplexChild Parent { get; set; } +} diff --git a/test/EFCore.Specification.Tests/TestModels/JsonQuery/JsonOwnedAllTypes.cs b/test/EFCore.Specification.Tests/TestModels/JsonQuery/JsonOwnedAllTypes.cs index 1e53672004f..d455de89c9a 100644 --- a/test/EFCore.Specification.Tests/TestModels/JsonQuery/JsonOwnedAllTypes.cs +++ b/test/EFCore.Specification.Tests/TestModels/JsonQuery/JsonOwnedAllTypes.cs @@ -48,11 +48,11 @@ public class JsonOwnedAllTypes public JsonEnum? TestNullableEnumWithIntConverter { get; set; } public JsonEnum? TestNullableEnumWithConverterThatHandlesNulls { get; set; } - public List> TestInt64CollectionCollection { get; set; } = []; - public List TestDoubleCollectionCollection { get; set; } = new(); - public List TestSingleCollectionCollection { get; set; } = new([([1.1f, 1.2f])]); - public bool[][] TestBooleanCollectionCollection { get; set; } = []; - public ObservableCollection> TestCharacterCollectionCollection { get; set; } = []; + public List> TestInt64CollectionCollection { get; set; } = []; + public List TestDoubleCollectionCollection { get; set; } = new(); + public List TestSingleCollectionCollection { get; set; } = new([( [1.1f, 1.2f])]); + public bool[][] TestBooleanCollectionCollection { get; set; } = []; + public ObservableCollection> TestCharacterCollectionCollection { get; set; } = []; public string[] TestDefaultStringCollection { get; set; } public ReadOnlyCollection TestMaxLengthStringCollection { get; set; } @@ -83,7 +83,7 @@ public IList TestDoubleCollection public decimal[] TestDecimalCollection { get; set; } public List TestDateTimeCollection { get; set; } public IList TestDateTimeOffsetCollection { get; set; } - public TimeSpan[] TestTimeSpanCollection { get; set; } = [new(1, 1, 1)]; + public TimeSpan[] TestTimeSpanCollection { get; set; } = [new TimeSpan(1, 1, 1)]; public DateOnly[] TestDateOnlyCollection { get; set; } public TimeOnly[] TestTimeOnlyCollection { get; set; } diff --git a/test/EFCore.Specification.Tests/TestModels/JsonQuery/JsonOwnedBranch.cs b/test/EFCore.Specification.Tests/TestModels/JsonQuery/JsonOwnedBranch.cs index e3bdd6d376c..459f519dc32 100644 --- a/test/EFCore.Specification.Tests/TestModels/JsonQuery/JsonOwnedBranch.cs +++ b/test/EFCore.Specification.Tests/TestModels/JsonQuery/JsonOwnedBranch.cs @@ -7,6 +7,7 @@ namespace Microsoft.EntityFrameworkCore.TestModels.JsonQuery; public class JsonOwnedBranch { + public int Id { get; set; } public DateTime Date { get; set; } public decimal Fraction { get; set; } diff --git a/test/EFCore.Specification.Tests/TestModels/JsonQuery/JsonOwnedRoot.cs b/test/EFCore.Specification.Tests/TestModels/JsonQuery/JsonOwnedRoot.cs index 849c2884676..b9a7887fcdc 100644 --- a/test/EFCore.Specification.Tests/TestModels/JsonQuery/JsonOwnedRoot.cs +++ b/test/EFCore.Specification.Tests/TestModels/JsonQuery/JsonOwnedRoot.cs @@ -7,6 +7,7 @@ namespace Microsoft.EntityFrameworkCore.TestModels.JsonQuery; public class JsonOwnedRoot { + public int Id { get; set; } public string Name { get; set; } public int Number { get; set; } public string[] Names { get; set; } diff --git a/test/EFCore.Specification.Tests/TestModels/JsonQuery/JsonQueryContext.cs b/test/EFCore.Specification.Tests/TestModels/JsonQuery/JsonQueryContext.cs index b6010b6182f..d52093d8bcc 100644 --- a/test/EFCore.Specification.Tests/TestModels/JsonQuery/JsonQueryContext.cs +++ b/test/EFCore.Specification.Tests/TestModels/JsonQuery/JsonQueryContext.cs @@ -16,6 +16,7 @@ public class JsonQueryContext(DbContextOptions options) : DbContext(options) public DbSet JsonEntitiesInheritance { get; set; } public DbSet JsonEntitiesAllTypes { get; set; } public DbSet JsonEntitiesConverters { get; set; } + public DbSet JsonEntitiesHasComplexChild { get; set; } public static Task SeedAsync(JsonQueryContext context) { diff --git a/test/EFCore.Specification.Tests/TestModels/JsonQuery/JsonQueryData.cs b/test/EFCore.Specification.Tests/TestModels/JsonQuery/JsonQueryData.cs index 4d50437b494..71d19bc0b18 100644 --- a/test/EFCore.Specification.Tests/TestModels/JsonQuery/JsonQueryData.cs +++ b/test/EFCore.Specification.Tests/TestModels/JsonQuery/JsonQueryData.cs @@ -48,6 +48,7 @@ public static IReadOnlyList CreateJsonEntitiesBasic() var e1_r_r = new JsonOwnedBranch { + Id = 88, Date = new DateTime(2100, 1, 1), Fraction = 10.0M, Enum = JsonEnum.One, @@ -73,6 +74,7 @@ public static IReadOnlyList CreateJsonEntitiesBasic() var e1_r_c1 = new JsonOwnedBranch { + Id = 89, Date = new DateTime(2101, 1, 1), Fraction = 10.1M, Enum = JsonEnum.Two, @@ -98,6 +100,7 @@ public static IReadOnlyList CreateJsonEntitiesBasic() var e1_r_c2 = new JsonOwnedBranch { + Id = 90, Date = new DateTime(2102, 1, 1), Fraction = 10.2M, Enum = JsonEnum.Three, @@ -137,6 +140,7 @@ public static IReadOnlyList CreateJsonEntitiesBasic() var e1_c1_r = new JsonOwnedBranch { + Id = 91, Date = new DateTime(2110, 1, 1), Fraction = 11.0M, Enum = JsonEnum.One, @@ -162,6 +166,7 @@ public static IReadOnlyList CreateJsonEntitiesBasic() var e1_c1_c1 = new JsonOwnedBranch { + Id = 92, Date = new DateTime(2111, 1, 1), Fraction = 11.1M, Enum = JsonEnum.Two, @@ -187,6 +192,7 @@ public static IReadOnlyList CreateJsonEntitiesBasic() var e1_c1_c2 = new JsonOwnedBranch { + Id = 93, Date = new DateTime(2112, 1, 1), Fraction = 11.2M, Enum = JsonEnum.Three, @@ -226,6 +232,7 @@ public static IReadOnlyList CreateJsonEntitiesBasic() var e1_c2_r = new JsonOwnedBranch { + Id = 94, Date = new DateTime(2120, 1, 1), Fraction = 12.0M, Enum = JsonEnum.Three, @@ -251,6 +258,7 @@ public static IReadOnlyList CreateJsonEntitiesBasic() var e1_c2_c1 = new JsonOwnedBranch { + Id = 95, Date = new DateTime(2121, 1, 1), Fraction = 12.1M, Enum = JsonEnum.Two, @@ -276,6 +284,7 @@ public static IReadOnlyList CreateJsonEntitiesBasic() var e1_c2_c2 = new JsonOwnedBranch { + Id = 96, Date = new DateTime(2122, 1, 1), Fraction = 12.2M, Enum = JsonEnum.One, @@ -471,9 +480,9 @@ public static IReadOnlyList CreateJsonEntitiesSingleOwned Name = "JsonEntitySingleOwned1", OwnedCollection = [ - new() { SomethingSomething = "owned_1_1" }, - new() { SomethingSomething = "owned_1_2" }, - new() { SomethingSomething = "owned_1_3" } + new JsonOwnedLeaf { SomethingSomething = "owned_1_1" }, + new JsonOwnedLeaf { SomethingSomething = "owned_1_2" }, + new JsonOwnedLeaf { SomethingSomething = "owned_1_3" } ] }; @@ -490,7 +499,7 @@ public static IReadOnlyList CreateJsonEntitiesSingleOwned Name = "JsonEntitySingleOwned3", OwnedCollection = [ - new() { SomethingSomething = "owned_3_1" }, new() { SomethingSomething = "owned_3_2" } + new JsonOwnedLeaf { SomethingSomething = "owned_3_1" }, new JsonOwnedLeaf { SomethingSomething = "owned_3_2" } ] }; @@ -512,6 +521,7 @@ public static IReadOnlyList CreateJsonEntitiesInherit var b1_r = new JsonOwnedBranch { + Id = 97, Date = new DateTime(2010, 1, 1), Fraction = 1.0M, Enum = JsonEnum.One, @@ -530,6 +540,7 @@ public static IReadOnlyList CreateJsonEntitiesInherit var b1_c1 = new JsonOwnedBranch { + Id = 98, Date = new DateTime(2011, 1, 1), Fraction = 11.1M, Enum = JsonEnum.Three, @@ -548,6 +559,7 @@ public static IReadOnlyList CreateJsonEntitiesInherit var b1_c2 = new JsonOwnedBranch { + Id = 99, Date = new DateTime(2012, 1, 1), Fraction = 12.1M, Enum = JsonEnum.Two, @@ -566,6 +578,7 @@ public static IReadOnlyList CreateJsonEntitiesInherit var b2_r = new JsonOwnedBranch { + Id = 100, Date = new DateTime(2020, 1, 1), Fraction = 2.0M, Enum = JsonEnum.Two, @@ -584,6 +597,7 @@ public static IReadOnlyList CreateJsonEntitiesInherit var b2_c1 = new JsonOwnedBranch { + Id = 101, Date = new DateTime(2021, 1, 1), Fraction = 21.1M, Enum = JsonEnum.Three, @@ -602,6 +616,7 @@ public static IReadOnlyList CreateJsonEntitiesInherit var b2_c2 = new JsonOwnedBranch { + Id = 102, Date = new DateTime(2022, 1, 1), Fraction = 22.1M, Enum = JsonEnum.One, @@ -620,6 +635,7 @@ public static IReadOnlyList CreateJsonEntitiesInherit var d2_r = new JsonOwnedBranch { + Id = 103, Date = new DateTime(2220, 1, 1), Fraction = 22.0M, Enum = JsonEnum.One, @@ -638,6 +654,7 @@ public static IReadOnlyList CreateJsonEntitiesInherit var d2_c1 = new JsonOwnedBranch { + Id = 104, Date = new DateTime(2221, 1, 1), Fraction = 221.1M, Enum = JsonEnum.Two, @@ -656,6 +673,7 @@ public static IReadOnlyList CreateJsonEntitiesInherit var d2_c2 = new JsonOwnedBranch { + Id = 105, Date = new DateTime(2222, 1, 1), Fraction = 222.1M, Enum = JsonEnum.Three, @@ -737,7 +755,7 @@ public static IReadOnlyList CreateJsonEntitiesAllTypes() TestDateTimeOffsetCollection = new[] { new DateTimeOffset(DateTime.Parse("01/01/2000 12:34:56"), TimeSpan.FromHours(-8.0)) }, TestDoubleCollection = new[] { -1.23456789, 1.23456789, 0.0 }, TestDecimalCollection = [-1234567890.01M], - TestGuidCollection = [new("12345678-1234-4321-7777-987654321000")], + TestGuidCollection = [new Guid("12345678-1234-4321-7777-987654321000")], TestInt16Collection = new[] { short.MinValue, (short)0, short.MaxValue }, TestInt32Collection = [int.MinValue, 0, int.MaxValue], TestInt64Collection = @@ -746,7 +764,7 @@ public static IReadOnlyList CreateJsonEntitiesAllTypes() 0, long.MaxValue ], - TestSignedByteCollection = [sbyte.MinValue, (sbyte)0, sbyte.MaxValue], + TestSignedByteCollection = [sbyte.MinValue, 0, sbyte.MaxValue], TestSingleCollection = [ -1.234F, @@ -762,7 +780,7 @@ public static IReadOnlyList CreateJsonEntitiesAllTypes() 0, ushort.MaxValue }, - TestUnsignedInt32Collection = [uint.MinValue, (uint)0, uint.MaxValue], + TestUnsignedInt32Collection = [uint.MinValue, 0, uint.MaxValue], TestUnsignedInt64Collection = [ ulong.MinValue, @@ -796,7 +814,8 @@ public static IReadOnlyList CreateJsonEntitiesAllTypes() ], TestNullableEnumWithConverterThatHandlesNullsCollection = [JsonEnum.One, null, (JsonEnum)(-7)], TestDefaultStringCollectionCollection = [["S11", "S12", "S13"], null, ["S21", null, "S23"]], - TestMaxLengthStringCollectionCollection = [new ReadOnlyCollection(["S11", "S12", "S13"]), null, new ReadOnlyCollection(["S21", null, "S23"])], + TestMaxLengthStringCollectionCollection = + [new ReadOnlyCollection(["S11", "S12", "S13"]), null, new ReadOnlyCollection(["S21", null, "S23"])], TestBooleanCollectionCollection = [[true], null, [true, false]], TestCharacterCollectionCollection = [['A', 'B', 'C'], null, ['D', 'E', 'F']], TestDoubleCollectionCollection = [[-1.23456789, -1.23456789], null, [1.23456789]], @@ -805,8 +824,16 @@ public static IReadOnlyList CreateJsonEntitiesAllTypes() TestInt64CollectionCollection = [[long.MinValue, 0, long.MaxValue], null, [long.MinValue, 0, long.MaxValue]], TestSingleCollectionCollection = [[-1.234F, 0.0F, -1.234F], null, [-1.234F, 0.0F, -1.234F]], TestNullableInt32CollectionCollection = [null, [int.MinValue, null, int.MaxValue, null], null, [int.MinValue, 0, int.MaxValue]], - TestNullableEnumCollectionCollection = [[null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)], null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)]], null], - TestNullableEnumWithIntConverterCollectionCollection = [[null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)], null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)]], null], + TestNullableEnumCollectionCollection = + [ + [null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)], null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)]], + null + ], + TestNullableEnumWithIntConverterCollectionCollection = + [ + [null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)], null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)]], + null + ], }; var r2 = new JsonOwnedAllTypes @@ -857,7 +884,7 @@ public static IReadOnlyList CreateJsonEntitiesAllTypes() TestDateTimeOffsetCollection = new[] { new DateTimeOffset(DateTime.Parse("01/01/2000 12:34:56"), TimeSpan.FromHours(-8.0)) }, TestDoubleCollection = new[] { -1.23456789, 1.23456789, 0.0 }, TestDecimalCollection = [-1234567890.01M], - TestGuidCollection = [new("12345678-1234-4321-7777-987654321000")], + TestGuidCollection = [new Guid("12345678-1234-4321-7777-987654321000")], TestInt16Collection = new[] { short.MinValue, (short)0, short.MaxValue }, TestInt32Collection = [int.MinValue, 0, int.MaxValue], TestInt64Collection = @@ -866,7 +893,7 @@ public static IReadOnlyList CreateJsonEntitiesAllTypes() 0, long.MaxValue ], - TestSignedByteCollection = [sbyte.MinValue, (sbyte)0, sbyte.MaxValue], + TestSignedByteCollection = [sbyte.MinValue, 0, sbyte.MaxValue], TestSingleCollection = [ -1.234F, @@ -877,7 +904,7 @@ public static IReadOnlyList CreateJsonEntitiesAllTypes() TestDateOnlyCollection = [new DateOnly(2234, 1, 23), new DateOnly(5321, 1, 21)], TestTimeOnlyCollection = [new TimeOnly(21, 42, 23), new TimeOnly(17, 17, 27)], TestUnsignedInt16Collection = new[] { ushort.MinValue, (ushort)0, ushort.MaxValue }, - TestUnsignedInt32Collection = [uint.MinValue, (uint)0, uint.MaxValue], + TestUnsignedInt32Collection = [uint.MinValue, 0, uint.MaxValue], TestUnsignedInt64Collection = [ ulong.MinValue, @@ -911,7 +938,8 @@ public static IReadOnlyList CreateJsonEntitiesAllTypes() ], TestNullableEnumWithConverterThatHandlesNullsCollection = [JsonEnum.One, null, (JsonEnum)(-7)], TestDefaultStringCollectionCollection = [["S11", "S12", "S13"], null, ["S21", null, "S23"]], - TestMaxLengthStringCollectionCollection = [new ReadOnlyCollection(["S11", "S12", "S13"]), null, new ReadOnlyCollection(["S21", null, "S23"])], + TestMaxLengthStringCollectionCollection = + [new ReadOnlyCollection(["S11", "S12", "S13"]), null, new ReadOnlyCollection(["S21", null, "S23"])], TestBooleanCollectionCollection = [[true], null, [true, false]], TestCharacterCollectionCollection = [['A', 'B', 'C'], null, ['D', 'E', 'F']], TestDoubleCollectionCollection = [[-1.23456789, -1.23456789], null, [1.23456789]], @@ -920,8 +948,16 @@ public static IReadOnlyList CreateJsonEntitiesAllTypes() TestInt64CollectionCollection = [[long.MinValue, 0, long.MaxValue], null, [long.MinValue, 0, long.MaxValue]], TestSingleCollectionCollection = [[-1.234F, 0.0F, -1.234F], null, [-1.234F, 0.0F, -1.234F]], TestNullableInt32CollectionCollection = [null, [int.MinValue, null, int.MaxValue, null], null, [int.MinValue, 0, int.MaxValue]], - TestNullableEnumCollectionCollection = [[null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)], null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)]], null], - TestNullableEnumWithIntConverterCollectionCollection = [[null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)], null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)]], null], + TestNullableEnumCollectionCollection = + [ + [null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)], null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)]], + null + ], + TestNullableEnumWithIntConverterCollectionCollection = + [ + [null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)], null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)]], + null + ], }; var c1 = new JsonOwnedAllTypes @@ -972,7 +1008,7 @@ public static IReadOnlyList CreateJsonEntitiesAllTypes() TestDateTimeOffsetCollection = new[] { new DateTimeOffset(DateTime.Parse("01/01/2000 12:34:56"), TimeSpan.FromHours(-8.0)) }, TestDoubleCollection = new[] { -1.23456789, 1.23456789, 0.0 }, TestDecimalCollection = [-1234567890.01M], - TestGuidCollection = [new("12345678-1234-4321-7777-987654321000")], + TestGuidCollection = [new Guid("12345678-1234-4321-7777-987654321000")], TestInt16Collection = new[] { short.MinValue, (short)0, short.MaxValue }, TestInt32Collection = [int.MinValue, 0, int.MaxValue], TestInt64Collection = @@ -981,7 +1017,7 @@ public static IReadOnlyList CreateJsonEntitiesAllTypes() 0, long.MaxValue ], - TestSignedByteCollection = [sbyte.MinValue, (sbyte)0, sbyte.MaxValue], + TestSignedByteCollection = [sbyte.MinValue, 0, sbyte.MaxValue], TestSingleCollection = [ -1.234F, @@ -992,7 +1028,7 @@ public static IReadOnlyList CreateJsonEntitiesAllTypes() TestDateOnlyCollection = [new DateOnly(3234, 1, 23), new DateOnly(4331, 1, 21)], TestTimeOnlyCollection = [new TimeOnly(13, 42, 23), new TimeOnly(7, 17, 25)], TestUnsignedInt16Collection = new[] { ushort.MinValue, (ushort)0, ushort.MaxValue }, - TestUnsignedInt32Collection = [uint.MinValue, (uint)0, uint.MaxValue], + TestUnsignedInt32Collection = [uint.MinValue, 0, uint.MaxValue], TestUnsignedInt64Collection = [ ulong.MinValue, @@ -1026,7 +1062,8 @@ public static IReadOnlyList CreateJsonEntitiesAllTypes() }, TestNullableEnumWithConverterThatHandlesNullsCollection = [JsonEnum.One, null, (JsonEnum)(-7)], TestDefaultStringCollectionCollection = [["S11", "S12", "S13"], null, ["S21", null, "S23"]], - TestMaxLengthStringCollectionCollection = [new ReadOnlyCollection(["S11", "S12", "S13"]), null, new ReadOnlyCollection(["S21", null, "S23"])], + TestMaxLengthStringCollectionCollection = + [new ReadOnlyCollection(["S11", "S12", "S13"]), null, new ReadOnlyCollection(["S21", null, "S23"])], TestBooleanCollectionCollection = [[true], null, [true, false]], TestCharacterCollectionCollection = [['A', 'B', 'C'], null, ['D', 'E', 'F']], TestDoubleCollectionCollection = [[-1.23456789, -1.23456789], null, [1.23456789]], @@ -1035,8 +1072,16 @@ public static IReadOnlyList CreateJsonEntitiesAllTypes() TestInt64CollectionCollection = [[long.MinValue, 0, long.MaxValue], null, [long.MinValue, 0, long.MaxValue]], TestSingleCollectionCollection = [[-1.234F, 0.0F, -1.234F], null, [-1.234F, 0.0F, -1.234F]], TestNullableInt32CollectionCollection = [null, [int.MinValue, null, int.MaxValue, null], null, [int.MinValue, 0, int.MaxValue]], - TestNullableEnumCollectionCollection = [[null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)], null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)]], null], - TestNullableEnumWithIntConverterCollectionCollection = [[null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)], null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)]], null], + TestNullableEnumCollectionCollection = + [ + [null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)], null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)]], + null + ], + TestNullableEnumWithIntConverterCollectionCollection = + [ + [null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)], null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)]], + null + ], }; var c2 = new JsonOwnedAllTypes @@ -1087,7 +1132,7 @@ public static IReadOnlyList CreateJsonEntitiesAllTypes() TestDateTimeOffsetCollection = new[] { new DateTimeOffset(DateTime.Parse("01/01/2000 12:34:56"), TimeSpan.FromHours(-8.0)) }, TestDoubleCollection = new[] { -1.23456789, 1.23456789, 0.0 }, TestDecimalCollection = [-1234567890.01M], - TestGuidCollection = [new("12345678-1234-4321-7777-987654321000")], + TestGuidCollection = [new Guid("12345678-1234-4321-7777-987654321000")], TestInt16Collection = new[] { short.MinValue, (short)0, short.MaxValue }, TestInt32Collection = [int.MinValue, 0, int.MaxValue], TestInt64Collection = @@ -1096,7 +1141,7 @@ public static IReadOnlyList CreateJsonEntitiesAllTypes() 0, long.MaxValue ], - TestSignedByteCollection = [sbyte.MinValue, (sbyte)0, sbyte.MaxValue], + TestSignedByteCollection = [sbyte.MinValue, 0, sbyte.MaxValue], TestSingleCollection = [ -1.234F, @@ -1107,7 +1152,7 @@ public static IReadOnlyList CreateJsonEntitiesAllTypes() TestDateOnlyCollection = [new DateOnly(1638, 1, 23), new DateOnly(4321, 1, 21)], TestTimeOnlyCollection = [new TimeOnly(8, 22, 23), new TimeOnly(7, 27, 37)], TestUnsignedInt16Collection = new[] { ushort.MinValue, (ushort)0, ushort.MaxValue }, - TestUnsignedInt32Collection = [uint.MinValue, (uint)0, uint.MaxValue], + TestUnsignedInt32Collection = [uint.MinValue, 0, uint.MaxValue], TestUnsignedInt64Collection = [ ulong.MinValue, @@ -1141,7 +1186,8 @@ public static IReadOnlyList CreateJsonEntitiesAllTypes() }, TestNullableEnumWithConverterThatHandlesNullsCollection = [JsonEnum.One, null, (JsonEnum)(-7)], TestDefaultStringCollectionCollection = [["S11", "S12", "S13"], null, ["S21", null, "S23"]], - TestMaxLengthStringCollectionCollection = [new ReadOnlyCollection(["S11", "S12", "S13"]), null, new ReadOnlyCollection(["S21", null, "S23"])], + TestMaxLengthStringCollectionCollection = + [new ReadOnlyCollection(["S11", "S12", "S13"]), null, new ReadOnlyCollection(["S21", null, "S23"])], TestBooleanCollectionCollection = [[true], null, [true, false]], TestCharacterCollectionCollection = [['A', 'B', 'C'], null, ['D', 'E', 'F']], TestDoubleCollectionCollection = [[-1.23456789, -1.23456789], null, [1.23456789]], @@ -1150,8 +1196,16 @@ public static IReadOnlyList CreateJsonEntitiesAllTypes() TestInt64CollectionCollection = [[long.MinValue, 0, long.MaxValue], null, [long.MinValue, 0, long.MaxValue]], TestSingleCollectionCollection = [[-1.234F, 0.0F, -1.234F], null, [-1.234F, 0.0F, -1.234F]], TestNullableInt32CollectionCollection = [null, [int.MinValue, null, int.MaxValue, null], null, [int.MinValue, 0, int.MaxValue]], - TestNullableEnumCollectionCollection = [[null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)], null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)]], null], - TestNullableEnumWithIntConverterCollectionCollection = [[null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)], null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)]], null], + TestNullableEnumCollectionCollection = + [ + [null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)], null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)]], + null + ], + TestNullableEnumWithIntConverterCollectionCollection = + [ + [null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)], null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)]], + null + ], }; return new List @@ -1169,6 +1223,7 @@ public static IReadOnlyList CreateJsonEntitiesAllTypes() "S3" ], TestBooleanCollection = new[] { true, false }, + TestByteCollection = [], TestCharacterCollection = [ 'A', @@ -1181,7 +1236,7 @@ public static IReadOnlyList CreateJsonEntitiesAllTypes() new[] { new DateTimeOffset(DateTime.Parse("01/01/2000 12:34:56"), TimeSpan.FromHours(-8.0)) }, TestDoubleCollection = new[] { -1.23456789, 1.23456789, 0.0 }, TestDecimalCollection = [-1234567890.01M], - TestGuidCollection = new ReadOnlyCollection([new("12345678-1234-4321-7777-987654321000")]), + TestGuidCollection = new ReadOnlyCollection([new Guid("12345678-1234-4321-7777-987654321000")]), TestInt16Collection = new[] { short.MinValue, (short)0, short.MaxValue }, TestInt32Collection = [int.MinValue, 0, int.MaxValue], TestInt64Collection = new ReadOnlyCollection( @@ -1190,7 +1245,7 @@ public static IReadOnlyList CreateJsonEntitiesAllTypes() 0, long.MaxValue ]), - TestSignedByteCollection = [sbyte.MinValue, (sbyte)0, sbyte.MaxValue], + TestSignedByteCollection = [sbyte.MinValue, 0, sbyte.MaxValue], TestSingleCollection = [ -1.234F, @@ -1204,7 +1259,7 @@ public static IReadOnlyList CreateJsonEntitiesAllTypes() 0, ushort.MaxValue }, - TestUnsignedInt32Collection = [uint.MinValue, (uint)0, uint.MaxValue], + TestUnsignedInt32Collection = [uint.MinValue, 0, uint.MaxValue], TestUnsignedInt64Collection = [ ulong.MinValue, @@ -1240,15 +1295,31 @@ public static IReadOnlyList CreateJsonEntitiesAllTypes() TestDefaultStringCollectionCollection = [["S11", "S12", "S13"], null, ["S21", null, "S23"]], TestMaxLengthStringCollectionCollection = [["S11", "S12", "S13"], null, ["S21", null, "S23"]], TestBooleanCollectionCollection = [[true], null, [true, false]], - TestCharacterCollectionCollection = [new ReadOnlyCollection(['A', 'B', 'C']), null, new ReadOnlyCollection(['D', 'E', 'F'])], + TestCharacterCollectionCollection = + [new ReadOnlyCollection(['A', 'B', 'C']), null, new ReadOnlyCollection(['D', 'E', 'F'])], TestDoubleCollectionCollection = [[-1.23456789, -1.23456789], null, [1.23456789]], TestInt16CollectionCollection = [[short.MinValue, 0, short.MaxValue], null, [short.MinValue, 0, short.MaxValue]], TestInt32CollectionCollection = [[int.MinValue, 0, int.MaxValue], null, [int.MinValue, 0, int.MaxValue]], TestInt64CollectionCollection = [[long.MinValue, 0, long.MaxValue], null, [long.MinValue, 0, long.MaxValue]], TestSingleCollectionCollection = [[-1.234F, 0.0F, -1.234F], null, [-1.234F, 0.0F, -1.234F]], - TestNullableInt32CollectionCollection = [null, [int.MinValue, null, int.MaxValue, null], null, [int.MinValue, 0, int.MaxValue]], - TestNullableEnumCollectionCollection = [[null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)], null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)]], null], - TestNullableEnumWithIntConverterCollectionCollection = [[null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)], null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)]], null], + TestNullableInt32CollectionCollection = + [null, [int.MinValue, null, int.MaxValue, null], null, [int.MinValue, 0, int.MaxValue]], + TestNullableEnumCollectionCollection = + [ + [ + null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)], null, + [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)] + ], + null + ], + TestNullableEnumWithIntConverterCollectionCollection = + [ + [ + null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)], null, + [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)] + ], + null + ], }, new() { @@ -1263,6 +1334,7 @@ public static IReadOnlyList CreateJsonEntitiesAllTypes() "S3" ], TestBooleanCollection = new[] { true, false }, + TestByteCollection = [], TestCharacterCollection = [ 'A', @@ -1275,7 +1347,7 @@ public static IReadOnlyList CreateJsonEntitiesAllTypes() new[] { new DateTimeOffset(DateTime.Parse("01/01/2000 12:34:56"), TimeSpan.FromHours(-8.0)) }, TestDoubleCollection = new[] { -1.23456789, 1.23456789, 0.0 }, TestDecimalCollection = [-1234567890.01M], - TestGuidCollection = new ReadOnlyCollection([new("12345678-1234-4321-7777-987654321000")]), + TestGuidCollection = new ReadOnlyCollection([new Guid("12345678-1234-4321-7777-987654321000")]), TestInt16Collection = new[] { short.MinValue, (short)0, short.MaxValue }, TestInt32Collection = [int.MinValue, 0, int.MaxValue], TestInt64Collection = new ReadOnlyCollection( @@ -1284,7 +1356,7 @@ public static IReadOnlyList CreateJsonEntitiesAllTypes() 0, long.MaxValue ]), - TestSignedByteCollection = [sbyte.MinValue, (sbyte)0, sbyte.MaxValue], + TestSignedByteCollection = [sbyte.MinValue, 0, sbyte.MaxValue], TestSingleCollection = [ -1.234F, @@ -1298,7 +1370,7 @@ public static IReadOnlyList CreateJsonEntitiesAllTypes() 0, ushort.MaxValue }, - TestUnsignedInt32Collection = [uint.MinValue, (uint)0, uint.MaxValue], + TestUnsignedInt32Collection = [uint.MinValue, 0, uint.MaxValue], TestUnsignedInt64Collection = [ ulong.MinValue, @@ -1334,15 +1406,31 @@ public static IReadOnlyList CreateJsonEntitiesAllTypes() TestDefaultStringCollectionCollection = [["S11B", "S12B", "S13B"], null, ["S21B", null, "S23B"]], TestMaxLengthStringCollectionCollection = [["S11B", "S12B", "S13B"], null, ["S21B", null, "S23B"]], TestBooleanCollectionCollection = [[true], null, [true, false]], - TestCharacterCollectionCollection = [new ReadOnlyCollection(['A', 'B', 'C']), null, new ReadOnlyCollection(['D', 'E', 'F'])], + TestCharacterCollectionCollection = + [new ReadOnlyCollection(['A', 'B', 'C']), null, new ReadOnlyCollection(['D', 'E', 'F'])], TestDoubleCollectionCollection = [[-1.23456789, -1.23456789], null, [1.23456789]], TestInt16CollectionCollection = [[short.MinValue, 0, short.MaxValue], null, [short.MinValue, 0, short.MaxValue]], TestInt32CollectionCollection = [[int.MinValue, 0, int.MaxValue], null, [int.MinValue, 0, int.MaxValue]], TestInt64CollectionCollection = [[long.MinValue, 0, long.MaxValue], null, [long.MinValue, 0, long.MaxValue]], TestSingleCollectionCollection = [[-1.234F, 0.0F, -1.234F], null, [-1.234F, 0.0F, -1.234F]], - TestNullableInt32CollectionCollection = [null, [int.MinValue, null, int.MaxValue, null], null, [int.MinValue, 0, int.MaxValue]], - TestNullableEnumCollectionCollection = [[null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)], null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)]], null], - TestNullableEnumWithIntConverterCollectionCollection = [[null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)], null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)]], null], + TestNullableInt32CollectionCollection = + [null, [int.MinValue, null, int.MaxValue, null], null, [int.MinValue, 0, int.MaxValue]], + TestNullableEnumCollectionCollection = + [ + [ + null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)], null, + [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)] + ], + null + ], + TestNullableEnumWithIntConverterCollectionCollection = + [ + [ + null, [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)], null, + [JsonEnum.One, null, JsonEnum.Three, (JsonEnum)(-7)] + ], + null + ], } }; } diff --git a/test/EFCore.Specification.Tests/TestModels/MonsterContext`.cs b/test/EFCore.Specification.Tests/TestModels/MonsterContext`.cs index de7eab59d7f..a3b6ca82d09 100644 --- a/test/EFCore.Specification.Tests/TestModels/MonsterContext`.cs +++ b/test/EFCore.Specification.Tests/TestModels/MonsterContext`.cs @@ -12,7 +12,8 @@ public class MonsterContext< TSmartCard, TRsaToken, TPasswordReset, TPageView, TLastLogin, TMessage, TAnOrder, TOrderNote, TOrderQualityCheck, TOrderLine, TProduct, TProductDetail, TProductReview, TProductPhoto, TProductWebFeature, TSupplier, TSupplierLogo, TSupplierInfo, TCustomerInfo, TComputer, TComputerDetail, TDriver, TLicense, TConcurrencyInfo, TAuditInfo, - TContactDetails, TDimensions, TPhone, TBackOrderLine, TDiscontinuedProduct, TProductPageView>(DbContextOptions options) : MonsterContext(options) + TContactDetails, TDimensions, TPhone, TBackOrderLine, TDiscontinuedProduct, TProductPageView>(DbContextOptions options) + : MonsterContext(options) where TCustomer : class, ICustomer, new() where TBarcode : class, IBarcode, new() where TIncorrectScan : class, IIncorrectScan, new() @@ -798,10 +799,7 @@ public override Task SeedUsingFKs() new TSupplier { Name = "Ants By Boris" }).Entity; var supplierLogo1 = Add( - new TSupplierLogo - { - SupplierId = Entry(supplier1).Property(e => e.SupplierId).CurrentValue, Logo = [201, 202] - }) + new TSupplierLogo { SupplierId = Entry(supplier1).Property(e => e.SupplierId).CurrentValue, Logo = [201, 202] }) .Entity; var supplierInfo1 = Add( @@ -1416,8 +1414,7 @@ public override Task SeedUsingNavigations(bool dependentNavs, bool principalNavs var supplierLogo1 = Add( new TSupplierLogo { - SupplierId = !principalNavs ? Entry(supplier1).Property(e => e.SupplierId).CurrentValue : 0, - Logo = [201, 202] + SupplierId = !principalNavs ? Entry(supplier1).Property(e => e.SupplierId).CurrentValue : 0, Logo = [201, 202] }).Entity; if (principalNavs) { diff --git a/test/EFCore.Specification.Tests/TestModels/Northwind/Customer.cs b/test/EFCore.Specification.Tests/TestModels/Northwind/Customer.cs index 6ab99aef8ed..ccabdd5406e 100644 --- a/test/EFCore.Specification.Tests/TestModels/Northwind/Customer.cs +++ b/test/EFCore.Specification.Tests/TestModels/Northwind/Customer.cs @@ -19,9 +19,7 @@ public Customer() // Custom ctor binding public Customer(DbContext context, ILazyLoader lazyLoader, string customerID) - { - CustomerID = customerID; - } + => CustomerID = customerID; [MaxLength(5)] [Required] diff --git a/test/EFCore.Specification.Tests/TestModels/Northwind/NorthwindContext.cs b/test/EFCore.Specification.Tests/TestModels/Northwind/NorthwindContext.cs index 9d2357038fe..7e63a90966a 100644 --- a/test/EFCore.Specification.Tests/TestModels/Northwind/NorthwindContext.cs +++ b/test/EFCore.Specification.Tests/TestModels/Northwind/NorthwindContext.cs @@ -75,11 +75,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) }); modelBuilder.Entity( - e => - { - e.HasKey( - od => new { od.OrderID, od.ProductID }); - }); + e => e.HasKey(od => new { od.OrderID, od.ProductID })); modelBuilder.Entity().HasNoKey(); modelBuilder.Entity().HasNoKey(); diff --git a/test/EFCore.Specification.Tests/TestModels/Northwind/OrderQuery.cs b/test/EFCore.Specification.Tests/TestModels/Northwind/OrderQuery.cs index a3ea211e310..2bbd5fdfbab 100644 --- a/test/EFCore.Specification.Tests/TestModels/Northwind/OrderQuery.cs +++ b/test/EFCore.Specification.Tests/TestModels/Northwind/OrderQuery.cs @@ -12,9 +12,7 @@ public OrderQuery() } public OrderQuery(string customerID) - { - CustomerID = customerID; - } + => CustomerID = customerID; public string CustomerID { get; set; } diff --git a/test/EFCore.Specification.Tests/TestModels/Northwind/Product.cs b/test/EFCore.Specification.Tests/TestModels/Northwind/Product.cs index 3926568be96..ddde126b672 100644 --- a/test/EFCore.Specification.Tests/TestModels/Northwind/Product.cs +++ b/test/EFCore.Specification.Tests/TestModels/Northwind/Product.cs @@ -12,9 +12,7 @@ public class Product private int? _productId; public Product() - { - OrderDetails = []; - } + => OrderDetails = []; public int ProductID { diff --git a/test/EFCore.Specification.Tests/TestModels/SpatialModel/SpatialData.cs b/test/EFCore.Specification.Tests/TestModels/SpatialModel/SpatialData.cs index 79c37161a84..0492bb4077e 100644 --- a/test/EFCore.Specification.Tests/TestModels/SpatialModel/SpatialData.cs +++ b/test/EFCore.Specification.Tests/TestModels/SpatialModel/SpatialData.cs @@ -100,11 +100,7 @@ public static IReadOnlyList CreateGeoPointEntities() public static IReadOnlyList CreateLineStringEntities(GeometryFactory factory) => new[] { - new LineStringEntity - { - Id = 1, - LineString = factory.CreateLineString([new(0, 0), new(1, 0)]) - }, + new LineStringEntity { Id = 1, LineString = factory.CreateLineString([new Coordinate(0, 0), new Coordinate(1, 0)]) }, new LineStringEntity { Id = 2, LineString = null } }; @@ -128,8 +124,8 @@ public static IReadOnlyList CreateMultiLineStringEntities Id = 1, MultiLineString = factory.CreateMultiLineString( [ - factory.CreateLineString([new(0, 0), new(0, 1)]), - factory.CreateLineString([new(1, 0), new(1, 1)]) + factory.CreateLineString([new Coordinate(0, 0), new Coordinate(0, 1)]), + factory.CreateLineString([new Coordinate(1, 0), new Coordinate(1, 1)]) ]) }, new MultiLineStringEntity { Id = 2, MultiLineString = null } 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/TestUtilities/DataGenerator`.cs b/test/EFCore.Specification.Tests/TestUtilities/DataGenerator`.cs index 21b225c9c20..61d5ef762e0 100644 --- a/test/EFCore.Specification.Tests/TestUtilities/DataGenerator`.cs +++ b/test/EFCore.Specification.Tests/TestUtilities/DataGenerator`.cs @@ -7,8 +7,9 @@ namespace Microsoft.EntityFrameworkCore.TestUtilities; public class DataGenerator : IEnumerable { - public IEnumerator GetEnumerator() => - DataGenerator.GetCombinations(typeof(T)).AsEnumerable().GetEnumerator(); + public IEnumerator GetEnumerator() + => DataGenerator.GetCombinations(typeof(T)).AsEnumerable().GetEnumerator(); - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() + => GetEnumerator(); } diff --git a/test/EFCore.Specification.Tests/TestUtilities/DataGenerator``.cs b/test/EFCore.Specification.Tests/TestUtilities/DataGenerator``.cs index 00f5917b903..48dc2f14c44 100644 --- a/test/EFCore.Specification.Tests/TestUtilities/DataGenerator``.cs +++ b/test/EFCore.Specification.Tests/TestUtilities/DataGenerator``.cs @@ -7,8 +7,9 @@ namespace Microsoft.EntityFrameworkCore.TestUtilities; public class DataGenerator : IEnumerable { - public IEnumerator GetEnumerator() => - DataGenerator.GetCombinations(typeof(T1), typeof(T2)).AsEnumerable().GetEnumerator(); + public IEnumerator GetEnumerator() + => DataGenerator.GetCombinations(typeof(T1), typeof(T2)).AsEnumerable().GetEnumerator(); - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() + => GetEnumerator(); } diff --git a/test/EFCore.Specification.Tests/TestUtilities/ExpectedQueryRewritingVisitor.cs b/test/EFCore.Specification.Tests/TestUtilities/ExpectedQueryRewritingVisitor.cs index 678072fdc69..4bbaef6b333 100644 --- a/test/EFCore.Specification.Tests/TestUtilities/ExpectedQueryRewritingVisitor.cs +++ b/test/EFCore.Specification.Tests/TestUtilities/ExpectedQueryRewritingVisitor.cs @@ -3,7 +3,8 @@ namespace Microsoft.EntityFrameworkCore.TestUtilities; -public class ExpectedQueryRewritingVisitor(Dictionary<(Type, string), Func>? shadowPropertyMappings = null) : ExpressionVisitor +public class ExpectedQueryRewritingVisitor(Dictionary<(Type, string), Func>? shadowPropertyMappings = null) + : ExpressionVisitor { private static readonly MethodInfo _maybeDefaultIfEmpty = typeof(TestExtensions).GetMethod(nameof(TestExtensions.MaybeDefaultIfEmpty))!; @@ -17,7 +18,8 @@ private static readonly MethodInfo _getShadowPropertyValueMethodInfo private static readonly MethodInfo _maybeScalarNullableMethod; private static readonly MethodInfo _maybeScalarNonNullableMethod; - private readonly Dictionary<(Type, string), Func> _shadowPropertyMappings = shadowPropertyMappings ?? new Dictionary<(Type, string), Func>(); + private readonly Dictionary<(Type, string), Func> _shadowPropertyMappings = + shadowPropertyMappings ?? new Dictionary<(Type, string), Func>(); private bool _negated; diff --git a/test/EFCore.Specification.Tests/TestUtilities/ListLoggerFactory.cs b/test/EFCore.Specification.Tests/TestUtilities/ListLoggerFactory.cs index e1ed535fa12..f4acf95c785 100644 --- a/test/EFCore.Specification.Tests/TestUtilities/ListLoggerFactory.cs +++ b/test/EFCore.Specification.Tests/TestUtilities/ListLoggerFactory.cs @@ -18,7 +18,7 @@ public ListLoggerFactory() public List<(LogLevel Level, EventId Id, string? Message, object? State, Exception? Exception)> Log => Logger.LoggedEvents; - protected ListLogger Logger { get; set; } = new ListLogger(); + protected ListLogger Logger { get; set; } = new(); public virtual void Clear() => Logger.Clear(); @@ -149,7 +149,8 @@ public bool IsEnabled(LogLevel logLevel) public IDisposable? BeginScope(object state) => null; - public IDisposable? BeginScope(TState state) where TState : notnull + public IDisposable? BeginScope(TState state) + where TState : notnull => null; public void SuspendTestOutput(bool writeAllPreviousMessages = true) diff --git a/test/EFCore.Specification.Tests/TestUtilities/MetadataExtensions.cs b/test/EFCore.Specification.Tests/TestUtilities/MetadataExtensions.cs index b9b0bb96db8..2c0b76ad569 100644 --- a/test/EFCore.Specification.Tests/TestUtilities/MetadataExtensions.cs +++ b/test/EFCore.Specification.Tests/TestUtilities/MetadataExtensions.cs @@ -1,8 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.EntityFrameworkCore.Metadata.Internal; - namespace Microsoft.EntityFrameworkCore.TestUtilities; public static class MetadataExtensions diff --git a/test/EFCore.Specification.Tests/TestUtilities/ModelAsserter.cs b/test/EFCore.Specification.Tests/TestUtilities/ModelAsserter.cs index dd6699e7a09..b9f4f93cc71 100644 --- a/test/EFCore.Specification.Tests/TestUtilities/ModelAsserter.cs +++ b/test/EFCore.Specification.Tests/TestUtilities/ModelAsserter.cs @@ -3,6 +3,7 @@ using System.ComponentModel; using Microsoft.EntityFrameworkCore.Metadata.Internal; +using Index = Microsoft.EntityFrameworkCore.Metadata.Internal.Index; namespace Microsoft.EntityFrameworkCore.TestUtilities; @@ -54,7 +55,8 @@ public virtual void AssertEqual( Assert.Equal(expected.GetPropertyAccessMode(), actual.GetPropertyAccessMode()); } }, - () => AssertEqual(expected.GetEntityTypes(), actual.GetEntityTypes(), + () => AssertEqual( + expected.GetEntityTypes(), actual.GetEntityTypes(), assertOrder: true, compareAnnotations: compareMemberAnnotations), () => Assert.Equal(expectedAnnotations, actualAnnotations, TestAnnotationComparer.Instance)); } @@ -75,7 +77,8 @@ public virtual void AssertEqual( expectedEntityTypes = expectedEntityTypes.Select(x => x); } - Assert.Equal(expectedEntityTypes, actualEntityTypes, + Assert.Equal( + expectedEntityTypes, actualEntityTypes, (expected, actual) => AssertEqual( expected, @@ -86,9 +89,13 @@ public virtual void AssertEqual( compareMemberAnnotations: compareAnnotations)); } - public virtual bool AssertEqual(IReadOnlyEntityType? expected, IReadOnlyEntityType? actual, - IEnumerable expectedAnnotations, IEnumerable actualAnnotations, - bool compareBackreferences = false, bool compareMemberAnnotations = false) + public virtual bool AssertEqual( + IReadOnlyEntityType? expected, + IReadOnlyEntityType? actual, + IEnumerable expectedAnnotations, + IEnumerable actualAnnotations, + bool compareBackreferences = false, + bool compareMemberAnnotations = false) { if (expected == null) { @@ -135,19 +142,26 @@ public virtual bool AssertEqual(IReadOnlyEntityType? expected, IReadOnlyEntityTy () => Assert.Equal(expected.GetDiscriminatorPropertyName(), actual.GetDiscriminatorPropertyName()), () => Assert.Equal(expected.GetDiscriminatorValue(), actual.GetDiscriminatorValue()), () => Assert.Equal(expected.GetIsDiscriminatorMappingComplete(), actual.GetIsDiscriminatorMappingComplete()), - () => AssertEqual(expected.GetProperties(), actual.GetProperties(), + () => AssertEqual( + expected.GetProperties(), actual.GetProperties(), assertOrder: true, compareAnnotations: compareMemberAnnotations), - () => AssertEqual(expected.GetServiceProperties(), actual.GetServiceProperties(), + () => AssertEqual( + expected.GetServiceProperties(), actual.GetServiceProperties(), assertOrder: true, compareAnnotations: compareMemberAnnotations), - () => AssertEqual(expected.GetSkipNavigations(), actual.GetSkipNavigations(), + () => AssertEqual( + expected.GetSkipNavigations(), actual.GetSkipNavigations(), assertOrder: true, compareAnnotations: compareMemberAnnotations), - () => AssertEqual(expected.GetForeignKeys(), actual.GetForeignKeys(), + () => AssertEqual( + expected.GetForeignKeys(), actual.GetForeignKeys(), assertOrder: true, compareAnnotations: compareMemberAnnotations), - () => AssertEqual(expected.GetKeys(), actual.GetKeys(), + () => AssertEqual( + expected.GetKeys(), actual.GetKeys(), assertOrder: true, compareAnnotations: compareMemberAnnotations), - () => AssertEqual(expected.GetIndexes(), actual.GetIndexes(), + () => AssertEqual( + expected.GetIndexes(), actual.GetIndexes(), assertOrder: true, compareAnnotations: compareMemberAnnotations), - () => AssertEqual(expected.GetComplexProperties(), actual.GetComplexProperties(), + () => AssertEqual( + expected.GetComplexProperties(), actual.GetComplexProperties(), assertOrder: true, compareAnnotations: compareMemberAnnotations), () => { @@ -168,8 +182,11 @@ public virtual bool AssertEqual(IReadOnlyEntityType? expected, IReadOnlyEntityTy return true; } - public virtual bool AssertEqual(IReadOnlyComplexType expected, IReadOnlyComplexType actual, - IEnumerable expectedAnnotations, IEnumerable actualAnnotations, + public virtual bool AssertEqual( + IReadOnlyComplexType expected, + IReadOnlyComplexType actual, + IEnumerable expectedAnnotations, + IEnumerable actualAnnotations, bool compareBackreferences = false, bool compareMemberAnnotations = false) { @@ -189,9 +206,11 @@ public virtual bool AssertEqual(IReadOnlyComplexType expected, IReadOnlyComplexT } }, () => Assert.Equal(expected.GetChangeTrackingStrategy(), actual.GetChangeTrackingStrategy()), - () => AssertEqual(expected.GetProperties(), actual.GetProperties(), + () => AssertEqual( + expected.GetProperties(), actual.GetProperties(), assertOrder: true, compareAnnotations: compareMemberAnnotations), - () => AssertEqual(expected.GetComplexProperties(), actual.GetComplexProperties(), + () => AssertEqual( + expected.GetComplexProperties(), actual.GetComplexProperties(), assertOrder: true, compareAnnotations: compareMemberAnnotations), () => { @@ -221,7 +240,8 @@ public virtual void AssertEqual( expectedProperties = expectedProperties.Select(x => x); } - Assert.Equal(expectedProperties, actualProperties, + Assert.Equal( + expectedProperties, actualProperties, (expected, actual) => AssertEqual( expected, @@ -232,8 +252,11 @@ public virtual void AssertEqual( compareMemberAnnotations: compareAnnotations)); } - public virtual bool AssertEqual(IReadOnlyComplexProperty? expected, IReadOnlyComplexProperty? actual, - IEnumerable expectedAnnotations, IEnumerable actualAnnotations, + public virtual bool AssertEqual( + IReadOnlyComplexProperty? expected, + IReadOnlyComplexProperty? actual, + IEnumerable expectedAnnotations, + IEnumerable actualAnnotations, bool compareBackreferences = false, bool compareMemberAnnotations = false) { @@ -258,7 +281,8 @@ public virtual bool AssertEqual(IReadOnlyComplexProperty? expected, IReadOnlyCom () => Assert.Equal(expected.IsNullable, actual.IsNullable), () => Assert.Equal(expected.Sentinel, actual.Sentinel), () => Assert.Equal(expected.GetPropertyAccessMode(), actual.GetPropertyAccessMode()), - () => AssertEqual(expected.ComplexType, actual.ComplexType, + () => AssertEqual( + expected.ComplexType, actual.ComplexType, compareMemberAnnotations ? expected.GetAnnotations() : Enumerable.Empty(), compareMemberAnnotations ? actual.GetAnnotations() : Enumerable.Empty(), compareBackreferences: false, @@ -291,7 +315,8 @@ public virtual void AssertEqual( expectedProperties = expectedProperties.Select(x => x); } - Assert.Equal(expectedProperties, actualProperties, + Assert.Equal( + expectedProperties, actualProperties, (expected, actual) => AssertEqual( expected, @@ -422,7 +447,8 @@ public virtual void AssertEqual( expectedProperties = expectedProperties.Select(x => x); } - Assert.Equal(expectedProperties, actualProperties, + Assert.Equal( + expectedProperties, actualProperties, (expected, actual) => AssertEqual( expected, @@ -432,8 +458,11 @@ public virtual void AssertEqual( compareBackreferences: false)); } - public virtual bool AssertEqual(IReadOnlyServiceProperty? expected, IReadOnlyServiceProperty? actual, - IEnumerable expectedAnnotations, IEnumerable actualAnnotations, + public virtual bool AssertEqual( + IReadOnlyServiceProperty? expected, + IReadOnlyServiceProperty? actual, + IEnumerable expectedAnnotations, + IEnumerable actualAnnotations, bool compareBackreferences = false) { if (expected == null) @@ -484,7 +513,8 @@ public virtual void AssertEqual( expectedNavigations = expectedNavigations.Select(x => x); } - Assert.Equal(expectedNavigations, actualNavigations, + Assert.Equal( + expectedNavigations, actualNavigations, (expected, actual) => AssertEqual( expected, @@ -494,8 +524,11 @@ public virtual void AssertEqual( compareBackreferences: false)); } - public virtual bool AssertEqual(IReadOnlyNavigation? expected, IReadOnlyNavigation? actual, - IEnumerable expectedAnnotations, IEnumerable actualAnnotations, + public virtual bool AssertEqual( + IReadOnlyNavigation? expected, + IReadOnlyNavigation? actual, + IEnumerable expectedAnnotations, + IEnumerable actualAnnotations, bool compareBackreferences = false) { if (expected == null) @@ -563,7 +596,8 @@ public virtual void AssertEqual( expectedNavigations = expectedNavigations.Select(x => x); } - Assert.Equal(expectedNavigations, actualNavigations, + Assert.Equal( + expectedNavigations, actualNavigations, (expected, actual) => AssertEqual( expected, @@ -573,8 +607,11 @@ public virtual void AssertEqual( compareBackreferences: false)); } - public virtual bool AssertEqual(IReadOnlySkipNavigation expected, IReadOnlySkipNavigation actual, - IEnumerable expectedAnnotations, IEnumerable actualAnnotations, + public virtual bool AssertEqual( + IReadOnlySkipNavigation expected, + IReadOnlySkipNavigation actual, + IEnumerable expectedAnnotations, + IEnumerable actualAnnotations, bool compareBackreferences = false) { if (expected == null) @@ -642,7 +679,8 @@ public virtual void AssertEqual( expectedKeys = expectedKeys.Select(x => x); } - Assert.Equal(expectedKeys, actualKeys, + Assert.Equal( + expectedKeys, actualKeys, (expected, actual) => AssertEqual( expected, @@ -696,7 +734,8 @@ public virtual bool AssertEqual( { if (compareBackreferences) { - Assert.Equal(expected.GetReferencingForeignKeys().ToList(), actual.GetReferencingForeignKeys(), ForeignKeyComparer.Instance); + Assert.Equal( + expected.GetReferencingForeignKeys().ToList(), actual.GetReferencingForeignKeys(), ForeignKeyComparer.Instance); } }, () => Assert.Equal(expectedAnnotations, actualAnnotations, TestAnnotationComparer.Instance)); @@ -720,7 +759,8 @@ public virtual void AssertEqual( expectedForeignKey = expectedForeignKey.Select(x => x); } - Assert.Equal(expectedForeignKey, actualForeignKey, + Assert.Equal( + expectedForeignKey, actualForeignKey, (expected, actual) => AssertEqual( expected, @@ -768,7 +808,8 @@ public virtual bool AssertEqual( () => Assert.Equal(expected.IsRequiredDependent, actual.IsRequiredDependent), () => Assert.Equal(expected.IsUnique, actual.IsUnique), () => Assert.Equal(expected.DeleteBehavior, actual.DeleteBehavior), - () => AssertEqual(expected.DependentToPrincipal, actual.DependentToPrincipal, + () => AssertEqual( + expected.DependentToPrincipal, actual.DependentToPrincipal, compareMemberAnnotations ? expected.DependentToPrincipal?.GetAnnotations() ?? Enumerable.Empty() : Enumerable.Empty(), @@ -776,7 +817,8 @@ public virtual bool AssertEqual( ? actual.DependentToPrincipal?.GetAnnotations() ?? Enumerable.Empty() : Enumerable.Empty(), compareBackreferences: true), - () => AssertEqual(expected.PrincipalToDependent, actual.PrincipalToDependent, + () => AssertEqual( + expected.PrincipalToDependent, actual.PrincipalToDependent, compareMemberAnnotations ? expected.PrincipalToDependent?.GetAnnotations() ?? Enumerable.Empty() : Enumerable.Empty(), @@ -812,7 +854,8 @@ public virtual void AssertEqual( expectedIndex = expectedIndex.Select(x => x); } - Assert.Equal(expectedIndex, actualIndex, + Assert.Equal( + expectedIndex, actualIndex, (expected, actual) => AssertEqual( expected, @@ -842,7 +885,7 @@ public virtual bool AssertEqual( expectedAnnotations = expectedAnnotations.Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name)); actualAnnotations = actualAnnotations.Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name)); - var designTime = expected is Metadata.Internal.Index && actual is Metadata.Internal.Index; + var designTime = expected is Index && actual is Index; Assert.Multiple( () => @@ -922,12 +965,13 @@ public virtual IReadOnlyModel Clone(IReadOnlyModel model) { var targetEntityType = clonedEntityType.Value; var otherEntityType = targetEntityType.Model.FindEntityType(skipNavigation.TargetEntityType.Name)!; - Copy(skipNavigation, clonedEntityType.Value.AddSkipNavigation( - skipNavigation.Name, - skipNavigation.GetIdentifyingMemberInfo(), - otherEntityType, - skipNavigation.IsCollection, - skipNavigation.IsOnDependent)); + Copy( + skipNavigation, clonedEntityType.Value.AddSkipNavigation( + skipNavigation.Name, + skipNavigation.GetIdentifyingMemberInfo(), + otherEntityType, + skipNavigation.IsCollection, + skipNavigation.IsOnDependent)); } } @@ -965,24 +1009,27 @@ protected virtual void Copy(IReadOnlyEntityType sourceEntityType, IMutableEntity foreach (var property in sourceEntityType.GetDeclaredComplexProperties()) { - Copy(property, targetEntityType.AddComplexProperty( - property.Name, - property.ClrType, - property.ComplexType.ClrType, - property.ComplexType.Name, - collection: property.IsCollection)); + Copy( + property, targetEntityType.AddComplexProperty( + property.Name, + property.ClrType, + property.ComplexType.ClrType, + property.ComplexType.Name, + collection: property.IsCollection)); } foreach (var property in sourceEntityType.GetDeclaredServiceProperties()) { - Copy(property, targetEntityType.AddServiceProperty( - property.GetIdentifyingMemberInfo()!, property.ClrType)); + Copy( + property, targetEntityType.AddServiceProperty( + property.GetIdentifyingMemberInfo()!, property.ClrType)); } foreach (var key in sourceEntityType.GetDeclaredKeys()) { - Copy(key, targetEntityType.AddKey( - key.Properties.Select(p => targetEntityType.FindProperty(p.Name)!).ToList())); + Copy( + key, targetEntityType.AddKey( + key.Properties.Select(p => targetEntityType.FindProperty(p.Name)!).ToList())); } foreach (var index in sourceEntityType.GetDeclaredIndexes()) @@ -1003,6 +1050,7 @@ protected virtual void Copy(IReadOnlyProperty sourceProperty, IMutableProperty t { targetProperty.FieldInfo = fieldInfo; } + targetProperty.IsNullable = sourceProperty.IsNullable; targetProperty.IsConcurrencyToken = sourceProperty.IsConcurrencyToken; targetProperty.Sentinel = sourceProperty.Sentinel; @@ -1025,6 +1073,7 @@ protected virtual void Copy(IReadOnlyServiceProperty sourceProperty, IMutableSer { targetProperty.FieldInfo = fieldInfo; } + targetProperty.SetPropertyAccessMode(sourceProperty.GetPropertyAccessMode()); targetProperty.AddAnnotations(sourceProperty.GetAnnotations().Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name))); } @@ -1035,6 +1084,7 @@ protected virtual void Copy(IReadOnlyComplexProperty sourceProperty, IMutableCom { targetProperty.FieldInfo = fieldInfo; } + targetProperty.IsNullable = sourceProperty.IsNullable; targetProperty.SetPropertyAccessMode(sourceProperty.GetPropertyAccessMode()); targetProperty.AddAnnotations(sourceProperty.GetAnnotations().Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name))); @@ -1053,12 +1103,13 @@ protected virtual void Copy(IReadOnlyComplexType sourceComplexType, IMutableComp foreach (var property in sourceComplexType.GetDeclaredComplexProperties()) { - Copy(property, targetComplexType.AddComplexProperty( - property.Name, - property.ClrType, - property.ComplexType.ClrType, - property.ComplexType.Name, - collection: property.IsCollection)); + Copy( + property, targetComplexType.AddComplexProperty( + property.Name, + property.ClrType, + property.ComplexType.ClrType, + property.ComplexType.Name, + collection: property.IsCollection)); } targetComplexType.AddAnnotations(sourceComplexType.GetAnnotations().Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name))); @@ -1104,8 +1155,9 @@ protected virtual void Copy(IReadOnlyForeignKey sourceForeignKey, IMutableForeig Copy(sourceForeignKey.PrincipalToDependent, clonedNavigation!); } - targetForeignKey.AddAnnotations(sourceForeignKey.GetAnnotations() - .Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name))); + targetForeignKey.AddAnnotations( + sourceForeignKey.GetAnnotations() + .Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name))); } protected virtual void Copy(IReadOnlyNavigation sourceNavigation, IMutableNavigation targetNavigation) @@ -1118,8 +1170,9 @@ protected virtual void Copy(IReadOnlyNavigation sourceNavigation, IMutableNaviga targetNavigation.SetPropertyAccessMode(sourceNavigation.GetPropertyAccessMode()); targetNavigation.SetIsEagerLoaded(sourceNavigation.IsEagerLoaded); targetNavigation.SetLazyLoadingEnabled(sourceNavigation.LazyLoadingEnabled); - targetNavigation.AddAnnotations(sourceNavigation.GetAnnotations() - .Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name))); + targetNavigation.AddAnnotations( + sourceNavigation.GetAnnotations() + .Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name))); } protected virtual void Copy(IReadOnlySkipNavigation sourceNavigation, IMutableSkipNavigation targetNavigation) diff --git a/test/EFCore.Specification.Tests/TestUtilities/TestAnnotationComparer.cs b/test/EFCore.Specification.Tests/TestUtilities/TestAnnotationComparer.cs index 12fc99b8c49..55985e8067b 100644 --- a/test/EFCore.Specification.Tests/TestUtilities/TestAnnotationComparer.cs +++ b/test/EFCore.Specification.Tests/TestUtilities/TestAnnotationComparer.cs @@ -31,9 +31,10 @@ public bool Equals(IAnnotation? x, IAnnotation? y) return y == null; } - return y != null && (x.Name == y.Name - && (x.Name == CoreAnnotationNames.ValueGeneratorFactory - || CompareAnnotations())); + return y != null + && (x.Name == y.Name + && (x.Name == CoreAnnotationNames.ValueGeneratorFactory + || CompareAnnotations())); bool CompareAnnotations() { @@ -46,7 +47,7 @@ bool CompareAnnotations() return false; } - for (int i = 0; i < xList.Count; i++) + for (var i = 0; i < xList.Count; i++) { if (!Equals(xList[i], yList[i])) { diff --git a/test/EFCore.Specification.Tests/TestUtilities/TestHelpers.cs b/test/EFCore.Specification.Tests/TestUtilities/TestHelpers.cs index d00ba6ec514..bfad3f6333a 100644 --- a/test/EFCore.Specification.Tests/TestUtilities/TestHelpers.cs +++ b/test/EFCore.Specification.Tests/TestUtilities/TestHelpers.cs @@ -5,7 +5,6 @@ using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; using Microsoft.EntityFrameworkCore.Design.Internal; using Microsoft.EntityFrameworkCore.Internal; -using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.Extensions.DependencyInjection.Extensions; @@ -432,7 +431,8 @@ public override IModel FinalizeModel() public IModel FinalizeModel(bool designTime = false, bool skipValidation = false) { - var designTimeModel = _modelRuntimeInitializer.Initialize((IModel)Model, designTime: true, skipValidation ? null : _validationLogger); + var designTimeModel = _modelRuntimeInitializer.Initialize( + (IModel)Model, designTime: true, skipValidation ? null : _validationLogger); var runtimeModel = (IModel)designTimeModel.FindRuntimeAnnotationValue(CoreAnnotationNames.ReadOnlyModel)!; return designTime ? designTimeModel : runtimeModel; } diff --git a/test/EFCore.Specification.Tests/TestUtilities/TestLogger.cs b/test/EFCore.Specification.Tests/TestUtilities/TestLogger.cs index 9af4c2282a6..48fb28042ae 100644 --- a/test/EFCore.Specification.Tests/TestUtilities/TestLogger.cs +++ b/test/EFCore.Specification.Tests/TestUtilities/TestLogger.cs @@ -23,7 +23,8 @@ public ILogger Logger public bool IsEnabled(LogLevel logLevel) => EnabledFor == logLevel; - public IDisposable? BeginScope(TState state) where TState : notnull + public IDisposable? BeginScope(TState state) + where TState : notnull => null; public void Log( diff --git a/test/EFCore.Specification.Tests/TestUtilities/TestLoggerFactory.cs b/test/EFCore.Specification.Tests/TestUtilities/TestLoggerFactory.cs index c0f51d02a81..d8ae3c7b541 100644 --- a/test/EFCore.Specification.Tests/TestUtilities/TestLoggerFactory.cs +++ b/test/EFCore.Specification.Tests/TestUtilities/TestLoggerFactory.cs @@ -5,7 +5,7 @@ namespace Microsoft.EntityFrameworkCore.TestUtilities; public class TestLoggerFactory(LoggingDefinitions definitions) : ILoggerFactory { - public TestLogger Logger { get; } = new TestLogger(definitions); + public TestLogger Logger { get; } = new(definitions); public LogLevel? LoggedAt => Logger.LoggedAt; diff --git a/test/EFCore.Specification.Tests/TestUtilities/TestStore.cs b/test/EFCore.Specification.Tests/TestUtilities/TestStore.cs index 6884b6ac5d3..035197a2d59 100644 --- a/test/EFCore.Specification.Tests/TestUtilities/TestStore.cs +++ b/test/EFCore.Specification.Tests/TestUtilities/TestStore.cs @@ -5,7 +5,7 @@ namespace Microsoft.EntityFrameworkCore.TestUtilities; -public abstract class TestStore(string name, bool shared) : IDisposable +public abstract class TestStore(string name, bool shared) : IAsyncDisposable { private static readonly TestStoreIndex GlobalTestStoreIndex = new(); public IServiceProvider? ServiceProvider { get; protected set; } @@ -83,15 +83,8 @@ protected virtual DbContext CreateDefaultContext() protected virtual TestStoreIndex GetTestStoreIndex(IServiceProvider? serviceProvider) => GlobalTestStoreIndex; - public virtual void Dispose() - { - } - - public virtual Task DisposeAsync() - { - Dispose(); - return Task.CompletedTask; - } + public virtual ValueTask DisposeAsync() + => default; private static readonly SemaphoreSlim _transactionSyncRoot = new(1); @@ -116,9 +109,7 @@ public static IDisposable CreateTransactionScope(bool useTransaction = true) private class DistributedTransactionListener : IDisposable { public DistributedTransactionListener() - { - TransactionManager.DistributedTransactionStarted += DistributedTransactionStarted; - } + => TransactionManager.DistributedTransactionStarted += DistributedTransactionStarted; private void DistributedTransactionStarted(object? sender, TransactionEventArgs e) => Assert.Fail("Distributed transaction started"); diff --git a/test/EFCore.Specification.Tests/TestUtilities/TestValueConverterComparer.cs b/test/EFCore.Specification.Tests/TestUtilities/TestValueConverterComparer.cs index 6a3f95a7cdc..2d9d43bbcba 100644 --- a/test/EFCore.Specification.Tests/TestUtilities/TestValueConverterComparer.cs +++ b/test/EFCore.Specification.Tests/TestUtilities/TestValueConverterComparer.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable PossibleNullReferenceException + namespace Microsoft.EntityFrameworkCore.TestUtilities; public class TestValueConverterComparer : IEqualityComparer @@ -18,7 +19,7 @@ public bool Equals(ValueConverter? x, ValueConverter? y) : y == null ? false : ExpressionEqualityComparer.Instance.Equals(x.ConvertFromProviderExpression, y.ConvertFromProviderExpression) - && ExpressionEqualityComparer.Instance.Equals(x.ConvertToProviderExpression, y.ConvertToProviderExpression); + && ExpressionEqualityComparer.Instance.Equals(x.ConvertToProviderExpression, y.ConvertToProviderExpression); public int GetHashCode(ValueConverter obj) => ExpressionEqualityComparer.Instance.GetHashCode(obj.ConvertFromProviderExpression) diff --git a/test/EFCore.Specification.Tests/TestUtilities/Xunit/SkipOnCiConditionAttribute.cs b/test/EFCore.Specification.Tests/TestUtilities/Xunit/SkipOnCiConditionAttribute.cs new file mode 100644 index 00000000000..3a018bd3fa8 --- /dev/null +++ b/test/EFCore.Specification.Tests/TestUtilities/Xunit/SkipOnCiConditionAttribute.cs @@ -0,0 +1,15 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.TestUtilities.Xunit; + +[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly)] +public sealed class SkipOnCiConditionAttribute : Attribute, ITestCondition +{ + public ValueTask IsMetAsync() + => new( + Environment.GetEnvironmentVariable("PIPELINE_WORKSPACE") == null + && Environment.GetEnvironmentVariable("GITHUB_RUN_ID") == null); + + public string SkipReason { get; set; } = "Tests not reliable on C.I."; +} diff --git a/test/EFCore.Specification.Tests/Update/UpdatesTestBase.cs b/test/EFCore.Specification.Tests/Update/UpdatesTestBase.cs index bf3395d59b2..f0c0d83e3d7 100644 --- a/test/EFCore.Specification.Tests/Update/UpdatesTestBase.cs +++ b/test/EFCore.Specification.Tests/Update/UpdatesTestBase.cs @@ -863,7 +863,6 @@ protected class Muffin : Baked { public required string MuffinName { get; set; } public Top Top { get; set; } = null!; - } protected class Tin @@ -936,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.Specification.Tests/WithConstructorsTestBase.cs b/test/EFCore.Specification.Tests/WithConstructorsTestBase.cs index 822e188a925..018a307eef4 100644 --- a/test/EFCore.Specification.Tests/WithConstructorsTestBase.cs +++ b/test/EFCore.Specification.Tests/WithConstructorsTestBase.cs @@ -797,9 +797,7 @@ public Post( string content, Blog blog = null) : this(0, title, content) - { - Blog = blog; - } + => Blog = blog; public string Title { get; } public string Content { get; set; } @@ -890,9 +888,7 @@ public HasEntityType() } private HasEntityType(IEntityType entityType) - { - _entityType = entityType; - } + => _entityType = entityType; public int Id { get; set; } @@ -921,9 +917,7 @@ public HasEntityTypePc() } private HasEntityTypePc(IEntityType entityType) - { - _entityType = entityType; - } + => _entityType = entityType; public int Id { get; set; } @@ -956,9 +950,7 @@ public HasStateManager() } private HasStateManager(IStateManager stateManager) - { - _stateManager = stateManager; - } + => _stateManager = stateManager; public int Id { get; set; } @@ -988,9 +980,7 @@ public HasStateManagerPc() } private HasStateManagerPc(IStateManager stateManager) - { - _stateManager = stateManager; - } + => _stateManager = stateManager; public int Id { get; set; } @@ -1024,9 +1014,7 @@ public LazyBlog() } private LazyBlog(ILazyLoader loader) - { - _loader = loader; - } + => _loader = loader; public int Id { get; set; } @@ -1049,9 +1037,7 @@ public LazyPost() } private LazyPost(ILazyLoader loader) - { - _loader = loader; - } + => _loader = loader; public int Id { get; set; } @@ -1231,9 +1217,7 @@ public LazyPcBlog() } private LazyPcBlog(ILazyLoader loader) - { - _loader = loader; - } + => _loader = loader; private ILazyLoader Loader { @@ -1270,9 +1254,7 @@ public LazyPcPost() } private LazyPcPost(ILazyLoader loader) - { - _loader = loader; - } + => _loader = loader; private ILazyLoader Loader { @@ -1309,9 +1291,7 @@ public LazyPcsBlog() } private LazyPcsBlog(Action lazyLoader) - { - _loader = lazyLoader; - } + => _loader = lazyLoader; private Action LazyLoader { @@ -1348,9 +1328,7 @@ public LazyPcsPost() } private LazyPcsPost(Action lazyLoader) - { - _loader = lazyLoader; - } + => _loader = lazyLoader; private Action LazyLoader { @@ -1390,9 +1368,7 @@ public LazyPocoBlog() } private LazyPocoBlog(Action lazyLoader) - { - _loader = lazyLoader; - } + => _loader = lazyLoader; public int Id { get; set; } @@ -1415,9 +1391,7 @@ public LazyPocoPost() } private LazyPocoPost(Action lazyLoader) - { - _loader = lazyLoader; - } + => _loader = lazyLoader; public int Id { get; set; } @@ -1440,9 +1414,7 @@ public LazyAsyncPocoBlog() } private LazyAsyncPocoBlog(Func lazyLoader) - { - _loader = lazyLoader; - } + => _loader = lazyLoader; public int Id { get; set; } @@ -1471,9 +1443,7 @@ public LazyAsyncPocoPost() } private LazyAsyncPocoPost(Func lazyLoader) - { - _loader = lazyLoader; - } + => _loader = lazyLoader; public int Id { get; set; } @@ -1499,9 +1469,7 @@ public LazyAsyncBlog() } private LazyAsyncBlog(ILazyLoader loader) - { - _loader = loader; - } + => _loader = loader; public int Id { get; set; } @@ -1530,9 +1498,7 @@ public LazyAsyncPost() } private LazyAsyncPost(ILazyLoader loader) - { - _loader = loader; - } + => _loader = loader; public int Id { get; set; } diff --git a/test/EFCore.SqlServer.FunctionalTests/BuiltInDataTypesSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/BuiltInDataTypesSqlServerTest.cs index 0eb93759021..bcb427626aa 100644 --- a/test/EFCore.SqlServer.FunctionalTests/BuiltInDataTypesSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/BuiltInDataTypesSqlServerTest.cs @@ -15,7 +15,7 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -[SqlServerCondition(SqlServerCondition.IsNotSqlAzure | SqlServerCondition.SupportsUtf8)] +[SqlServerCondition(SqlServerCondition.IsNotAzureSql | SqlServerCondition.SupportsUtf8)] public class BuiltInDataTypesSqlServerTest : BuiltInDataTypesTestBase { private static readonly string _eol = Environment.NewLine; diff --git a/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/ComplexTypeBulkUpdatesSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/ComplexTypeBulkUpdatesSqlServerTest.cs index 1c719aa04e4..2f6c2b967ee 100644 --- a/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/ComplexTypeBulkUpdatesSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/ComplexTypeBulkUpdatesSqlServerTest.cs @@ -5,7 +5,9 @@ namespace Microsoft.EntityFrameworkCore.BulkUpdates; #nullable disable -public class ComplexTypeBulkUpdatesSqlServerTest(ComplexTypeBulkUpdatesSqlServerTest.ComplexTypeBulkUpdatesSqlServerFixture fixture, ITestOutputHelper testOutputHelper) : ComplexTypeBulkUpdatesRelationalTestBase< +public class ComplexTypeBulkUpdatesSqlServerTest( + ComplexTypeBulkUpdatesSqlServerTest.ComplexTypeBulkUpdatesSqlServerFixture fixture, + ITestOutputHelper testOutputHelper) : ComplexTypeBulkUpdatesRelationalTestBase< ComplexTypeBulkUpdatesSqlServerTest.ComplexTypeBulkUpdatesSqlServerFixture>(fixture, testOutputHelper) { public override async Task Delete_entity_type_with_complex_type(bool async) diff --git a/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesSqlServerTest.cs index 81b06f363b9..0974740ebed 100644 --- a/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesSqlServerTest.cs @@ -192,6 +192,37 @@ FROM [Orders] AS [o] """); } + public override async Task Delete_with_view_mapping(bool async) + { + await base.Delete_with_view_mapping(async); + + AssertSql( + """ +DELETE FROM [b] +FROM [Blogs] AS [b] +"""); + } + + public override async Task Update_with_view_mapping(bool async) + { + await base.Update_with_view_mapping(async); + + AssertSql( + """ +UPDATE [b] +SET [b].[Data] = N'Updated' +FROM [Blogs] AS [b] +"""); + } + + public override async Task Update_complex_type_with_view_mapping(bool async) + { + await base.Update_complex_type_with_view_mapping(async); + + // #34706 + AssertSql(); + } + private void AssertSql(params string[] expected) => TestSqlLoggerFactory.AssertBaseline(expected); diff --git a/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqlServerTest.cs index 27dd7719563..fd52c737309 100644 --- a/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqlServerTest.cs @@ -7,7 +7,8 @@ namespace Microsoft.EntityFrameworkCore.BulkUpdates; public class NorthwindBulkUpdatesSqlServerTest( NorthwindBulkUpdatesSqlServerFixture fixture, - ITestOutputHelper testOutputHelper) : NorthwindBulkUpdatesRelationalTestBase>(fixture, testOutputHelper) + ITestOutputHelper testOutputHelper) + : NorthwindBulkUpdatesRelationalTestBase>(fixture, testOutputHelper) { [ConditionalFact] public virtual void Check_all_tests_overridden() @@ -1035,7 +1036,7 @@ public override async Task Update_Where_set_property_plus_parameter(bool async) await base.Update_Where_set_property_plus_parameter(async); AssertExecuteUpdateSql( -""" + """ @__value_0='Abc' (Size = 4000) UPDATE [c] diff --git a/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/TPTInheritanceBulkUpdatesSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/TPTInheritanceBulkUpdatesSqlServerTest.cs index e047c9b138d..42168ca6a4f 100644 --- a/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/TPTInheritanceBulkUpdatesSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/TPTInheritanceBulkUpdatesSqlServerTest.cs @@ -9,9 +9,7 @@ public class TPTInheritanceBulkUpdatesSqlServerTest : TPTInheritanceBulkUpdatesT { public TPTInheritanceBulkUpdatesSqlServerTest(TPTInheritanceBulkUpdatesSqlServerFixture fixture, ITestOutputHelper testOutputHelper) : base(fixture, testOutputHelper) - { - ClearLog(); - } + => ClearLog(); [ConditionalFact] public virtual void Check_all_tests_overridden() diff --git a/test/EFCore.SqlServer.FunctionalTests/ComplexTypesTrackingSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/ComplexTypesTrackingSqlServerTest.cs index fe8535e292f..87f88713b7c 100644 --- a/test/EFCore.SqlServer.FunctionalTests/ComplexTypesTrackingSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/ComplexTypesTrackingSqlServerTest.cs @@ -6,8 +6,8 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable public class ComplexTypesTrackingSqlServerTest( - ComplexTypesTrackingSqlServerTest.SqlServerFixture fixture, - ITestOutputHelper testOutputHelper) + ComplexTypesTrackingSqlServerTest.SqlServerFixture fixture, + ITestOutputHelper testOutputHelper) : ComplexTypesTrackingSqlServerTestBase(fixture, testOutputHelper) { public class SqlServerFixture : SqlServerFixtureBase @@ -18,8 +18,8 @@ protected override string StoreName } public class ComplexTypesTrackingProxiesSqlServerTest( - ComplexTypesTrackingProxiesSqlServerTest.SqlServerFixture fixture, - ITestOutputHelper testOutputHelper) + ComplexTypesTrackingProxiesSqlServerTest.SqlServerFixture fixture, + ITestOutputHelper testOutputHelper) : ComplexTypesTrackingSqlServerTestBase(fixture, testOutputHelper) { // Fields can't be proxied diff --git a/test/EFCore.SqlServer.FunctionalTests/CompositeKeyEndToEndSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/CompositeKeyEndToEndSqlServerTest.cs index 3cdebfb1688..7ce2175182b 100644 --- a/test/EFCore.SqlServer.FunctionalTests/CompositeKeyEndToEndSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/CompositeKeyEndToEndSqlServerTest.cs @@ -5,8 +5,9 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class CompositeKeyEndToEndSqlServerTest(CompositeKeyEndToEndSqlServerTest.CompositeKeyEndToEndSqlServerFixture fixture) : CompositeKeyEndToEndTestBase< - CompositeKeyEndToEndSqlServerTest.CompositeKeyEndToEndSqlServerFixture>(fixture) +public class CompositeKeyEndToEndSqlServerTest(CompositeKeyEndToEndSqlServerTest.CompositeKeyEndToEndSqlServerFixture fixture) + : CompositeKeyEndToEndTestBase< + CompositeKeyEndToEndSqlServerTest.CompositeKeyEndToEndSqlServerFixture>(fixture) { public class CompositeKeyEndToEndSqlServerFixture : CompositeKeyEndToEndFixtureBase { diff --git a/test/EFCore.SqlServer.FunctionalTests/ComputedColumnTest.cs b/test/EFCore.SqlServer.FunctionalTests/ComputedColumnTest.cs index 009d5739827..fd0c4fd5021 100644 --- a/test/EFCore.SqlServer.FunctionalTests/ComputedColumnTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/ComputedColumnTest.cs @@ -133,9 +133,6 @@ public void Can_use_computed_columns_with_nullable_enum() public async Task InitializeAsync() => TestStore = await SqlServerTestStore.CreateInitializedAsync("ComputedColumnTest"); - public Task DisposeAsync() - { - TestStore.Dispose(); - return Task.CompletedTask; - } + public async Task DisposeAsync() + => await TestStore.DisposeAsync(); } diff --git a/test/EFCore.SqlServer.FunctionalTests/ConcurrencyDetectorDisabledSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/ConcurrencyDetectorDisabledSqlServerTest.cs index 5d973555b5f..d373d8ac63c 100644 --- a/test/EFCore.SqlServer.FunctionalTests/ConcurrencyDetectorDisabledSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/ConcurrencyDetectorDisabledSqlServerTest.cs @@ -10,9 +10,7 @@ public class ConcurrencyDetectorDisabledSqlServerTest : ConcurrencyDetectorDisab { public ConcurrencyDetectorDisabledSqlServerTest(ConcurrencyDetectorSqlServerFixture fixture) : base(fixture) - { - Fixture.TestSqlLoggerFactory.Clear(); - } + => Fixture.TestSqlLoggerFactory.Clear(); protected override async Task ConcurrencyDetectorTest(Func> test) { diff --git a/test/EFCore.SqlServer.FunctionalTests/ConcurrencyDetectorEnabledSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/ConcurrencyDetectorEnabledSqlServerTest.cs index 93d5cfe64d1..f1b771d3171 100644 --- a/test/EFCore.SqlServer.FunctionalTests/ConcurrencyDetectorEnabledSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/ConcurrencyDetectorEnabledSqlServerTest.cs @@ -10,9 +10,7 @@ public class ConcurrencyDetectorEnabledSqlServerTest : ConcurrencyDetectorEnable { public ConcurrencyDetectorEnabledSqlServerTest(ConcurrencyDetectorSqlServerFixture fixture) : base(fixture) - { - Fixture.TestSqlLoggerFactory.Clear(); - } + => Fixture.TestSqlLoggerFactory.Clear(); protected override async Task ConcurrencyDetectorTest(Func> test) { diff --git a/test/EFCore.SqlServer.FunctionalTests/ConferencePlannerSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/ConferencePlannerSqlServerTest.cs index d3aed4b2065..86e5d615196 100644 --- a/test/EFCore.SqlServer.FunctionalTests/ConferencePlannerSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/ConferencePlannerSqlServerTest.cs @@ -5,8 +5,9 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class ConferencePlannerSqlServerTest(ConferencePlannerSqlServerTest.ConferencePlannerSqlServerFixture fixture) : ConferencePlannerTestBase(fixture) +public class ConferencePlannerSqlServerTest(ConferencePlannerSqlServerTest.ConferencePlannerSqlServerFixture fixture) + : ConferencePlannerTestBase(fixture) { protected override void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction) => facade.UseTransaction(transaction.GetDbTransaction()); diff --git a/test/EFCore.SqlServer.FunctionalTests/ConnectionInterceptionSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/ConnectionInterceptionSqlServerTest.cs index d5148ae98d2..b4867588d2e 100644 --- a/test/EFCore.SqlServer.FunctionalTests/ConnectionInterceptionSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/ConnectionInterceptionSqlServerTest.cs @@ -73,7 +73,8 @@ protected override bool ShouldSubscribeToDiagnosticListener } } - public class ConnectionInterceptionWithConnectionStringSqlServerTest(ConnectionInterceptionWithConnectionStringSqlServerTest.InterceptionSqlServerFixture fixture) + public class ConnectionInterceptionWithConnectionStringSqlServerTest( + ConnectionInterceptionWithConnectionStringSqlServerTest.InterceptionSqlServerFixture fixture) : ConnectionInterceptionSqlServerTestBase(fixture), IClassFixture { @@ -87,8 +88,9 @@ protected override DbContextOptionsBuilder ConfigureProvider(DbContextOptionsBui => optionsBuilder.UseSqlServer("Database=Dummy"); } - public class ConnectionInterceptionWithDiagnosticsSqlServerTest(ConnectionInterceptionWithDiagnosticsSqlServerTest.InterceptionSqlServerFixture fixture) - : ConnectionInterceptionSqlServerTestBase(fixture), + public class ConnectionInterceptionWithDiagnosticsSqlServerTest( + ConnectionInterceptionWithDiagnosticsSqlServerTest.InterceptionSqlServerFixture fixture) + : ConnectionInterceptionSqlServerTestBase(fixture), IClassFixture { public class InterceptionSqlServerFixture : InterceptionSqlServerFixtureBase diff --git a/test/EFCore.SqlServer.FunctionalTests/ConnectionSpecificationTest.cs b/test/EFCore.SqlServer.FunctionalTests/ConnectionSpecificationTest.cs index 5e25523b0ef..f641b8c3c56 100644 --- a/test/EFCore.SqlServer.FunctionalTests/ConnectionSpecificationTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/ConnectionSpecificationTest.cs @@ -22,7 +22,7 @@ var serviceProvider .AddDbContext() .BuildServiceProvider(validateScopes: true); - using (await SqlServerTestStore.GetNorthwindStoreAsync()) + await using (await SqlServerTestStore.GetNorthwindStoreAsync()) { using var scope = serviceProvider.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); @@ -36,7 +36,7 @@ var serviceProvider [ConditionalFact] public async Task Can_specify_no_connection_string_in_OnConfiguring_with_default_service_provider() { - using (await SqlServerTestStore.GetNorthwindStoreAsync()) + await using (await SqlServerTestStore.GetNorthwindStoreAsync()) { using var context = new NoneInOnConfiguringContext(); @@ -49,7 +49,7 @@ public async Task Can_specify_no_connection_string_in_OnConfiguring_with_default [ConditionalFact] public async Task Throws_if_context_used_with_no_connection_or_connection_string() { - using (await SqlServerTestStore.GetNorthwindStoreAsync()) + await using (await SqlServerTestStore.GetNorthwindStoreAsync()) { using var context = new NoneInOnConfiguringContext(); @@ -73,7 +73,7 @@ var serviceProvider .AddDbContext() .BuildServiceProvider(validateScopes: true); - using (await SqlServerTestStore.GetNorthwindStoreAsync()) + await using (await SqlServerTestStore.GetNorthwindStoreAsync()) { using var scope = serviceProvider.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); @@ -84,7 +84,7 @@ var serviceProvider [ConditionalFact] public async Task Can_specify_connection_string_in_OnConfiguring_with_default_service_provider() { - using (await SqlServerTestStore.GetNorthwindStoreAsync()) + await using (await SqlServerTestStore.GetNorthwindStoreAsync()) { using var context = new StringInOnConfiguringContext(); Assert.True(await context.Customers.AnyAsync()); @@ -111,7 +111,7 @@ var serviceProvider SqlConnection connection; - using (await SqlServerTestStore.GetNorthwindStoreAsync()) + await using (await SqlServerTestStore.GetNorthwindStoreAsync()) { using var scope = serviceProvider.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); @@ -141,7 +141,7 @@ public async Task Can_specify_no_connection_in_OnConfiguring_with_default_servic { SqlConnection connection; - using (await SqlServerTestStore.GetNorthwindStoreAsync()) + await using (await SqlServerTestStore.GetNorthwindStoreAsync()) { using var context = new NoneInOnConfiguringContext(); @@ -171,7 +171,7 @@ var serviceProvider .AddScoped(p => new SqlConnection(SqlServerNorthwindTestStoreFactory.NorthwindConnectionString)) .AddDbContext().BuildServiceProvider(validateScopes: true); - using (await SqlServerTestStore.GetNorthwindStoreAsync()) + await using (await SqlServerTestStore.GetNorthwindStoreAsync()) { using var scope = serviceProvider.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); @@ -182,7 +182,7 @@ var serviceProvider [ConditionalFact] public async Task Can_specify_connection_in_OnConfiguring_with_default_service_provider() { - using (await SqlServerTestStore.GetNorthwindStoreAsync()) + await using (await SqlServerTestStore.GetNorthwindStoreAsync()) { using var connection = new SqlConnection(SqlServerNorthwindTestStoreFactory.NorthwindConnectionString); using var context = new ConnectionInOnConfiguringContext(connection); @@ -201,7 +201,7 @@ var serviceProvider SqlConnection connection; - using (await SqlServerTestStore.GetNorthwindStoreAsync()) + await using (await SqlServerTestStore.GetNorthwindStoreAsync()) { connection = serviceProvider.GetRequiredService(); @@ -218,7 +218,7 @@ public async Task Can_specify_owned_connection_in_OnConfiguring_with_default_ser { SqlConnection connection; - using (await SqlServerTestStore.GetNorthwindStoreAsync()) + await using (await SqlServerTestStore.GetNorthwindStoreAsync()) { connection = new SqlConnection(SqlServerNorthwindTestStoreFactory.NorthwindConnectionString); using var context = new OwnedConnectionInOnConfiguringContext(connection); @@ -239,7 +239,7 @@ var serviceProvider .AddScoped(p => connection) .AddDbContext().BuildServiceProvider(validateScopes: true); - using (await SqlServerTestStore.GetNorthwindStoreAsync()) + await using (await SqlServerTestStore.GetNorthwindStoreAsync()) { using var scope = serviceProvider.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); @@ -265,7 +265,7 @@ var serviceProvider .AddScoped(p => connection) .AddDbContext().BuildServiceProvider(validateScopes: true); - using (await SqlServerTestStore.GetNorthwindStoreAsync()) + await using (await SqlServerTestStore.GetNorthwindStoreAsync()) { using var scope = serviceProvider.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); @@ -292,7 +292,7 @@ var serviceProvider .AddScoped(p => connection) .AddDbContext().BuildServiceProvider(validateScopes: true); - using (await SqlServerTestStore.GetNorthwindStoreAsync()) + await using (await SqlServerTestStore.GetNorthwindStoreAsync()) { using var scope = serviceProvider.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); @@ -378,7 +378,7 @@ var serviceProvider .AddDbContext() .BuildServiceProvider(validateScopes: true); - using (await SqlServerTestStore.GetNorthwindStoreAsync()) + await using (await SqlServerTestStore.GetNorthwindStoreAsync()) { using var scope = serviceProvider.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); @@ -389,7 +389,7 @@ var serviceProvider [ConditionalFact] public async Task Can_depend_on_DbContextOptions_with_default_service_provider() { - using (await SqlServerTestStore.GetNorthwindStoreAsync()) + await using (await SqlServerTestStore.GetNorthwindStoreAsync()) { using var connection = new SqlConnection(SqlServerNorthwindTestStoreFactory.NorthwindConnectionString); @@ -432,7 +432,7 @@ var serviceProvider .AddDbContext() .BuildServiceProvider(validateScopes: true); - using (await SqlServerTestStore.GetNorthwindStoreAsync()) + await using (await SqlServerTestStore.GetNorthwindStoreAsync()) { using var scope = serviceProvider.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); @@ -443,7 +443,7 @@ var serviceProvider [ConditionalFact] public async Task Can_depend_on_non_generic_options_when_only_one_context_with_default_service_provider() { - using (await SqlServerTestStore.GetNorthwindStoreAsync()) + await using (await SqlServerTestStore.GetNorthwindStoreAsync()) { using var context = new NonGenericOptionsContext(new DbContextOptions()); Assert.True(await context.Customers.AnyAsync()); @@ -483,7 +483,7 @@ var serviceProvider b => b.UseSqlServer(connectionString).EnableServiceProviderCaching(false)) .BuildServiceProvider(validateScopes: true); - using (await SqlServerTestStore.GetNorthwindStoreAsync()) + await using (await SqlServerTestStore.GetNorthwindStoreAsync()) { using var serviceScope = serviceProvider.GetRequiredService().CreateScope(); using var context = serviceScope.ServiceProvider.GetRequiredService(); @@ -535,7 +535,7 @@ public async Task Can_use_an_existing_closed_connection_test(bool openConnection .AddEntityFrameworkSqlServer() .BuildServiceProvider(validateScopes: true); - using var store = await SqlServerTestStore.GetNorthwindStoreAsync(); + await using var store = await SqlServerTestStore.GetNorthwindStoreAsync(); store.CloseConnection(); var openCount = 0; diff --git a/test/EFCore.SqlServer.FunctionalTests/ConvertToProviderTypesSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/ConvertToProviderTypesSqlServerTest.cs index 1bca0ae908e..25a0c2f303a 100644 --- a/test/EFCore.SqlServer.FunctionalTests/ConvertToProviderTypesSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/ConvertToProviderTypesSqlServerTest.cs @@ -5,7 +5,7 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -[SqlServerCondition(SqlServerCondition.IsNotSqlAzure)] +[SqlServerCondition(SqlServerCondition.IsNotAzureSql)] public class ConvertToProviderTypesSqlServerTest(ConvertToProviderTypesSqlServerTest.ConvertToProviderTypesSqlServerFixture fixture) : ConvertToProviderTypesTestBase< ConvertToProviderTypesSqlServerTest.ConvertToProviderTypesSqlServerFixture>(fixture) diff --git a/test/EFCore.SqlServer.FunctionalTests/CustomConvertersSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/CustomConvertersSqlServerTest.cs index 5b947a6643a..39f7d5baa2f 100644 --- a/test/EFCore.SqlServer.FunctionalTests/CustomConvertersSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/CustomConvertersSqlServerTest.cs @@ -7,14 +7,12 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -[SqlServerCondition(SqlServerCondition.IsNotSqlAzure)] +[SqlServerCondition(SqlServerCondition.IsNotAzureSql)] public class CustomConvertersSqlServerTest : CustomConvertersTestBase { public CustomConvertersSqlServerTest(CustomConvertersSqlServerFixture fixture) : base(fixture) - { - Fixture.TestSqlLoggerFactory.Clear(); - } + => Fixture.TestSqlLoggerFactory.Clear(); [ConditionalFact] public virtual void Columns_have_expected_data_types() @@ -282,7 +280,7 @@ FROM [Blog] AS [b] """); } - public async override Task Where_bool_gets_converted_to_equality_when_value_conversion_is_used_using_EFProperty() + public override async Task Where_bool_gets_converted_to_equality_when_value_conversion_is_used_using_EFProperty() { await base.Where_bool_gets_converted_to_equality_when_value_conversion_is_used_using_EFProperty(); @@ -294,7 +292,7 @@ FROM [Blog] AS [b] """); } - public async override Task Where_bool_gets_converted_to_equality_when_value_conversion_is_used_using_indexer() + public override async Task Where_bool_gets_converted_to_equality_when_value_conversion_is_used_using_indexer() { await base.Where_bool_gets_converted_to_equality_when_value_conversion_is_used_using_indexer(); @@ -310,7 +308,7 @@ public override Task Object_to_string_conversion() // Return values are not string => Task.CompletedTask; - public async override Task Id_object_as_entity_key() + public override async Task Id_object_as_entity_key() { await base.Id_object_as_entity_key(); diff --git a/test/EFCore.SqlServer.FunctionalTests/DbContextPoolingTest.cs b/test/EFCore.SqlServer.FunctionalTests/DbContextPoolingTest.cs index 778813b94b9..49f7a25e89d 100644 --- a/test/EFCore.SqlServer.FunctionalTests/DbContextPoolingTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/DbContextPoolingTest.cs @@ -19,9 +19,9 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable - #pragma warning disable CS9113 // Parameter is unread. -public class DbContextPoolingTest(NorthwindQuerySqlServerFixture fixture, ITestOutputHelper testOutputHelper) : IClassFixture> +public class DbContextPoolingTest(NorthwindQuerySqlServerFixture fixture, ITestOutputHelper testOutputHelper) + : IClassFixture> #pragma warning restore CS9113 // Parameter is unread. { private static DbContextOptionsBuilder ConfigureOptions(DbContextOptionsBuilder optionsBuilder) @@ -531,15 +531,11 @@ private class WithParameterlessConstructorContext : DbContext public string ConstructorUsed { get; } public WithParameterlessConstructorContext() - { - ConstructorUsed = "Parameterless"; - } + => ConstructorUsed = "Parameterless"; public WithParameterlessConstructorContext(DbContextOptions options) : base(options) - { - ConstructorUsed = "Options"; - } + => ConstructorUsed = "Options"; } [ConditionalTheory] @@ -2010,7 +2006,7 @@ public void Double_dispose_concurrency_test(bool useInterface) }); } - [ConditionalTheory (Skip = "Issue #32700")] + [ConditionalTheory(Skip = "Issue #32700")] [InlineData(false, false)] [InlineData(true, false)] [InlineData(false, true)] diff --git a/test/EFCore.SqlServer.FunctionalTests/DefaultValuesTest.cs b/test/EFCore.SqlServer.FunctionalTests/DefaultValuesTest.cs index ef03987f5b1..07cf0c41aee 100644 --- a/test/EFCore.SqlServer.FunctionalTests/DefaultValuesTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/DefaultValuesTest.cs @@ -91,9 +91,6 @@ private class Chipper public async Task InitializeAsync() => TestStore = await SqlServerTestStore.CreateInitializedAsync("DefaultValuesTest"); - public Task DisposeAsync() - { - TestStore.Dispose(); - return Task.CompletedTask; - } + public async Task DisposeAsync() + => await TestStore.DisposeAsync(); } diff --git a/test/EFCore.SqlServer.FunctionalTests/DesignTimeSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/DesignTimeSqlServerTest.cs index 12258ce23dd..8a9fabe566f 100644 --- a/test/EFCore.SqlServer.FunctionalTests/DesignTimeSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/DesignTimeSqlServerTest.cs @@ -7,7 +7,8 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class DesignTimeSqlServerTest(DesignTimeSqlServerTest.DesignTimeSqlServerFixture fixture) : DesignTimeTestBase(fixture) +public class DesignTimeSqlServerTest(DesignTimeSqlServerTest.DesignTimeSqlServerFixture fixture) + : DesignTimeTestBase(fixture) { protected override Assembly ProviderAssembly => typeof(SqlServerDesignTimeServices).Assembly; 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/EverythingIsBytesSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/EverythingIsBytesSqlServerTest.cs index 4cdfbd4027e..b8e57fc1c1c 100644 --- a/test/EFCore.SqlServer.FunctionalTests/EverythingIsBytesSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/EverythingIsBytesSqlServerTest.cs @@ -8,7 +8,7 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -[SqlServerCondition(SqlServerCondition.IsNotSqlAzure)] +[SqlServerCondition(SqlServerCondition.IsNotAzureSql)] public class EverythingIsBytesSqlServerTest(EverythingIsBytesSqlServerTest.EverythingIsBytesSqlServerFixture fixture) : BuiltInDataTypesTestBase(fixture) { @@ -261,8 +261,7 @@ public SqlServerBytesTypeMappingSource( TypeMappingSourceDependencies dependencies, RelationalTypeMappingSourceDependencies relationalDependencies) : base(dependencies, relationalDependencies) - { - _storeTypeMappings + => _storeTypeMappings = new Dictionary(StringComparer.OrdinalIgnoreCase) { { "binary varying", _variableLengthBinary }, @@ -271,7 +270,6 @@ public SqlServerBytesTypeMappingSource( { "rowversion", _rowversion }, { "varbinary", _variableLengthBinary } }; - } protected override RelationalTypeMapping FindMapping(in RelationalTypeMappingInfo mappingInfo) => FindRawMapping(mappingInfo)?.WithTypeMappingInfo(mappingInfo); diff --git a/test/EFCore.SqlServer.FunctionalTests/EverythingIsStringsSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/EverythingIsStringsSqlServerTest.cs index 3edade4ed1b..4a03311ece0 100644 --- a/test/EFCore.SqlServer.FunctionalTests/EverythingIsStringsSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/EverythingIsStringsSqlServerTest.cs @@ -8,7 +8,7 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -[SqlServerCondition(SqlServerCondition.IsNotSqlAzure)] +[SqlServerCondition(SqlServerCondition.IsNotAzureSql)] public class EverythingIsStringsSqlServerTest(EverythingIsStringsSqlServerTest.EverythingIsStringsSqlServerFixture fixture) : BuiltInDataTypesTestBase< EverythingIsStringsSqlServerTest.EverythingIsStringsSqlServerFixture>(fixture) @@ -261,8 +261,7 @@ public SqlServerStringsTypeMappingSource( TypeMappingSourceDependencies dependencies, RelationalTypeMappingSourceDependencies relationalDependencies) : base(dependencies, relationalDependencies) - { - _storeTypeMappings + => _storeTypeMappings = new Dictionary(StringComparer.OrdinalIgnoreCase) { { "char varying", _variableLengthAnsiString }, @@ -278,7 +277,6 @@ public SqlServerStringsTypeMappingSource( { "text", _variableLengthAnsiString }, { "varchar", _variableLengthAnsiString } }; - } protected override RelationalTypeMapping FindMapping(in RelationalTypeMappingInfo mappingInfo) => FindRawMapping(mappingInfo)?.WithTypeMappingInfo(mappingInfo); diff --git a/test/EFCore.SqlServer.FunctionalTests/FieldMappingSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/FieldMappingSqlServerTest.cs index aeeae47abeb..22a61c84ec4 100644 --- a/test/EFCore.SqlServer.FunctionalTests/FieldMappingSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/FieldMappingSqlServerTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class FieldMappingSqlServerTest(FieldMappingSqlServerTest.FieldMappingSqlServerFixture fixture) : FieldMappingTestBase(fixture) +public class FieldMappingSqlServerTest(FieldMappingSqlServerTest.FieldMappingSqlServerFixture fixture) + : FieldMappingTestBase(fixture) { protected override void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction) => facade.UseTransaction(transaction.GetDbTransaction()); diff --git a/test/EFCore.SqlServer.FunctionalTests/FieldsOnlyLoadSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/FieldsOnlyLoadSqlServerTest.cs index 3255d8db36c..eb4ba3c7968 100644 --- a/test/EFCore.SqlServer.FunctionalTests/FieldsOnlyLoadSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/FieldsOnlyLoadSqlServerTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class FieldsOnlyLoadSqlServerTest(FieldsOnlyLoadSqlServerTest.FieldsOnlyLoadSqlServerFixture fixture) : FieldsOnlyLoadTestBase(fixture) +public class FieldsOnlyLoadSqlServerTest(FieldsOnlyLoadSqlServerTest.FieldsOnlyLoadSqlServerFixture fixture) + : FieldsOnlyLoadTestBase(fixture) { public class FieldsOnlyLoadSqlServerFixture : FieldsOnlyLoadFixtureBase { diff --git a/test/EFCore.SqlServer.FunctionalTests/FindSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/FindSqlServerTest.cs index 5540e94ad32..a5b6b87f5b7 100644 --- a/test/EFCore.SqlServer.FunctionalTests/FindSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/FindSqlServerTest.cs @@ -9,9 +9,7 @@ public abstract class FindSqlServerTest : FindTestBase fixture.TestSqlLoggerFactory.Clear(); public class FindSqlServerTestSet(FindSqlServerFixture fixture) : FindSqlServerTest(fixture) { diff --git a/test/EFCore.SqlServer.FunctionalTests/GraphUpdates/GraphUpdatesSqlServerClientCascadeTest.cs b/test/EFCore.SqlServer.FunctionalTests/GraphUpdates/GraphUpdatesSqlServerClientCascadeTest.cs index e9fc8fe77e1..d7396dd6b44 100644 --- a/test/EFCore.SqlServer.FunctionalTests/GraphUpdates/GraphUpdatesSqlServerClientCascadeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/GraphUpdates/GraphUpdatesSqlServerClientCascadeTest.cs @@ -5,8 +5,9 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class GraphUpdatesSqlServerClientCascadeTest(GraphUpdatesSqlServerClientCascadeTest.SqlServerFixture fixture) : GraphUpdatesSqlServerTestBase< - GraphUpdatesSqlServerClientCascadeTest.SqlServerFixture>(fixture) +public class GraphUpdatesSqlServerClientCascadeTest(GraphUpdatesSqlServerClientCascadeTest.SqlServerFixture fixture) + : GraphUpdatesSqlServerTestBase< + GraphUpdatesSqlServerClientCascadeTest.SqlServerFixture>(fixture) { protected override void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction) => facade.UseTransaction(transaction.GetDbTransaction()); diff --git a/test/EFCore.SqlServer.FunctionalTests/GraphUpdates/GraphUpdatesSqlServerClientNoActionTest.cs b/test/EFCore.SqlServer.FunctionalTests/GraphUpdates/GraphUpdatesSqlServerClientNoActionTest.cs index d8e440c4b88..1631dc1f65a 100644 --- a/test/EFCore.SqlServer.FunctionalTests/GraphUpdates/GraphUpdatesSqlServerClientNoActionTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/GraphUpdates/GraphUpdatesSqlServerClientNoActionTest.cs @@ -5,8 +5,9 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class GraphUpdatesSqlServerClientNoActionTest(GraphUpdatesSqlServerClientNoActionTest.SqlServerFixture fixture) : GraphUpdatesSqlServerTestBase< - GraphUpdatesSqlServerClientNoActionTest.SqlServerFixture>(fixture) +public class GraphUpdatesSqlServerClientNoActionTest(GraphUpdatesSqlServerClientNoActionTest.SqlServerFixture fixture) + : GraphUpdatesSqlServerTestBase< + GraphUpdatesSqlServerClientNoActionTest.SqlServerFixture>(fixture) { protected override void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction) => facade.UseTransaction(transaction.GetDbTransaction()); diff --git a/test/EFCore.SqlServer.FunctionalTests/GraphUpdates/GraphUpdatesSqlServerHiLoTest.cs b/test/EFCore.SqlServer.FunctionalTests/GraphUpdates/GraphUpdatesSqlServerHiLoTest.cs index f178d2729fe..bde99583153 100644 --- a/test/EFCore.SqlServer.FunctionalTests/GraphUpdates/GraphUpdatesSqlServerHiLoTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/GraphUpdates/GraphUpdatesSqlServerHiLoTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class GraphUpdatesSqlServerHiLoTest(GraphUpdatesSqlServerHiLoTest.SqlServerFixture fixture) : GraphUpdatesSqlServerTestBase(fixture) +public class GraphUpdatesSqlServerHiLoTest(GraphUpdatesSqlServerHiLoTest.SqlServerFixture fixture) + : GraphUpdatesSqlServerTestBase(fixture) { protected override void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction) => facade.UseTransaction(transaction.GetDbTransaction()); diff --git a/test/EFCore.SqlServer.FunctionalTests/GraphUpdates/GraphUpdatesSqlServerIdentityTest.cs b/test/EFCore.SqlServer.FunctionalTests/GraphUpdates/GraphUpdatesSqlServerIdentityTest.cs index e4704b253ed..5cda53cab07 100644 --- a/test/EFCore.SqlServer.FunctionalTests/GraphUpdates/GraphUpdatesSqlServerIdentityTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/GraphUpdates/GraphUpdatesSqlServerIdentityTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class GraphUpdatesSqlServerIdentityTest(GraphUpdatesSqlServerIdentityTest.SqlServerFixture fixture) : GraphUpdatesSqlServerTestBase(fixture) +public class GraphUpdatesSqlServerIdentityTest(GraphUpdatesSqlServerIdentityTest.SqlServerFixture fixture) + : GraphUpdatesSqlServerTestBase(fixture) { protected override void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction) => facade.UseTransaction(transaction.GetDbTransaction()); diff --git a/test/EFCore.SqlServer.FunctionalTests/GraphUpdates/GraphUpdatesSqlServerSequenceTest.cs b/test/EFCore.SqlServer.FunctionalTests/GraphUpdates/GraphUpdatesSqlServerSequenceTest.cs index 2e56efd8491..2693329222b 100644 --- a/test/EFCore.SqlServer.FunctionalTests/GraphUpdates/GraphUpdatesSqlServerSequenceTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/GraphUpdates/GraphUpdatesSqlServerSequenceTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class GraphUpdatesSqlServerSequenceTest(GraphUpdatesSqlServerSequenceTest.SqlServerFixture fixture) : GraphUpdatesSqlServerTestBase(fixture) +public class GraphUpdatesSqlServerSequenceTest(GraphUpdatesSqlServerSequenceTest.SqlServerFixture fixture) + : GraphUpdatesSqlServerTestBase(fixture) { protected override void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction) => facade.UseTransaction(transaction.GetDbTransaction()); diff --git a/test/EFCore.SqlServer.FunctionalTests/GraphUpdates/GraphUpdatesSqlServerTestBase.cs b/test/EFCore.SqlServer.FunctionalTests/GraphUpdates/GraphUpdatesSqlServerTestBase.cs index 482f2b45c1a..8d612278e72 100644 --- a/test/EFCore.SqlServer.FunctionalTests/GraphUpdates/GraphUpdatesSqlServerTestBase.cs +++ b/test/EFCore.SqlServer.FunctionalTests/GraphUpdates/GraphUpdatesSqlServerTestBase.cs @@ -19,11 +19,7 @@ public virtual void Key_and_index_properties_use_appropriate_comparer() UniqueIndex = "UniqueIndex" }; - var child = new StringKeyAndIndexChild - { - Id = "Child", - ParentId = "parent" - }; + var child = new StringKeyAndIndexChild { Id = "Child", ParentId = "parent" }; using var context = CreateContext(); context.AttachRange(parent, child); @@ -61,7 +57,6 @@ public virtual void Key_and_index_properties_use_appropriate_comparer() Assert.False(childEntry.Property(e => e.Id).IsModified); Assert.False(childEntry.Property(e => e.ParentId).IsModified); } - } protected class StringKeyAndIndexParent : NotifyingEntity @@ -122,7 +117,6 @@ public string ParentId set => SetWithNotify(value, ref _parentId); } - public int Foo { get => _foo; diff --git a/test/EFCore.SqlServer.FunctionalTests/GraphUpdates/GraphUpdatesSqlServerTptIdentityTest.cs b/test/EFCore.SqlServer.FunctionalTests/GraphUpdates/GraphUpdatesSqlServerTptIdentityTest.cs index 167e5035017..35e7cb1e538 100644 --- a/test/EFCore.SqlServer.FunctionalTests/GraphUpdates/GraphUpdatesSqlServerTptIdentityTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/GraphUpdates/GraphUpdatesSqlServerTptIdentityTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class GraphUpdatesSqlServerTptIdentityTest(GraphUpdatesSqlServerTptIdentityTest.SqlServerFixture fixture) : GraphUpdatesSqlServerTestBase(fixture) +public class GraphUpdatesSqlServerTptIdentityTest(GraphUpdatesSqlServerTptIdentityTest.SqlServerFixture fixture) + : GraphUpdatesSqlServerTestBase(fixture) { protected override void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction) => facade.UseTransaction(transaction.GetDbTransaction()); diff --git a/test/EFCore.SqlServer.FunctionalTests/JsonTypesCustomMappingSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/JsonTypesCustomMappingSqlServerTest.cs index c1acbfa7271..700bccd5963 100644 --- a/test/EFCore.SqlServer.FunctionalTests/JsonTypesCustomMappingSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/JsonTypesCustomMappingSqlServerTest.cs @@ -11,8 +11,8 @@ protected override IServiceCollection AddServices(IServiceCollection serviceColl => serviceCollection.AddSingleton(); private class TestSqlServerTypeMappingSource( - TypeMappingSourceDependencies dependencies, - RelationalTypeMappingSourceDependencies relationalDependencies) + TypeMappingSourceDependencies dependencies, + RelationalTypeMappingSourceDependencies relationalDependencies) : SqlServerTypeMappingSource(dependencies, relationalDependencies) { protected override RelationalTypeMapping? FindMapping(in RelationalTypeMappingInfo mappingInfo) diff --git a/test/EFCore.SqlServer.FunctionalTests/JsonTypesSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/JsonTypesSqlServerTest.cs index 8c8fb545851..c8e6e9904d5 100644 --- a/test/EFCore.SqlServer.FunctionalTests/JsonTypesSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/JsonTypesSqlServerTest.cs @@ -3,6 +3,4 @@ namespace Microsoft.EntityFrameworkCore; -#nullable disable - public class JsonTypesSqlServerTest : JsonTypesSqlServerTestBase; diff --git a/test/EFCore.SqlServer.FunctionalTests/KeysWithConvertersSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/KeysWithConvertersSqlServerTest.cs index 8d1d05fed20..150de2e2455 100644 --- a/test/EFCore.SqlServer.FunctionalTests/KeysWithConvertersSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/KeysWithConvertersSqlServerTest.cs @@ -5,8 +5,9 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class KeysWithConvertersSqlServerTest(KeysWithConvertersSqlServerTest.KeysWithConvertersSqlServerFixture fixture) : KeysWithConvertersTestBase< - KeysWithConvertersSqlServerTest.KeysWithConvertersSqlServerFixture>(fixture) +public class KeysWithConvertersSqlServerTest(KeysWithConvertersSqlServerTest.KeysWithConvertersSqlServerFixture fixture) + : KeysWithConvertersTestBase< + KeysWithConvertersSqlServerTest.KeysWithConvertersSqlServerFixture>(fixture) { public class KeysWithConvertersSqlServerFixture : KeysWithConvertersFixtureBase { diff --git a/test/EFCore.SqlServer.FunctionalTests/LazyLoadProxySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/LazyLoadProxySqlServerTest.cs index 0b277099f14..596125f4ee1 100644 --- a/test/EFCore.SqlServer.FunctionalTests/LazyLoadProxySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/LazyLoadProxySqlServerTest.cs @@ -9,9 +9,7 @@ public class LazyLoadProxySqlServerTest : LazyLoadProxyTestBase fixture.TestSqlLoggerFactory.Clear(); public override void Lazy_load_collection(EntityState state, bool useAttach, bool useDetach) { diff --git a/test/EFCore.SqlServer.FunctionalTests/LoadSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/LoadSqlServerTest.cs index 2f294a0876d..a59ee7f2f0a 100644 --- a/test/EFCore.SqlServer.FunctionalTests/LoadSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/LoadSqlServerTest.cs @@ -9,9 +9,7 @@ public class LoadSqlServerTest : LoadTestBase fixture.TestSqlLoggerFactory.Clear(); public override async Task Lazy_load_collection(EntityState state, QueryTrackingBehavior queryTrackingBehavior, bool async) { diff --git a/test/EFCore.SqlServer.FunctionalTests/LoggingSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/LoggingSqlServerTest.cs index 64c82f18cdb..188824e6da2 100644 --- a/test/EFCore.SqlServer.FunctionalTests/LoggingSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/LoggingSqlServerTest.cs @@ -27,7 +27,8 @@ public virtual void StoredProcedureConcurrencyTokenNotMapped_throws_by_default() () => context.Model).Message); } - protected class StoredProcedureConcurrencyTokenNotMappedContext(DbContextOptionsBuilder optionsBuilder) : DbContext(optionsBuilder.Options) + protected class StoredProcedureConcurrencyTokenNotMappedContext(DbContextOptionsBuilder optionsBuilder) + : DbContext(optionsBuilder.Options) { protected override void OnModelCreating(ModelBuilder modelBuilder) => modelBuilder.Entity( diff --git a/test/EFCore.SqlServer.FunctionalTests/ManyToManyFieldsLoadSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/ManyToManyFieldsLoadSqlServerTest.cs index d3b7c3231c8..603be183660 100644 --- a/test/EFCore.SqlServer.FunctionalTests/ManyToManyFieldsLoadSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/ManyToManyFieldsLoadSqlServerTest.cs @@ -7,8 +7,9 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class ManyToManyFieldsLoadSqlServerTest(ManyToManyFieldsLoadSqlServerTest.ManyToManyFieldsLoadSqlServerFixture fixture) : ManyToManyFieldsLoadTestBase< - ManyToManyFieldsLoadSqlServerTest.ManyToManyFieldsLoadSqlServerFixture>(fixture) +public class ManyToManyFieldsLoadSqlServerTest(ManyToManyFieldsLoadSqlServerTest.ManyToManyFieldsLoadSqlServerFixture fixture) + : ManyToManyFieldsLoadTestBase< + ManyToManyFieldsLoadSqlServerTest.ManyToManyFieldsLoadSqlServerFixture>(fixture) { public override async Task Load_collection(EntityState state, QueryTrackingBehavior queryTrackingBehavior, bool async) { diff --git a/test/EFCore.SqlServer.FunctionalTests/ManyToManyLoadSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/ManyToManyLoadSqlServerTest.cs index 7b9bb63a67a..2c840d57f36 100644 --- a/test/EFCore.SqlServer.FunctionalTests/ManyToManyLoadSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/ManyToManyLoadSqlServerTest.cs @@ -7,7 +7,8 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class ManyToManyLoadSqlServerTest(ManyToManyLoadSqlServerTest.ManyToManyLoadSqlServerFixture fixture) : ManyToManyLoadTestBase(fixture) +public class ManyToManyLoadSqlServerTest(ManyToManyLoadSqlServerTest.ManyToManyLoadSqlServerFixture fixture) + : ManyToManyLoadTestBase(fixture) { public override async Task Load_collection(EntityState state, QueryTrackingBehavior queryTrackingBehavior, bool async) { diff --git a/test/EFCore.SqlServer.FunctionalTests/ManyToManyTrackingGeneratedKeysSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/ManyToManyTrackingGeneratedKeysSqlServerTest.cs index ec846eb50b8..b54c5563c4b 100644 --- a/test/EFCore.SqlServer.FunctionalTests/ManyToManyTrackingGeneratedKeysSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/ManyToManyTrackingGeneratedKeysSqlServerTest.cs @@ -7,8 +7,10 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class ManyToManyTrackingGeneratedKeysSqlServerTest(ManyToManyTrackingGeneratedKeysSqlServerTest.ManyToManyTrackingGeneratedKeysSqlServerFixture fixture) - : ManyToManyTrackingSqlServerTestBase(fixture) +public class ManyToManyTrackingGeneratedKeysSqlServerTest( + ManyToManyTrackingGeneratedKeysSqlServerTest.ManyToManyTrackingGeneratedKeysSqlServerFixture fixture) + : ManyToManyTrackingSqlServerTestBase( + fixture) { public class ManyToManyTrackingGeneratedKeysSqlServerFixture : ManyToManyTrackingSqlServerFixtureBase { diff --git a/test/EFCore.SqlServer.FunctionalTests/MemoryOptimizedTablesTest.cs b/test/EFCore.SqlServer.FunctionalTests/MemoryOptimizedTablesTest.cs index e834f928fba..c51639e7a24 100644 --- a/test/EFCore.SqlServer.FunctionalTests/MemoryOptimizedTablesTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/MemoryOptimizedTablesTest.cs @@ -19,7 +19,7 @@ public class MemoryOptimizedTablesTest(MemoryOptimizedTablesTest.MemoryOptimized [ConditionalFact] public async Task Can_create_memoryOptimized_table() { - using (await CreateTestStoreAsync()) + await using (await CreateTestStoreAsync()) { var bigUn = new BigUn(); var fastUns = new[] { new FastUn { Name = "First 'un", BigUn = bigUn }, new FastUn { Name = "Second 'un", BigUn = bigUn } }; diff --git a/test/EFCore.SqlServer.FunctionalTests/Migrations/MigrationsInfrastructureSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Migrations/MigrationsInfrastructureSqlServerTest.cs index 1c3e933f398..f857bd8d268 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Migrations/MigrationsInfrastructureSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Migrations/MigrationsInfrastructureSqlServerTest.cs @@ -1,20 +1,20 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable disable + using Identity30.Data; using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore.Diagnostics.Internal; using Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal; using Microsoft.EntityFrameworkCore.TestModels.AspNetIdentity; -using static Microsoft.EntityFrameworkCore.DbLoggerCategory; - -#nullable disable // ReSharper disable InconsistentNaming namespace Microsoft.EntityFrameworkCore.Migrations { - [SqlServerCondition(SqlServerCondition.IsNotSqlAzure | SqlServerCondition.IsNotCI)] - public class MigrationsInfrastructureSqlServerTest(MigrationsInfrastructureSqlServerTest.MigrationsInfrastructureSqlServerFixture fixture) + [SqlServerCondition(SqlServerCondition.IsNotAzureSql | SqlServerCondition.IsNotCI)] + public class MigrationsInfrastructureSqlServerTest( + MigrationsInfrastructureSqlServerTest.MigrationsInfrastructureSqlServerFixture fixture) : MigrationsInfrastructureTestBase(fixture) { public override void Can_apply_all_migrations() // Issue #32826 @@ -29,8 +29,9 @@ public override void Can_apply_range_of_migrations() var sql = @"CREATE DATABASE TransactionSuppressed; "; - Assert.Equal(RelationalResources.LogNonTransactionalMigrationOperationWarning(new TestLogger()) - .GenerateMessage(sql, "Migration3"), + Assert.Equal( + RelationalResources.LogNonTransactionalMigrationOperationWarning(new TestLogger()) + .GenerateMessage(sql, "Migration3"), Fixture.TestSqlLoggerFactory.Log.Single(l => l.Id == RelationalEventId.NonTransactionalMigrationOperationWarning).Message); } @@ -966,8 +967,8 @@ public async Task Empty_Migration_Creates_Database() { using var context = new BloggingContext( Fixture.TestStore.AddProviderOptions( - new DbContextOptionsBuilder().EnableServiceProviderCaching(false)) - .ConfigureWarnings(e => e.Log(RelationalEventId.PendingModelChangesWarning)).Options); + new DbContextOptionsBuilder().EnableServiceProviderCaching(false)) + .ConfigureWarnings(e => e.Log(RelationalEventId.PendingModelChangesWarning)).Options); context.Database.EnsureDeleted(); GiveMeSomeTime(context); @@ -975,7 +976,7 @@ public async Task Empty_Migration_Creates_Database() var creator = (SqlServerDatabaseCreator)context.GetService(); creator.RetryTimeout = TimeSpan.FromMinutes(10); - await context.Database.MigrateAsync(null, "Empty"); + await context.Database.MigrateAsync("Empty"); Assert.True(creator.Exists()); } @@ -1001,6 +1002,8 @@ public void Non_transactional_migration_is_retried() context.Database.Migrate(); + SetSql(Fixture.TestSqlLoggerFactory.Sql); + Assert.Equal( """ CREATE DATABASE [MigrationsTest]; @@ -1012,19 +1015,20 @@ IF SERVERPROPERTY('EngineEdition') <> 5 SELECT 1 -@LockTimeout='?' (DbType = Double) - DECLARE @result int; -EXEC @result = sp_getapplock @Resource = '__EFMigrationsLock', @LockOwner = 'Session', @LockMode = 'Exclusive', @LockTimeout = @LockTimeout; +EXEC @result = sp_getapplock @Resource = '__EFMigrationsLock', @LockOwner = 'Session', @LockMode = 'Exclusive'; SELECT @result -SELECT OBJECT_ID(N'[__EFMigrationsHistory]'); +IF OBJECT_ID(N'[__EFMigrationsHistory]') IS NULL +BEGIN + CREATE TABLE [__EFMigrationsHistory] ( + [MigrationId] nvarchar(150) NOT NULL, + [ProductVersion] nvarchar(32) NOT NULL, + CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY ([MigrationId]) + ); +END; -CREATE TABLE [__EFMigrationsHistory] ( - [MigrationId] nvarchar(150) NOT NULL, - [ProductVersion] nvarchar(32) NOT NULL, - CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY ([MigrationId]) -); +SELECT 1 SELECT OBJECT_ID(N'[__EFMigrationsHistory]'); @@ -1033,7 +1037,7 @@ FROM [__EFMigrationsHistory] ORDER BY [MigrationId]; INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) -VALUES (N'00000000000000_Empty', N'9.0.0-dev'); +VALUES (N'00000000000000_Empty', N'7.0.0-test'); --Before @@ -1048,6 +1052,22 @@ CONSTRAINT [PK_Blogs] PRIMARY KEY ([Id]) THROW 65536, 'Test', 0; END +DECLARE @result int; +EXEC @result = sp_releaseapplock @Resource = '__EFMigrationsLock', @LockOwner = 'Session'; +SELECT @result + +DECLARE @result int; +EXEC @result = sp_getapplock @Resource = '__EFMigrationsLock', @LockOwner = 'Session', @LockMode = 'Exclusive'; +SELECT @result + +SELECT 1 + +SELECT OBJECT_ID(N'[__EFMigrationsHistory]'); + +SELECT [MigrationId], [ProductVersion] +FROM [__EFMigrationsHistory] +ORDER BY [MigrationId]; + IF OBJECT_ID(N'Blogs', N'U') IS NULL BEGIN CREATE TABLE [Blogs] ( @@ -1060,18 +1080,18 @@ CONSTRAINT [PK_Blogs] PRIMARY KEY ([Id]) END INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) -VALUES (N'00000000000001_Migration1', N'9.0.0-dev'); +VALUES (N'00000000000001_Migration1', N'7.0.0-test'); --After INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) -VALUES (N'00000000000002_Migration2', N'9.0.0-dev'); +VALUES (N'00000000000002_Migration2', N'7.0.0-test'); DECLARE @result int; EXEC @result = sp_releaseapplock @Resource = '__EFMigrationsLock', @LockOwner = 'Session'; SELECT @result """, - Fixture.TestSqlLoggerFactory.Sql, + Sql, ignoreLineEndingDifferences: true); } @@ -1096,6 +1116,8 @@ public async Task Non_transactional_migration_is_retried_async() await context.Database.MigrateAsync(); + SetSql(Fixture.TestSqlLoggerFactory.Sql); + Assert.Equal( """ CREATE DATABASE [MigrationsTest]; @@ -1107,19 +1129,20 @@ IF SERVERPROPERTY('EngineEdition') <> 5 SELECT 1 -@LockTimeout='?' (DbType = Double) - DECLARE @result int; -EXEC @result = sp_getapplock @Resource = '__EFMigrationsLock', @LockOwner = 'Session', @LockMode = 'Exclusive', @LockTimeout = @LockTimeout; +EXEC @result = sp_getapplock @Resource = '__EFMigrationsLock', @LockOwner = 'Session', @LockMode = 'Exclusive'; SELECT @result -SELECT OBJECT_ID(N'[__EFMigrationsHistory]'); +IF OBJECT_ID(N'[__EFMigrationsHistory]') IS NULL +BEGIN + CREATE TABLE [__EFMigrationsHistory] ( + [MigrationId] nvarchar(150) NOT NULL, + [ProductVersion] nvarchar(32) NOT NULL, + CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY ([MigrationId]) + ); +END; -CREATE TABLE [__EFMigrationsHistory] ( - [MigrationId] nvarchar(150) NOT NULL, - [ProductVersion] nvarchar(32) NOT NULL, - CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY ([MigrationId]) -); +SELECT 1 SELECT OBJECT_ID(N'[__EFMigrationsHistory]'); @@ -1128,7 +1151,7 @@ FROM [__EFMigrationsHistory] ORDER BY [MigrationId]; INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) -VALUES (N'00000000000000_Empty', N'9.0.0-dev'); +VALUES (N'00000000000000_Empty', N'7.0.0-test'); --Before @@ -1143,6 +1166,22 @@ CONSTRAINT [PK_Blogs] PRIMARY KEY ([Id]) THROW 65536, 'Test', 0; END +DECLARE @result int; +EXEC @result = sp_releaseapplock @Resource = '__EFMigrationsLock', @LockOwner = 'Session'; +SELECT @result + +DECLARE @result int; +EXEC @result = sp_getapplock @Resource = '__EFMigrationsLock', @LockOwner = 'Session', @LockMode = 'Exclusive'; +SELECT @result + +SELECT 1 + +SELECT OBJECT_ID(N'[__EFMigrationsHistory]'); + +SELECT [MigrationId], [ProductVersion] +FROM [__EFMigrationsHistory] +ORDER BY [MigrationId]; + IF OBJECT_ID(N'Blogs', N'U') IS NULL BEGIN CREATE TABLE [Blogs] ( @@ -1155,18 +1194,18 @@ CONSTRAINT [PK_Blogs] PRIMARY KEY ([Id]) END INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) -VALUES (N'00000000000001_Migration1', N'9.0.0-dev'); +VALUES (N'00000000000001_Migration1', N'7.0.0-test'); --After INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) -VALUES (N'00000000000002_Migration2', N'9.0.0-dev'); +VALUES (N'00000000000002_Migration2', N'7.0.0-test'); DECLARE @result int; EXEC @result = sp_releaseapplock @Resource = '__EFMigrationsLock', @LockOwner = 'Session'; SELECT @result """, - Fixture.TestSqlLoggerFactory.Sql, + Sql, ignoreLineEndingDifferences: true); } @@ -1202,7 +1241,8 @@ private class BloggingMigration1 : Migration protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.Sql("--Before", suppressTransaction: true); - migrationBuilder.Sql(""" + migrationBuilder.Sql( + """ IF OBJECT_ID(N'Blogs', N'U') IS NULL BEGIN CREATE TABLE [Blogs] ( @@ -1226,9 +1266,7 @@ protected override void Down(MigrationBuilder migrationBuilder) private class BloggingMigration2 : Migration { protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.Sql("--After"); - } + => migrationBuilder.Sql("--After"); protected override void Down(MigrationBuilder migrationBuilder) { @@ -2082,7 +2120,8 @@ IF EXISTS(select * from sys.databases where name='TransactionSuppressed') public override MigrationsContext CreateContext() { var options = AddOptions(TestStore.AddProviderOptions(new DbContextOptionsBuilder())) - .UseSqlServer(TestStore.ConnectionString, b => b.ApplyConfiguration()) + .UseSqlServer(TestStore.ConnectionString, b => b + .ApplyConfiguration()) .UseInternalServiceProvider(ServiceProvider) .Options; return new MigrationsContext(options); diff --git a/test/EFCore.SqlServer.FunctionalTests/Migrations/MigrationsSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Migrations/MigrationsSqlServerTest.cs index ce8f413ffe9..65a90ea1f54 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Migrations/MigrationsSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Migrations/MigrationsSqlServerTest.cs @@ -2865,12 +2865,13 @@ await Test( public virtual async Task Add_alternate_key_with_fill_factor() { await Test( - builder => { + builder => + { builder.Entity("People").Property("SomeField").IsRequired().HasMaxLength(450); builder.Entity("People").Property("SomeOtherField").IsRequired().HasMaxLength(450); - }, + }, builder => { }, - builder => builder.Entity("People").HasAlternateKey(["SomeField", "SomeOtherField"]).HasFillFactor(80), + builder => builder.Entity("People").HasAlternateKey("SomeField", "SomeOtherField").HasFillFactor(80), model => { var table = Assert.Single(model.Tables); @@ -7047,8 +7048,8 @@ await Test( """ ALTER TABLE [Customer] SET (SYSTEM_VERSIONING = OFF) """, - // - """ + // + """ DECLARE @var0 sysname; SELECT @var0 = [d].[name] FROM [sys].[default_constraints] [d] @@ -7059,8 +7060,8 @@ FROM [sys].[default_constraints] [d] ALTER TABLE [Customer] ALTER COLUMN [IsVip] bit NOT NULL; ALTER TABLE [Customer] ADD DEFAULT CAST(0 AS bit) FOR [IsVip]; """, - // - """ + // + """ DECLARE @var1 sysname; SELECT @var1 = [d].[name] FROM [sys].[default_constraints] [d] @@ -7071,8 +7072,8 @@ FROM [sys].[default_constraints] [d] ALTER TABLE [HistoryTable] ALTER COLUMN [IsVip] bit NOT NULL; ALTER TABLE [HistoryTable] ADD DEFAULT CAST(0 AS bit) FOR [IsVip]; """, - // - """ + // + """ DECLARE @historyTableSchema sysname = SCHEMA_NAME() EXEC(N'ALTER TABLE [Customer] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema + '].[HistoryTable]))') """); @@ -7185,16 +7186,16 @@ await Test( """ ALTER TABLE [Customer] SET (SYSTEM_VERSIONING = OFF) """, - // - """ + // + """ ALTER TABLE [Customer] ADD [IdPlusFive] AS Id + 5 PERSISTED; """, - // - """ + // + """ ALTER TABLE [HistoryTable] ADD [IdPlusFive] int NULL; """, - // - """ + // + """ DECLARE @historyTableSchema sysname = SCHEMA_NAME() EXEC(N'ALTER TABLE [Customer] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema + '].[HistoryTable]))') """); @@ -7249,16 +7250,16 @@ await Test( """ ALTER TABLE [Customer] SET (SYSTEM_VERSIONING = OFF) """, - // - """ + // + """ ALTER TABLE [Customer] ADD [Five] AS 5 PERSISTED; """, - // - """ + // + """ ALTER TABLE [HistoryTable] ADD [Five] int NOT NULL DEFAULT 0; """, - // - """ + // + """ DECLARE @historyTableSchema sysname = SCHEMA_NAME() EXEC(N'ALTER TABLE [Customer] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema + '].[HistoryTable]))') """); @@ -7312,8 +7313,8 @@ await Test( """ ALTER TABLE [Customer] SET (SYSTEM_VERSIONING = OFF) """, - // - """ + // + """ DECLARE @var0 sysname; SELECT @var0 = [d].[name] FROM [sys].[default_constraints] [d] @@ -7322,8 +7323,8 @@ FROM [sys].[default_constraints] [d] IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Customer] DROP CONSTRAINT [' + @var0 + '];'); ALTER TABLE [Customer] DROP COLUMN [IdPlusFive]; """, - // - """ + // + """ DECLARE @var1 sysname; SELECT @var1 = [d].[name] FROM [sys].[default_constraints] [d] @@ -7332,8 +7333,8 @@ FROM [sys].[default_constraints] [d] IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [HistoryTable] DROP CONSTRAINT [' + @var1 + '];'); ALTER TABLE [HistoryTable] DROP COLUMN [IdPlusFive]; """, - // - """ + // + """ DECLARE @historyTableSchema sysname = SCHEMA_NAME() EXEC(N'ALTER TABLE [Customer] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema + '].[HistoryTable]))') """); @@ -7342,51 +7343,52 @@ FROM [sys].[default_constraints] [d] [ConditionalFact] public virtual async Task Alter_computed_column_sql_on_temporal_table() { - var message = (await Assert.ThrowsAsync(() => Test( - builder => builder.Entity( - "Customer", e => - { - e.Property("Id").ValueGeneratedOnAdd(); - e.Property("Start").ValueGeneratedOnAddOrUpdate(); - e.Property("End").ValueGeneratedOnAddOrUpdate(); - e.HasKey("Id"); - - e.ToTable( - tb => tb.IsTemporal( - ttb => - { - ttb.UseHistoryTable("HistoryTable"); - ttb.HasPeriodStart("Start"); - ttb.HasPeriodEnd("End"); - })); - }), - builder => builder.Entity( - "Customer", e => - { - e.Property("IdPlusFive").HasComputedColumnSql("Id + 5 PERSISTED"); - }), - builder => builder.Entity( - "Customer", e => - { - e.Property("IdPlusFive").HasComputedColumnSql("Id + 10 PERSISTED"); - }), - model => - { - var table = Assert.Single(model.Tables); - Assert.Equal("Customer", table.Name); - Assert.NotNull(table[SqlServerAnnotationNames.IsTemporal]); - Assert.Equal("HistoryTable", table[SqlServerAnnotationNames.TemporalHistoryTableName]); - Assert.Equal("Start", table[SqlServerAnnotationNames.TemporalPeriodStartPropertyName]); - Assert.Equal("End", table[SqlServerAnnotationNames.TemporalPeriodEndPropertyName]); + var message = (await Assert.ThrowsAsync( + () => Test( + builder => builder.Entity( + "Customer", e => + { + e.Property("Id").ValueGeneratedOnAdd(); + e.Property("Start").ValueGeneratedOnAddOrUpdate(); + e.Property("End").ValueGeneratedOnAddOrUpdate(); + e.HasKey("Id"); - Assert.Collection( - table.Columns, - c => Assert.Equal("Id", c.Name), - c => Assert.Equal("IdPlusFive", c.Name)); - Assert.Same( - table.Columns.Single(c => c.Name == "Id"), - Assert.Single(table.PrimaryKey!.Columns)); - }))).Message; + e.ToTable( + tb => tb.IsTemporal( + ttb => + { + ttb.UseHistoryTable("HistoryTable"); + ttb.HasPeriodStart("Start"); + ttb.HasPeriodEnd("End"); + })); + }), + builder => builder.Entity( + "Customer", e => + { + e.Property("IdPlusFive").HasComputedColumnSql("Id + 5 PERSISTED"); + }), + builder => builder.Entity( + "Customer", e => + { + e.Property("IdPlusFive").HasComputedColumnSql("Id + 10 PERSISTED"); + }), + model => + { + var table = Assert.Single(model.Tables); + Assert.Equal("Customer", table.Name); + Assert.NotNull(table[SqlServerAnnotationNames.IsTemporal]); + Assert.Equal("HistoryTable", table[SqlServerAnnotationNames.TemporalHistoryTableName]); + Assert.Equal("Start", table[SqlServerAnnotationNames.TemporalPeriodStartPropertyName]); + Assert.Equal("End", table[SqlServerAnnotationNames.TemporalPeriodEndPropertyName]); + + Assert.Collection( + table.Columns, + c => Assert.Equal("Id", c.Name), + c => Assert.Equal("IdPlusFive", c.Name)); + Assert.Same( + table.Columns.Single(c => c.Name == "Id"), + Assert.Single(table.PrimaryKey!.Columns)); + }))).Message; Assert.Equal( SqlServerStrings.TemporalMigrationModifyingComputedColumnNotSupported("IdPlusFive", "Customer"), @@ -7502,8 +7504,8 @@ await Test( """ ALTER TABLE [Customer] SET (SYSTEM_VERSIONING = OFF) """, - // - """ + // + """ DECLARE @var0 sysname; SELECT @var0 = [d].[name] FROM [sys].[default_constraints] [d] @@ -7512,8 +7514,8 @@ FROM [sys].[default_constraints] [d] IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Customer] DROP CONSTRAINT [' + @var0 + '];'); ALTER TABLE [Customer] DROP COLUMN [Number]; """, - // - """ + // + """ DECLARE @var1 sysname; SELECT @var1 = [d].[name] FROM [sys].[default_constraints] [d] @@ -7522,8 +7524,8 @@ FROM [sys].[default_constraints] [d] IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [HistoryTable] DROP CONSTRAINT [' + @var1 + '];'); ALTER TABLE [HistoryTable] DROP COLUMN [Number]; """, - // - """ + // + """ DECLARE @historyTableSchema sysname = SCHEMA_NAME() EXEC(N'ALTER TABLE [Customer] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema + '].[HistoryTable]))') """); @@ -7635,21 +7637,21 @@ await Test( """ ALTER TABLE [Customer] SET (SYSTEM_VERSIONING = OFF) """, - // - """ + // + """ IF EXISTS (SELECT 1 FROM [sys].[tables] [t] INNER JOIN [sys].[partitions] [p] ON [t].[object_id] = [p].[object_id] WHERE [t].[name] = 'HistoryTable' AND data_compression <> 0) EXEC(N'ALTER TABLE [HistoryTable] REBUILD PARTITION = ALL WITH (DATA_COMPRESSION = NONE);'); """, - // - """ + // + """ ALTER TABLE [Customer] ADD [MyColumn] int SPARSE NULL; """, - // - """ + // + """ ALTER TABLE [HistoryTable] ADD [MyColumn] int SPARSE NULL; """, - // - """ + // + """ DECLARE @historyTableSchema sysname = SCHEMA_NAME() EXEC(N'ALTER TABLE [Customer] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema + '].[HistoryTable]))') """); @@ -7667,7 +7669,8 @@ await Test( e.Property("Start").ValueGeneratedOnAddOrUpdate(); e.Property("End").ValueGeneratedOnAddOrUpdate(); e.HasKey("Id"); - e.ToTable("Customers", "mySchema", + e.ToTable( + "Customers", "mySchema", tb => tb.IsTemporal( ttb => { @@ -7706,21 +7709,21 @@ await Test( """ ALTER TABLE [mySchema].[Customers] SET (SYSTEM_VERSIONING = OFF) """, - // - """ + // + """ IF EXISTS (SELECT 1 FROM [sys].[tables] [t] INNER JOIN [sys].[partitions] [p] ON [t].[object_id] = [p].[object_id] WHERE [t].[name] = 'HistoryTable' AND [t].[schema_id] = schema_id('myHistorySchema') AND data_compression <> 0) EXEC(N'ALTER TABLE [myHistorySchema].[HistoryTable] REBUILD PARTITION = ALL WITH (DATA_COMPRESSION = NONE);'); """, - // - """ + // + """ ALTER TABLE [mySchema].[Customers] ADD [MyColumn] int SPARSE NULL; """, - // - """ + // + """ ALTER TABLE [myHistorySchema].[HistoryTable] ADD [MyColumn] int SPARSE NULL; """, - // - """ + // + """ ALTER TABLE [mySchema].[Customers] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [myHistorySchema].[HistoryTable])) """); } @@ -7783,13 +7786,13 @@ await Test( """ ALTER TABLE [Customer] SET (SYSTEM_VERSIONING = OFF) """, - // - """ + // + """ IF EXISTS (SELECT 1 FROM [sys].[tables] [t] INNER JOIN [sys].[partitions] [p] ON [t].[object_id] = [p].[object_id] WHERE [t].[name] = 'HistoryTable' AND data_compression <> 0) EXEC(N'ALTER TABLE [HistoryTable] REBUILD PARTITION = ALL WITH (DATA_COMPRESSION = NONE);'); """, - // - """ + // + """ DECLARE @var0 sysname; SELECT @var0 = [d].[name] FROM [sys].[default_constraints] [d] @@ -7798,8 +7801,8 @@ FROM [sys].[default_constraints] [d] IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Customer] DROP CONSTRAINT [' + @var0 + '];'); ALTER TABLE [Customer] ALTER COLUMN [MyColumn] int SPARSE NULL; """, - // - """ + // + """ DECLARE @var1 sysname; SELECT @var1 = [d].[name] FROM [sys].[default_constraints] [d] @@ -7808,8 +7811,8 @@ FROM [sys].[default_constraints] [d] IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [HistoryTable] DROP CONSTRAINT [' + @var1 + '];'); ALTER TABLE [HistoryTable] ALTER COLUMN [MyColumn] int SPARSE NULL; """, - // - """ + // + """ DECLARE @historyTableSchema sysname = SCHEMA_NAME() EXEC(N'ALTER TABLE [Customer] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema + '].[HistoryTable]))') """); @@ -7939,24 +7942,24 @@ await Test( """ ALTER TABLE [Customers] ADD [End] datetime2 NOT NULL DEFAULT '9999-12-31T23:59:59.9999999'; """, - // - """ + // + """ ALTER TABLE [Customers] ADD [Start] datetime2 NOT NULL DEFAULT '0001-01-01T00:00:00.0000000'; """, - // - """ + // + """ ALTER TABLE [Customers] ADD PERIOD FOR SYSTEM_TIME ([Start], [End]) """, - // - """ + // + """ ALTER TABLE [Customers] ALTER COLUMN [Start] ADD HIDDEN """, - // - """ + // + """ ALTER TABLE [Customers] ALTER COLUMN [End] ADD HIDDEN """, - // - """ + // + """ DECLARE @historyTableSchema sysname = SCHEMA_NAME() EXEC(N'ALTER TABLE [Customers] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema + '].[HistoryTable]))') """); @@ -9658,8 +9661,8 @@ await Test( """ EXEC sp_rename N'[Customers].[PeriodStart]', N'ValidFrom', 'COLUMN'; """, - // - """ + // + """ EXEC sp_rename N'[Customers].[PeriodEnd]', N'ValidTo', 'COLUMN'; """); } @@ -9717,28 +9720,28 @@ await Test( """ ALTER TABLE [Customers] ADD [End] datetime2 NOT NULL DEFAULT '9999-12-31T23:59:59.9999999'; """, - // - """ + // + """ ALTER TABLE [Customers] ADD [Number] int NOT NULL DEFAULT 0; """, - // - """ + // + """ ALTER TABLE [Customers] ADD [Start] datetime2 NOT NULL DEFAULT '0001-01-01T00:00:00.0000000'; """, - // - """ + // + """ ALTER TABLE [Customers] ADD PERIOD FOR SYSTEM_TIME ([Start], [End]) """, - // - """ + // + """ ALTER TABLE [Customers] ALTER COLUMN [Start] ADD HIDDEN """, - // - """ + // + """ ALTER TABLE [Customers] ALTER COLUMN [End] ADD HIDDEN """, - // - """ + // + """ DECLARE @historyTableSchema sysname = SCHEMA_NAME() EXEC(N'ALTER TABLE [Customers] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema + '].[HistoryTable]))') """); @@ -9802,28 +9805,28 @@ FROM [sys].[default_constraints] [d] IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var0 + '];'); ALTER TABLE [Customers] DROP COLUMN [Number]; """, - // - """ + // + """ ALTER TABLE [Customers] ADD [End] datetime2 NOT NULL DEFAULT '9999-12-31T23:59:59.9999999'; """, - // - """ + // + """ ALTER TABLE [Customers] ADD [Start] datetime2 NOT NULL DEFAULT '0001-01-01T00:00:00.0000000'; """, - // - """ + // + """ ALTER TABLE [Customers] ADD PERIOD FOR SYSTEM_TIME ([Start], [End]) """, - // - """ + // + """ ALTER TABLE [Customers] ALTER COLUMN [Start] ADD HIDDEN """, - // - """ + // + """ ALTER TABLE [Customers] ALTER COLUMN [End] ADD HIDDEN """, - // - """ + // + """ DECLARE @historyTableSchema sysname = SCHEMA_NAME() EXEC(N'ALTER TABLE [Customers] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema + '].[HistoryTable]))') """); @@ -9883,28 +9886,28 @@ await Test( """ EXEC sp_rename N'[Customers].[Number]', N'NewNumber', 'COLUMN'; """, - // - """ + // + """ ALTER TABLE [Customers] ADD [End] datetime2 NOT NULL DEFAULT '9999-12-31T23:59:59.9999999'; """, - // - """ + // + """ ALTER TABLE [Customers] ADD [Start] datetime2 NOT NULL DEFAULT '0001-01-01T00:00:00.0000000'; """, - // - """ + // + """ ALTER TABLE [Customers] ADD PERIOD FOR SYSTEM_TIME ([Start], [End]) """, - // - """ + // + """ ALTER TABLE [Customers] ALTER COLUMN [Start] ADD HIDDEN """, - // - """ + // + """ ALTER TABLE [Customers] ALTER COLUMN [End] ADD HIDDEN """, - // - """ + // + """ DECLARE @historyTableSchema sysname = SCHEMA_NAME() EXEC(N'ALTER TABLE [Customers] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema + '].[HistoryTable]))') """); @@ -9924,13 +9927,12 @@ await Test( e.Property("Name"); e.ToTable( "Customers", tb => tb.IsTemporal( - ttb => - { - ttb.UseHistoryTable("HistoryTable"); - ttb.HasPeriodStart("Start"); - ttb.HasPeriodEnd("End"); - })); - + ttb => + { + ttb.UseHistoryTable("HistoryTable"); + ttb.HasPeriodStart("Start"); + ttb.HasPeriodEnd("End"); + })); }), builder => builder.Entity( "Customer", e => @@ -9960,12 +9962,12 @@ await Test( """ ALTER TABLE [Customers] SET (SYSTEM_VERSIONING = OFF) """, - // - """ + // + """ ALTER TABLE [Customers] DROP PERIOD FOR SYSTEM_TIME """, - // - """ + // + """ DECLARE @var0 sysname; SELECT @var0 = [d].[name] FROM [sys].[default_constraints] [d] @@ -9974,8 +9976,8 @@ FROM [sys].[default_constraints] [d] IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var0 + '];'); ALTER TABLE [Customers] DROP COLUMN [End]; """, - // - """ + // + """ DECLARE @var1 sysname; SELECT @var1 = [d].[name] FROM [sys].[default_constraints] [d] @@ -9984,12 +9986,12 @@ FROM [sys].[default_constraints] [d] IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var1 + '];'); ALTER TABLE [Customers] DROP COLUMN [Start]; """, - // - """ + // + """ DROP TABLE [HistoryTable]; """, - // - """ + // + """ ALTER TABLE [Customers] ADD [Number] int NOT NULL DEFAULT 0; """); } @@ -10042,12 +10044,12 @@ await Test( """ ALTER TABLE [Customers] SET (SYSTEM_VERSIONING = OFF) """, - // - """ + // + """ ALTER TABLE [Customers] DROP PERIOD FOR SYSTEM_TIME """, - // - """ + // + """ DECLARE @var0 sysname; SELECT @var0 = [d].[name] FROM [sys].[default_constraints] [d] @@ -10056,8 +10058,8 @@ FROM [sys].[default_constraints] [d] IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var0 + '];'); ALTER TABLE [Customers] DROP COLUMN [End]; """, - // - """ + // + """ DECLARE @var1 sysname; SELECT @var1 = [d].[name] FROM [sys].[default_constraints] [d] @@ -10066,8 +10068,8 @@ FROM [sys].[default_constraints] [d] IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var1 + '];'); ALTER TABLE [Customers] DROP COLUMN [Number]; """, - // - """ + // + """ DECLARE @var2 sysname; SELECT @var2 = [d].[name] FROM [sys].[default_constraints] [d] @@ -10076,8 +10078,8 @@ FROM [sys].[default_constraints] [d] IF @var2 IS NOT NULL EXEC(N'ALTER TABLE [HistoryTable] DROP CONSTRAINT [' + @var2 + '];'); ALTER TABLE [HistoryTable] DROP COLUMN [Number]; """, - // - """ + // + """ DECLARE @var3 sysname; SELECT @var3 = [d].[name] FROM [sys].[default_constraints] [d] @@ -10086,8 +10088,8 @@ FROM [sys].[default_constraints] [d] IF @var3 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var3 + '];'); ALTER TABLE [Customers] DROP COLUMN [Start]; """, - // - """ + // + """ DROP TABLE [HistoryTable]; """); } @@ -10142,12 +10144,12 @@ await Test( """ ALTER TABLE [Customers] SET (SYSTEM_VERSIONING = OFF) """, - // - """ + // + """ ALTER TABLE [Customers] DROP PERIOD FOR SYSTEM_TIME """, - // - """ + // + """ DECLARE @var0 sysname; SELECT @var0 = [d].[name] FROM [sys].[default_constraints] [d] @@ -10156,8 +10158,8 @@ FROM [sys].[default_constraints] [d] IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var0 + '];'); ALTER TABLE [Customers] DROP COLUMN [End]; """, - // - """ + // + """ DECLARE @var1 sysname; SELECT @var1 = [d].[name] FROM [sys].[default_constraints] [d] @@ -10166,12 +10168,12 @@ FROM [sys].[default_constraints] [d] IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var1 + '];'); ALTER TABLE [Customers] DROP COLUMN [Start]; """, - // - """ + // + """ EXEC sp_rename N'[Customers].[Number]', N'NewNumber', 'COLUMN'; """, - // - """ + // + """ DROP TABLE [HistoryTable]; """); } @@ -10710,19 +10712,18 @@ await Test( Assert.Same( historyTable.Columns.Single(c => c.Name == "Id"), Assert.Single(historyTable.PrimaryKey!.Columns)); - }); AssertSql( """ ALTER TABLE [Customers] SET (SYSTEM_VERSIONING = OFF) """, - // - """ + // + """ ALTER TABLE [Customers] DROP PERIOD FOR SYSTEM_TIME """, - // - """ + // + """ DECLARE @var0 sysname; SELECT @var0 = [d].[name] FROM [sys].[default_constraints] [d] @@ -10731,8 +10732,8 @@ FROM [sys].[default_constraints] [d] IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var0 + '];'); ALTER TABLE [Customers] DROP COLUMN [End]; """, - // - """ + // + """ DECLARE @var1 sysname; SELECT @var1 = [d].[name] FROM [sys].[default_constraints] [d] @@ -10741,12 +10742,12 @@ FROM [sys].[default_constraints] [d] IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var1 + '];'); ALTER TABLE [Customers] DROP COLUMN [Start]; """, - // - """ + // + """ DROP TABLE [HistoryTable]; """, - // - """ + // + """ CREATE TABLE [HistoryTable] ( [Id] int NOT NULL IDENTITY, [Name] nvarchar(max) NULL, @@ -10762,7 +10763,7 @@ public override async Task Add_required_primitive_collection_to_existing_table() await base.Add_required_primitive_collection_to_existing_table(); AssertSql( -""" + """ ALTER TABLE [Customers] ADD [Numbers] nvarchar(max) NOT NULL DEFAULT N'[]'; """); } @@ -10773,7 +10774,7 @@ public override async Task Add_required_primitive_collection_with_custom_default await base.Add_required_primitive_collection_with_custom_default_value_to_existing_table(); AssertSql( -""" + """ ALTER TABLE [Customers] ADD [Numbers] nvarchar(max) NOT NULL DEFAULT N'[1,2,3]'; """); } @@ -10784,7 +10785,7 @@ public override async Task Add_required_primitive_collection_with_custom_default await base.Add_required_primitive_collection_with_custom_default_value_sql_to_existing_table_core("N'[3, 2, 1]'"); AssertSql( -""" + """ ALTER TABLE [Customers] ADD [Numbers] nvarchar(max) NOT NULL DEFAULT (N'[3, 2, 1]'); """); } @@ -10795,7 +10796,7 @@ public override async Task Add_required_primitive_collection_with_custom_convert await base.Add_required_primitive_collection_with_custom_converter_to_existing_table(); AssertSql( -""" + """ ALTER TABLE [Customers] ADD [Numbers] nvarchar(max) NOT NULL DEFAULT N'nothing'; """); } @@ -10806,7 +10807,7 @@ public override async Task Add_required_primitive_collection_with_custom_convert await base.Add_required_primitive_collection_with_custom_converter_and_custom_default_value_to_existing_table(); AssertSql( -""" + """ ALTER TABLE [Customers] ADD [Numbers] nvarchar(max) NOT NULL DEFAULT N'some numbers'; """); } @@ -10817,7 +10818,7 @@ public override async Task Add_optional_primitive_collection_to_existing_table() await base.Add_optional_primitive_collection_to_existing_table(); AssertSql( -""" + """ ALTER TABLE [Customers] ADD [Numbers] nvarchar(max) NULL; """); } @@ -10828,7 +10829,7 @@ public override async Task Create_table_with_required_primitive_collection() await base.Create_table_with_required_primitive_collection(); AssertSql( -""" + """ CREATE TABLE [Customers] ( [Id] int NOT NULL IDENTITY, [Name] nvarchar(max) NULL, @@ -10844,7 +10845,7 @@ public override async Task Create_table_with_optional_primitive_collection() await base.Create_table_with_optional_primitive_collection(); AssertSql( -""" + """ CREATE TABLE [Customers] ( [Id] int NOT NULL IDENTITY, [Name] nvarchar(max) NULL, @@ -10860,7 +10861,7 @@ public override async Task Create_table_with_complex_type_with_required_properti await base.Create_table_with_complex_type_with_required_properties_on_derived_entity_in_TPH(); AssertSql( -""" + """ CREATE TABLE [Contacts] ( [Id] int NOT NULL IDENTITY, [Discriminator] nvarchar(8) NOT NULL, @@ -10880,7 +10881,7 @@ public override async Task Add_required_primitve_collection_to_existing_table() await base.Add_required_primitve_collection_to_existing_table(); AssertSql( -""" + """ ALTER TABLE [Customers] ADD [Numbers] nvarchar(max) NOT NULL DEFAULT N'[]'; """); } @@ -10891,7 +10892,7 @@ public override async Task Add_required_primitve_collection_with_custom_default_ await base.Add_required_primitve_collection_with_custom_default_value_to_existing_table(); AssertSql( -""" + """ ALTER TABLE [Customers] ADD [Numbers] nvarchar(max) NOT NULL DEFAULT N'[1,2,3]'; """); } @@ -10902,7 +10903,7 @@ public override async Task Add_required_primitve_collection_with_custom_default_ await base.Add_required_primitve_collection_with_custom_default_value_sql_to_existing_table_core("N'[3, 2, 1]'"); AssertSql( -""" + """ ALTER TABLE [Customers] ADD [Numbers] nvarchar(max) NOT NULL DEFAULT (N'[3, 2, 1]'); """); } @@ -10913,7 +10914,7 @@ public override async Task Add_required_primitve_collection_with_custom_converte await base.Add_required_primitve_collection_with_custom_converter_to_existing_table(); AssertSql( -""" + """ ALTER TABLE [Customers] ADD [Numbers] nvarchar(max) NOT NULL DEFAULT N'nothing'; """); } @@ -10924,7 +10925,7 @@ public override async Task Add_required_primitve_collection_with_custom_converte await base.Add_required_primitve_collection_with_custom_converter_and_custom_default_value_to_existing_table(); AssertSql( -""" + """ ALTER TABLE [Customers] ADD [Numbers] nvarchar(max) NOT NULL DEFAULT N'some numbers'; """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/ModelBuilding/SqlServerModelBuilderGenericTest.cs b/test/EFCore.SqlServer.FunctionalTests/ModelBuilding/SqlServerModelBuilderGenericTest.cs index 1a15b80ea0c..daad9ed50d9 100644 --- a/test/EFCore.SqlServer.FunctionalTests/ModelBuilding/SqlServerModelBuilderGenericTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/ModelBuilding/SqlServerModelBuilderGenericTest.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable InconsistentNaming + namespace Microsoft.EntityFrameworkCore.ModelBuilding; public class SqlServerModelBuilderGenericTest : SqlServerModelBuilderTestBase diff --git a/test/EFCore.SqlServer.FunctionalTests/ModelBuilding/SqlServerModelBuilderNonGenericTest.cs b/test/EFCore.SqlServer.FunctionalTests/ModelBuilding/SqlServerModelBuilderNonGenericTest.cs index 2dad5cd3892..02d2093ec15 100644 --- a/test/EFCore.SqlServer.FunctionalTests/ModelBuilding/SqlServerModelBuilderNonGenericTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/ModelBuilding/SqlServerModelBuilderNonGenericTest.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable InconsistentNaming + namespace Microsoft.EntityFrameworkCore.ModelBuilding; public class SqlServerModelBuilderNonGenericTest : SqlServerModelBuilderTestBase diff --git a/test/EFCore.SqlServer.FunctionalTests/ModelBuilding/SqlServerModelBuilderTestBase.cs b/test/EFCore.SqlServer.FunctionalTests/ModelBuilding/SqlServerModelBuilderTestBase.cs index d71b777c2b9..9b20c495e9e 100644 --- a/test/EFCore.SqlServer.FunctionalTests/ModelBuilding/SqlServerModelBuilderTestBase.cs +++ b/test/EFCore.SqlServer.FunctionalTests/ModelBuilding/SqlServerModelBuilderTestBase.cs @@ -8,7 +8,8 @@ namespace Microsoft.EntityFrameworkCore.ModelBuilding; public class SqlServerModelBuilderTestBase : RelationalModelBuilderTest { - public abstract class SqlServerNonRelationship(SqlServerModelBuilderFixture fixture) : RelationalNonRelationshipTestBase(fixture), IClassFixture + public abstract class SqlServerNonRelationship(SqlServerModelBuilderFixture fixture) + : RelationalNonRelationshipTestBase(fixture), IClassFixture { [ConditionalFact] public virtual void Index_has_a_filter_if_nonclustered_unique_with_nullable_properties() @@ -269,9 +270,10 @@ public virtual void Can_set_collation_for_primitive_collection() [InlineData(false)] public virtual void Can_avoid_attributes_when_discovering_properties(bool useAttributes) { - var modelBuilder = CreateModelBuilder(c => c.Conventions.Replace( - s => new PropertyDiscoveryConvention( - s.GetService()!, useAttributes))); + var modelBuilder = CreateModelBuilder( + c => c.Conventions.Replace( + s => new PropertyDiscoveryConvention( + s.GetService()!, useAttributes))); modelBuilder.Entity(); if (useAttributes) @@ -279,12 +281,14 @@ public virtual void Can_avoid_attributes_when_discovering_properties(bool useAtt var model = modelBuilder.FinalizeModel(); var entityType = model.FindEntityType(typeof(SqlVariantEntity))!; - Assert.Equal([nameof(SqlVariantEntity.Id), nameof(SqlVariantEntity.Value),], + Assert.Equal( + [nameof(SqlVariantEntity.Id), nameof(SqlVariantEntity.Value),], entityType.GetProperties().Select(p => p.Name)); } else { - Assert.Equal(CoreStrings.PropertyNotAdded(nameof(SqlVariantEntity), nameof(SqlVariantEntity.Value), "object"), + Assert.Equal( + CoreStrings.PropertyNotAdded(nameof(SqlVariantEntity), nameof(SqlVariantEntity.Value), "object"), Assert.Throws(modelBuilder.FinalizeModel).Message); } } @@ -292,14 +296,17 @@ public virtual void Can_avoid_attributes_when_discovering_properties(bool useAtt protected class SqlVariantEntity { public int Id { get; set; } + [Column(TypeName = "sql_variant")] public object? Value { get; set; } } } - public abstract class SqlServerComplexType(SqlServerModelBuilderFixture fixture) : RelationalComplexTypeTestBase(fixture), IClassFixture; + public abstract class SqlServerComplexType(SqlServerModelBuilderFixture fixture) + : RelationalComplexTypeTestBase(fixture), IClassFixture; - public abstract class SqlServerInheritance(SqlServerModelBuilderFixture fixture) : RelationalInheritanceTestBase(fixture), IClassFixture + public abstract class SqlServerInheritance(SqlServerModelBuilderFixture fixture) + : RelationalInheritanceTestBase(fixture), IClassFixture { [ConditionalFact] // #7240 public void Can_use_shadow_FK_that_collides_with_convention_shadow_FK_on_other_derived_type() @@ -642,7 +649,8 @@ protected class DisjointChildSubclass1 : Child; protected class DisjointChildSubclass2 : Child; } - public abstract class SqlServerOneToMany(SqlServerModelBuilderFixture fixture) : RelationalOneToManyTestBase(fixture), IClassFixture + public abstract class SqlServerOneToMany(SqlServerModelBuilderFixture fixture) + : RelationalOneToManyTestBase(fixture), IClassFixture { [ConditionalFact] public virtual void Shadow_foreign_keys_to_generic_types_have_terrible_names_that_should_not_change() @@ -695,11 +703,14 @@ protected class Company; protected class User; } - public abstract class SqlServerManyToOne(SqlServerModelBuilderFixture fixture) : RelationalManyToOneTestBase(fixture), IClassFixture; + public abstract class SqlServerManyToOne(SqlServerModelBuilderFixture fixture) + : RelationalManyToOneTestBase(fixture), IClassFixture; - public abstract class SqlServerOneToOne(SqlServerModelBuilderFixture fixture) : RelationalOneToOneTestBase(fixture), IClassFixture; + public abstract class SqlServerOneToOne(SqlServerModelBuilderFixture fixture) + : RelationalOneToOneTestBase(fixture), IClassFixture; - public abstract class SqlServerManyToMany(SqlServerModelBuilderFixture fixture) : RelationalManyToManyTestBase(fixture), IClassFixture + public abstract class SqlServerManyToMany(SqlServerModelBuilderFixture fixture) + : RelationalManyToManyTestBase(fixture), IClassFixture { [ConditionalFact] public virtual void Join_entity_type_uses_same_schema() @@ -758,7 +769,8 @@ public virtual void Join_entity_type_uses_default_schema_if_related_are_differen } } - public abstract class SqlServerOwnedTypes(SqlServerModelBuilderFixture fixture) : RelationalOwnedTypesTestBase(fixture), IClassFixture + public abstract class SqlServerOwnedTypes(SqlServerModelBuilderFixture fixture) + : RelationalOwnedTypesTestBase(fixture), IClassFixture { [ConditionalFact] public virtual void Owned_types_use_table_splitting_by_default() @@ -1621,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); }); @@ -1630,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] @@ -2035,67 +2063,12 @@ 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 { - public override TestHelpers TestHelpers => SqlServerTestHelpers.Instance; + public override TestHelpers TestHelpers + => SqlServerTestHelpers.Instance; } public abstract class TestTemporalTableBuilder @@ -2106,8 +2079,9 @@ public abstract class TestTemporalTableBuilder public abstract TestTemporalPeriodPropertyBuilder HasPeriodEnd(string propertyName); } - public class GenericTestTemporalTableBuilder(TemporalTableBuilder temporalTableBuilder) : TestTemporalTableBuilder, - IInfrastructure> + public class GenericTestTemporalTableBuilder(TemporalTableBuilder temporalTableBuilder) + : TestTemporalTableBuilder, + IInfrastructure> where TEntity : class { private TemporalTableBuilder TemporalTableBuilder { get; } = temporalTableBuilder; @@ -2128,7 +2102,8 @@ public override TestTemporalPeriodPropertyBuilder HasPeriodEnd(string propertyNa => new(TemporalTableBuilder.HasPeriodEnd(propertyName)); } - public class NonGenericTestTemporalTableBuilder(TemporalTableBuilder temporalTableBuilder) : TestTemporalTableBuilder, IInfrastructure + public class NonGenericTestTemporalTableBuilder(TemporalTableBuilder temporalTableBuilder) + : TestTemporalTableBuilder, IInfrastructure where TEntity : class { private TemporalTableBuilder TemporalTableBuilder { get; } = temporalTableBuilder; @@ -2187,7 +2162,8 @@ public override TestOwnedNavigationTemporalPeriodPropertyBuilder HasPeriodEnd(st => new(TemporalTableBuilder.HasPeriodEnd(propertyName)); } - public class NonGenericTestOwnedNavigationTemporalTableBuilder(OwnedNavigationTemporalTableBuilder temporalTableBuilder) : + public class NonGenericTestOwnedNavigationTemporalTableBuilder( + OwnedNavigationTemporalTableBuilder temporalTableBuilder) : TestOwnedNavigationTemporalTableBuilder, IInfrastructure where TOwnerEntity : class @@ -2220,7 +2196,8 @@ public TestTemporalPeriodPropertyBuilder HasColumnName(string name) => new(TemporalPeriodPropertyBuilder.HasColumnName(name)); } - public class TestOwnedNavigationTemporalPeriodPropertyBuilder(OwnedNavigationTemporalPeriodPropertyBuilder temporalPeriodPropertyBuilder) + public class TestOwnedNavigationTemporalPeriodPropertyBuilder( + OwnedNavigationTemporalPeriodPropertyBuilder temporalPeriodPropertyBuilder) { protected OwnedNavigationTemporalPeriodPropertyBuilder TemporalPeriodPropertyBuilder { get; } = temporalPeriodPropertyBuilder; diff --git a/test/EFCore.SqlServer.FunctionalTests/MonsterFixupChangedChangingSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/MonsterFixupChangedChangingSqlServerTest.cs index 9b7f4b9158d..5a122723726 100644 --- a/test/EFCore.SqlServer.FunctionalTests/MonsterFixupChangedChangingSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/MonsterFixupChangedChangingSqlServerTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class MonsterFixupChangedChangingSqlServerTest(MonsterFixupChangedChangingSqlServerTest.MonsterFixupChangedChangingSqlServerFixture fixture) : +public class MonsterFixupChangedChangingSqlServerTest( + MonsterFixupChangedChangingSqlServerTest.MonsterFixupChangedChangingSqlServerFixture fixture) : MonsterFixupTestBase(fixture) { public class MonsterFixupChangedChangingSqlServerFixture : MonsterFixupChangedChangingFixtureBase diff --git a/test/EFCore.SqlServer.FunctionalTests/MusicStoreSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/MusicStoreSqlServerTest.cs index 4ce9c31380a..c5913da5417 100644 --- a/test/EFCore.SqlServer.FunctionalTests/MusicStoreSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/MusicStoreSqlServerTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class MusicStoreSqlServerTest(MusicStoreSqlServerTest.MusicStoreSqlServerFixture fixture) : MusicStoreTestBase(fixture) +public class MusicStoreSqlServerTest(MusicStoreSqlServerTest.MusicStoreSqlServerFixture fixture) + : MusicStoreTestBase(fixture) { public class MusicStoreSqlServerFixture : MusicStoreFixtureBase { diff --git a/test/EFCore.SqlServer.FunctionalTests/OptimisticConcurrencySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/OptimisticConcurrencySqlServerTest.cs index d0ec7df169d..dc032d134bf 100644 --- a/test/EFCore.SqlServer.FunctionalTests/OptimisticConcurrencySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/OptimisticConcurrencySqlServerTest.cs @@ -8,7 +8,8 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class OptimisticConcurrencyULongSqlServerTest(F1ULongSqlServerFixture fixture) : OptimisticConcurrencySqlServerTestBase(fixture) +public class OptimisticConcurrencyULongSqlServerTest(F1ULongSqlServerFixture fixture) + : OptimisticConcurrencySqlServerTestBase(fixture) { [ConditionalFact] public async Task ULong_row_version_can_handle_empty_array_from_the_database() @@ -67,7 +68,8 @@ public Task Ulong_row_version_with_TPC_and_table_splitting(bool updateDependentF => Row_version_with_table_splitting(updateDependentFirst, Mapping.Tpc, "ULongVersion"); } -public class OptimisticConcurrencySqlServerTest(F1SqlServerFixture fixture) : OptimisticConcurrencySqlServerTestBase(fixture) +public class OptimisticConcurrencySqlServerTest(F1SqlServerFixture fixture) + : OptimisticConcurrencySqlServerTestBase(fixture) { [ConditionalTheory] [InlineData(true)] diff --git a/test/EFCore.SqlServer.FunctionalTests/OverzealousInitializationSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/OverzealousInitializationSqlServerTest.cs index 4d4edc012c2..a224f14ec3b 100644 --- a/test/EFCore.SqlServer.FunctionalTests/OverzealousInitializationSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/OverzealousInitializationSqlServerTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class OverzealousInitializationSqlServerTest(OverzealousInitializationSqlServerTest.OverzealousInitializationSqlServerFixture fixture) +public class OverzealousInitializationSqlServerTest( + OverzealousInitializationSqlServerTest.OverzealousInitializationSqlServerFixture fixture) : OverzealousInitializationTestBase(fixture) { public class OverzealousInitializationSqlServerFixture : OverzealousInitializationFixtureBase diff --git a/test/EFCore.SqlServer.FunctionalTests/PropertyValuesSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/PropertyValuesSqlServerTest.cs index 32cd97b4ecf..0802d269a13 100644 --- a/test/EFCore.SqlServer.FunctionalTests/PropertyValuesSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/PropertyValuesSqlServerTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class PropertyValuesSqlServerTest(PropertyValuesSqlServerTest.PropertyValuesSqlServerFixture fixture) : PropertyValuesTestBase(fixture) +public class PropertyValuesSqlServerTest(PropertyValuesSqlServerTest.PropertyValuesSqlServerFixture fixture) + : PropertyValuesTestBase(fixture) { public class PropertyValuesSqlServerFixture : PropertyValuesFixtureBase { diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocAdvancedMappingsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocAdvancedMappingsQuerySqlServerTest.cs index cd5b5c20dcc..6f0bce9d4dd 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocAdvancedMappingsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocAdvancedMappingsQuerySqlServerTest.cs @@ -15,7 +15,7 @@ public override async Task Setting_IsUnicode_generates_unicode_literal_in_SQL() await base.Setting_IsUnicode_generates_unicode_literal_in_SQL(); AssertSql( -""" + """ SELECT [t].[Id], [t].[Nombre] FROM [TipoServicio] AS [t] WHERE [t].[Nombre] LIKE '%lla%' @@ -53,7 +53,7 @@ public override async Task Projection_failing_with_EnumToStringConverter() await base.Projection_failing_with_EnumToStringConverter(); AssertSql( -""" + """ SELECT [p].[Id], [p].[Name], CASE WHEN [c].[Id] IS NULL THEN N'Other' ELSE [c].[Name] @@ -71,26 +71,26 @@ public override async Task Expression_tree_constructed_via_interface_works() await base.Expression_tree_constructed_via_interface_works(); AssertSql( -""" + """ SELECT [r].[Id], [r].[IsRemoved], [r].[Removed], [r].[RemovedByUser], [r].[OwnedEntity_Exists], [r].[OwnedEntity_OwnedValue] FROM [RemovableEntities] AS [r] WHERE [r].[IsRemoved] = CAST(0 AS bit) """, - // - """ + // + """ SELECT [p].[Id], [p].[RemovableEntityId] FROM [Parents] AS [p] LEFT JOIN [RemovableEntities] AS [r] ON [p].[RemovableEntityId] = [r].[Id] WHERE [r].[IsRemoved] = CAST(1 AS bit) """, - // - """ + // + """ SELECT [r].[Id], [r].[IsRemoved], [r].[Removed], [r].[RemovedByUser], [r].[OwnedEntity_Exists], [r].[OwnedEntity_OwnedValue] FROM [RemovableEntities] AS [r] WHERE [r].[OwnedEntity_OwnedValue] = N'Abc' """, - // - """ + // + """ @__id_0='1' SELECT [p].[Id], [p].[RemovableEntityId] @@ -104,7 +104,7 @@ public override async Task Double_convert_interface_created_expression_tree() await base.Double_convert_interface_created_expression_tree(); AssertSql( -""" + """ @__action_0='1' SELECT COUNT(*) @@ -121,15 +121,15 @@ public override async Task Casts_are_removed_from_expression_tree_when_redundant await base.Casts_are_removed_from_expression_tree_when_redundant(); AssertSql( -""" + """ @__id_0='1' SELECT TOP(1) [m].[Id], [m].[Name], [m].[NavigationEntityId] FROM [MockEntities] AS [m] WHERE [m].[Id] = @__id_0 """, - // - """ + // + """ SELECT COUNT(*) FROM [MockEntities] AS [m] """); @@ -140,7 +140,7 @@ public override async Task Can_query_hierarchy_with_non_nullable_property_on_der await base.Can_query_hierarchy_with_non_nullable_property_on_derived(); AssertSql( -""" + """ SELECT [b].[Id], [b].[Name], [b].[Type], [b].[IsOnline] FROM [Businesses] AS [b] """); @@ -151,7 +151,7 @@ public override async Task Query_generates_correct_datetime2_parameter_definitio await base.Query_generates_correct_datetime2_parameter_definition(fractionalSeconds, postfix); AssertSql( -$""" + $""" @__parameter_0='2021-11-12T13:14:15.1234567'{postfix} SELECT TOP(1) [e].[DateTime] @@ -165,7 +165,7 @@ public override async Task Query_generates_correct_datetimeoffset_parameter_defi await base.Query_generates_correct_datetimeoffset_parameter_definition(fractionalSeconds, postfix); AssertSql( -$""" + $""" @__parameter_0='2021-11-12T13:14:15.1234567+10:00'{postfix} SELECT TOP(1) [e].[DateTimeOffset] @@ -179,7 +179,7 @@ public override async Task Query_generates_correct_timespan_parameter_definition await base.Query_generates_correct_timespan_parameter_definition(fractionalSeconds, postfix); AssertSql( -$""" + $""" @__parameter_0='12:34:56.7890123'{postfix} SELECT TOP(1) [e].[TimeSpan] @@ -241,13 +241,13 @@ public override async Task Two_similar_complex_properties_projected_with_split_q await base.Two_similar_complex_properties_projected_with_split_query1(); AssertSql( -""" + """ SELECT [o].[Id] FROM [Offers] AS [o] ORDER BY [o].[Id] """, - // - """ + // + """ SELECT [s].[Id], [s].[NestedId], [s].[OfferId], [s].[payment_brutto], [s].[payment_netto], [s].[Id0], [s].[payment_brutto0], [s].[payment_netto0], [o].[Id] FROM [Offers] AS [o] INNER JOIN ( @@ -264,14 +264,14 @@ public override async Task Two_similar_complex_properties_projected_with_split_q await base.Two_similar_complex_properties_projected_with_split_query2(); AssertSql( -""" + """ SELECT TOP(2) [o].[Id] FROM [Offers] AS [o] WHERE [o].[Id] = 1 ORDER BY [o].[Id] """, - // - """ + // + """ SELECT [s].[Id], [s].[NestedId], [s].[OfferId], [s].[payment_brutto], [s].[payment_netto], [s].[Id0], [s].[payment_brutto0], [s].[payment_netto0], [o0].[Id] FROM ( SELECT TOP(1) [o].[Id] @@ -292,7 +292,7 @@ public override async Task Projecting_one_of_two_similar_complex_types_picks_the await base.Projecting_one_of_two_similar_complex_types_picks_the_correct_one(); AssertSql( -""" + """ @__p_0='10' SELECT [a].[Id], [s].[Info_Created0] AS [Created] diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocJsonQuerySqlServerJsonTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocJsonQuerySqlServerJsonTypeTest.cs new file mode 100644 index 00000000000..fb0e7c2d8ec --- /dev/null +++ b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocJsonQuerySqlServerJsonTypeTest.cs @@ -0,0 +1,42 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#nullable disable +using Microsoft.Data.SqlClient; + +namespace Microsoft.EntityFrameworkCore.Query; + +[SqlServerCondition(SqlServerCondition.SupportsJsonType)] +public class AdHocJsonQuerySqlServerJsonTypeTest : AdHocJsonQuerySqlServerTestBase +{ + public override async Task Missing_navigation_works_with_deduplication(bool async) + { + // TODO:SQLJSON Returns empty (invalid) JSON (See BadJson.cs) + if (async) + { + Assert.Equal( + "Unable to cast object of type 'System.DBNull' to type 'System.String'.", + (await Assert.ThrowsAsync(() => base.Missing_navigation_works_with_deduplication(true))).Message); + } + else + { + Assert.Equal( + RelationalStrings.JsonEmptyString, + (await Assert.ThrowsAsync(() => base.Missing_navigation_works_with_deduplication(false))) + .Message); + } + } + + public override async Task Contains_on_nested_collection_with_init_only_navigation(bool async) + // TODO:SQLJSON (See JsonTypeToFunction.cs) + => Assert.Equal( + "OpenJson support not yet supported for JSON native data type.", + (await Assert.ThrowsAsync( + () => base.Contains_on_nested_collection_with_init_only_navigation(async))).Message); + + protected override string StoreName + => "AdHocJsonQueryJsonTypeTest"; + + protected override string JsonColumnType + => "json"; +} diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocJsonQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocJsonQuerySqlServerTest.cs index 3f42c52b152..a9da97566d4 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocJsonQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocJsonQuerySqlServerTest.cs @@ -1,384 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Data.SqlClient; -using Microsoft.EntityFrameworkCore.Diagnostics.Internal; -using Microsoft.EntityFrameworkCore.SqlServer.Diagnostics.Internal; - namespace Microsoft.EntityFrameworkCore.Query; -#nullable disable - -public class AdHocJsonQuerySqlServerTest : AdHocJsonQueryTestBase +public class AdHocJsonQuerySqlServerTest : AdHocJsonQuerySqlServerTestBase { - protected override ITestStoreFactory TestStoreFactory - => SqlServerTestStoreFactory.Instance; - - protected override async Task Seed29219(MyContext29219 ctx) - { - var entity1 = new MyEntity29219 - { - Id = 1, - Reference = new MyJsonEntity29219 { NonNullableScalar = 10, NullableScalar = 11 }, - Collection = - [ - new() { NonNullableScalar = 100, NullableScalar = 101 }, - new() { NonNullableScalar = 200, NullableScalar = 201 }, - new() { NonNullableScalar = 300, NullableScalar = null } - ] - }; - - var entity2 = new MyEntity29219 - { - Id = 2, - Reference = new MyJsonEntity29219 { NonNullableScalar = 20, NullableScalar = null }, - Collection = [new() { NonNullableScalar = 1001, NullableScalar = null }] - }; - - ctx.Entities.AddRange(entity1, entity2); - await ctx.SaveChangesAsync(); - - await ctx.Database.ExecuteSqlAsync( - $$""" -INSERT INTO [Entities] ([Id], [Reference], [Collection]) -VALUES(3, N'{ "NonNullableScalar" : 30 }', N'[{ "NonNullableScalar" : 10001 }]') -"""); - } - - protected override async Task Seed30028(MyContext30028 ctx) - { - // complete - await ctx.Database.ExecuteSqlAsync( - $$$$""" -INSERT INTO [Entities] ([Id], [Json]) -VALUES( -1, -N'{"RootName":"e1","Collection":[{"BranchName":"e1 c1","Nested":{"LeafName":"e1 c1 l"}},{"BranchName":"e1 c2","Nested":{"LeafName":"e1 c2 l"}}],"OptionalReference":{"BranchName":"e1 or","Nested":{"LeafName":"e1 or l"}},"RequiredReference":{"BranchName":"e1 rr","Nested":{"LeafName":"e1 rr l"}}}') -"""); - - // missing collection - await ctx.Database.ExecuteSqlAsync( - $$$$""" -INSERT INTO [Entities] ([Id], [Json]) -VALUES( -2, -N'{"RootName":"e2","OptionalReference":{"BranchName":"e2 or","Nested":{"LeafName":"e2 or l"}},"RequiredReference":{"BranchName":"e2 rr","Nested":{"LeafName":"e2 rr l"}}}') -"""); - - // missing optional reference - await ctx.Database.ExecuteSqlAsync( - $$$$""" -INSERT INTO [Entities] ([Id], [Json]) -VALUES( -3, -N'{"RootName":"e3","Collection":[{"BranchName":"e3 c1","Nested":{"LeafName":"e3 c1 l"}},{"BranchName":"e3 c2","Nested":{"LeafName":"e3 c2 l"}}],"RequiredReference":{"BranchName":"e3 rr","Nested":{"LeafName":"e3 rr l"}}}') -"""); - - // missing required reference - await ctx.Database.ExecuteSqlAsync( - $$$$""" -INSERT INTO [Entities] ([Id], [Json]) -VALUES( -4, -N'{"RootName":"e4","Collection":[{"BranchName":"e4 c1","Nested":{"LeafName":"e4 c1 l"}},{"BranchName":"e4 c2","Nested":{"LeafName":"e4 c2 l"}}],"OptionalReference":{"BranchName":"e4 or","Nested":{"LeafName":"e4 or l"}}}') -"""); - } - - protected override Task Seed33046(Context33046 ctx) - => ctx.Database.ExecuteSqlAsync( - $$""" -INSERT INTO [Reviews] ([Rounds], [Id]) -VALUES(N'[{"RoundNumber":11,"SubRounds":[{"SubRoundNumber":111},{"SubRoundNumber":112}]}]', 1) -"""); - - protected override Task SeedArrayOfPrimitives(MyContextArrayOfPrimitives ctx) - { - var entity1 = new MyEntityArrayOfPrimitives - { - Id = 1, - Reference = new MyJsonEntityArrayOfPrimitives - { - IntArray = [1, 2, 3], - ListOfString = - [ - "Foo", - "Bar", - "Baz" - ] - }, - Collection = - [ - new() { IntArray = [111, 112, 113], ListOfString = ["Foo11", "Bar11"] }, - new() { IntArray = [211, 212, 213], ListOfString = ["Foo12", "Bar12"] } - ] - }; - - var entity2 = new MyEntityArrayOfPrimitives - { - Id = 2, - Reference = new MyJsonEntityArrayOfPrimitives - { - IntArray = [10, 20, 30], - ListOfString = - [ - "A", - "B", - "C" - ] - }, - Collection = - [ - new() { IntArray = [110, 120, 130], ListOfString = ["A1", "Z1"] }, - new() { IntArray = [210, 220, 230], ListOfString = ["A2", "Z2"] } - ] - }; - - ctx.Entities.AddRange(entity1, entity2); - return ctx.SaveChangesAsync(); - } - - protected override Task SeedJunkInJson(MyContextJunkInJson ctx) - => ctx.Database.ExecuteSqlAsync( - $$$$""" -INSERT INTO [Entities] ([Collection], [CollectionWithCtor], [Reference], [ReferenceWithCtor], [Id]) -VALUES( -N'[{"JunkReference":{"Something":"SomeValue" },"Name":"c11","JunkProperty1":50,"Number":11.5,"JunkCollection1":[],"JunkCollection2":[{"Foo":"junk value"}],"NestedCollection":[{"DoB":"2002-04-01T00:00:00","DummyProp":"Dummy value"},{"DoB":"2002-04-02T00:00:00","DummyReference":{"Foo":5}}],"NestedReference":{"DoB":"2002-03-01T00:00:00"}},{"Name":"c12","Number":12.5,"NestedCollection":[{"DoB":"2002-06-01T00:00:00"},{"DoB":"2002-06-02T00:00:00"}],"NestedDummy":59,"NestedReference":{"DoB":"2002-05-01T00:00:00"}}]', -N'[{"MyBool":true,"Name":"c11 ctor","JunkReference":{"Something":"SomeValue","JunkCollection":[{"Foo":"junk value"}]},"NestedCollection":[{"DoB":"2002-08-01T00:00:00"},{"DoB":"2002-08-02T00:00:00"}],"NestedReference":{"DoB":"2002-07-01T00:00:00"}},{"MyBool":false,"Name":"c12 ctor","NestedCollection":[{"DoB":"2002-10-01T00:00:00"},{"DoB":"2002-10-02T00:00:00"}],"JunkCollection":[{"Foo":"junk value"}],"NestedReference":{"DoB":"2002-09-01T00:00:00"}}]', -N'{"Name":"r1","JunkCollection":[{"Foo":"junk value"}],"JunkReference":{"Something":"SomeValue" },"Number":1.5,"NestedCollection":[{"DoB":"2000-02-01T00:00:00","JunkReference":{"Something":"SomeValue"}},{"DoB":"2000-02-02T00:00:00"}],"NestedReference":{"DoB":"2000-01-01T00:00:00"}}', -N'{"MyBool":true,"JunkCollection":[{"Foo":"junk value"}],"Name":"r1 ctor","JunkReference":{"Something":"SomeValue" },"NestedCollection":[{"DoB":"2001-02-01T00:00:00"},{"DoB":"2001-02-02T00:00:00"}],"NestedReference":{"JunkCollection":[{"Foo":"junk value"}],"DoB":"2001-01-01T00:00:00"}}', -1) -"""); - - protected override Task SeedTrickyBuffering(MyContextTrickyBuffering ctx) - => ctx.Database.ExecuteSqlAsync( - $$$""" -INSERT INTO [Entities] ([Reference], [Id]) -VALUES( -N'{"Name": "r1", "Number": 7, "JunkReference":{"Something": "SomeValue" }, "JunkCollection": [{"Foo": "junk value"}], "NestedReference": {"DoB": "2000-01-01T00:00:00"}, "NestedCollection": [{"DoB": "2000-02-01T00:00:00", "JunkReference": {"Something": "SomeValue"}}, {"DoB": "2000-02-02T00:00:00"}]}',1) -"""); - - protected override Task SeedShadowProperties(MyContextShadowProperties ctx) - => ctx.Database.ExecuteSqlAsync( - $$""" -INSERT INTO [Entities] ([Collection], [CollectionWithCtor], [Reference], [ReferenceWithCtor], [Id], [Name]) -VALUES( -N'[{"Name":"e1_c1","ShadowDouble":5.5},{"ShadowDouble":20.5,"Name":"e1_c2"}]', -N'[{"Name":"e1_c1 ctor","ShadowNullableByte":6},{"ShadowNullableByte":null,"Name":"e1_c2 ctor"}]', -N'{"Name":"e1_r", "ShadowString":"Foo"}', -N'{"ShadowInt":143,"Name":"e1_r ctor"}', -1, -N'e1') -"""); - - protected override async Task SeedNotICollection(MyContextNotICollection ctx) - { - await ctx.Database.ExecuteSqlAsync( - $$""" -INSERT INTO [Entities] ([Json], [Id]) -VALUES( -N'{"Collection":[{"Bar":11,"Foo":"c11"},{"Bar":12,"Foo":"c12"},{"Bar":13,"Foo":"c13"}]}', -1) -"""); - - await ctx.Database.ExecuteSqlAsync( - $$$""" -INSERT INTO [Entities] ([Json], [Id]) -VALUES( -N'{"Collection":[{"Bar":21,"Foo":"c21"},{"Bar":22,"Foo":"c22"}]}', -2) -"""); - } - - #region EnumLegacyValues - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual async Task Read_enum_property_with_legacy_values(bool async) - { - var contextFactory = await InitializeAsync( - seed: SeedEnumLegacyValues); - - using (var context = contextFactory.CreateContext()) - { - var query = context.Entities.Select( - x => new - { - x.Reference.IntEnum, - x.Reference.ByteEnum, - x.Reference.LongEnum, - x.Reference.NullableEnum - }); - - var exception = async - ? await (Assert.ThrowsAsync(() => query.ToListAsync())) - : Assert.Throws(() => query.ToList()); - - // Conversion failed when converting the nvarchar value '...' to data type int - Assert.Equal(245, exception.Number); - } - } - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual async Task Read_json_entity_with_enum_properties_with_legacy_values(bool async) - { - var contextFactory = await InitializeAsync( - seed: SeedEnumLegacyValues, - shouldLogCategory: c => c == DbLoggerCategory.Query.Name); - - using (var context = contextFactory.CreateContext()) - { - var query = context.Entities.Select(x => x.Reference).AsNoTracking(); - - var result = async - ? await query.ToListAsync() - : query.ToList(); - - Assert.Equal(1, result.Count); - Assert.Equal(ByteEnumLegacyValues.Redmond, result[0].ByteEnum); - Assert.Equal(IntEnumLegacyValues.Foo, result[0].IntEnum); - Assert.Equal(LongEnumLegacyValues.Three, result[0].LongEnum); - Assert.Equal(ULongEnumLegacyValues.Three, result[0].ULongEnum); - Assert.Equal(IntEnumLegacyValues.Bar, result[0].NullableEnum); - } - - var testLogger = new TestLogger(); - Assert.Single( - ListLoggerFactory.Log.Where( - l => l.Message == CoreResources.LogStringEnumValueInJson(testLogger).GenerateMessage(nameof(ByteEnumLegacyValues)))); - Assert.Single( - ListLoggerFactory.Log.Where( - l => l.Message == CoreResources.LogStringEnumValueInJson(testLogger).GenerateMessage(nameof(IntEnumLegacyValues)))); - Assert.Single( - ListLoggerFactory.Log.Where( - l => l.Message == CoreResources.LogStringEnumValueInJson(testLogger).GenerateMessage(nameof(LongEnumLegacyValues)))); - Assert.Single( - ListLoggerFactory.Log.Where( - l => l.Message == CoreResources.LogStringEnumValueInJson(testLogger).GenerateMessage(nameof(ULongEnumLegacyValues)))); - } - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual async Task Read_json_entity_collection_with_enum_properties_with_legacy_values(bool async) - { - var contextFactory = await InitializeAsync( - seed: SeedEnumLegacyValues, - shouldLogCategory: c => c == DbLoggerCategory.Query.Name); - - using (var context = contextFactory.CreateContext()) - { - var query = context.Entities.Select(x => x.Collection).AsNoTracking(); - - var result = async - ? await query.ToListAsync() - : query.ToList(); - - Assert.Equal(1, result.Count); - Assert.Equal(2, result[0].Count); - Assert.Equal(ByteEnumLegacyValues.Bellevue, result[0][0].ByteEnum); - Assert.Equal(IntEnumLegacyValues.Foo, result[0][0].IntEnum); - Assert.Equal(LongEnumLegacyValues.One, result[0][0].LongEnum); - Assert.Equal(ULongEnumLegacyValues.One, result[0][0].ULongEnum); - Assert.Equal(IntEnumLegacyValues.Bar, result[0][0].NullableEnum); - Assert.Equal(ByteEnumLegacyValues.Seattle, result[0][1].ByteEnum); - Assert.Equal(IntEnumLegacyValues.Baz, result[0][1].IntEnum); - Assert.Equal(LongEnumLegacyValues.Two, result[0][1].LongEnum); - Assert.Equal(ULongEnumLegacyValues.Two, result[0][1].ULongEnum); - Assert.Null(result[0][1].NullableEnum); - } - - var testLogger = new TestLogger(); - Assert.Single( - ListLoggerFactory.Log.Where( - l => l.Message == CoreResources.LogStringEnumValueInJson(testLogger).GenerateMessage(nameof(ByteEnumLegacyValues)))); - Assert.Single( - ListLoggerFactory.Log.Where( - l => l.Message == CoreResources.LogStringEnumValueInJson(testLogger).GenerateMessage(nameof(IntEnumLegacyValues)))); - Assert.Single( - ListLoggerFactory.Log.Where( - l => l.Message == CoreResources.LogStringEnumValueInJson(testLogger).GenerateMessage(nameof(LongEnumLegacyValues)))); - Assert.Single( - ListLoggerFactory.Log.Where( - l => l.Message == CoreResources.LogStringEnumValueInJson(testLogger).GenerateMessage(nameof(ULongEnumLegacyValues)))); - } - - private Task SeedEnumLegacyValues(MyContextEnumLegacyValues ctx) - => ctx.Database.ExecuteSqlAsync( - $$""" -INSERT INTO [Entities] ([Collection], [Reference], [Id], [Name]) -VALUES( -N'[{"ByteEnum":"Bellevue","IntEnum":"Foo","LongEnum":"One","ULongEnum":"One","Name":"e1_c1","NullableEnum":"Bar"},{"ByteEnum":"Seattle","IntEnum":"Baz","LongEnum":"Two","ULongEnum":"Two","Name":"e1_c2","NullableEnum":null}]', -N'{"ByteEnum":"Redmond","IntEnum":"Foo","LongEnum":"Three","ULongEnum":"Three","Name":"e1_r","NullableEnum":"Bar"}', -1, -N'e1') -"""); - - private class MyContextEnumLegacyValues(DbContextOptions options) : DbContext((new DbContextOptionsBuilder(options)).ConfigureWarnings(b => b.Log(CoreEventId.StringEnumValueInJson)).Options) - { - - // ReSharper disable once UnusedAutoPropertyAccessor.Local - public DbSet Entities { get; set; } - - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - modelBuilder.Entity().Property(x => x.Id).ValueGeneratedNever(); - modelBuilder.Entity().OwnsOne(x => x.Reference, b => b.ToJson()); - modelBuilder.Entity().OwnsMany(x => x.Collection, b => b.ToJson()); - } - } - - private class MyEntityEnumLegacyValues - { - public int Id { get; set; } - public string Name { get; set; } - - public MyJsonEntityEnumLegacyValues Reference { get; set; } - public List Collection { get; set; } - } - - private class MyJsonEntityEnumLegacyValues - { - public string Name { get; set; } - - // ReSharper disable once UnusedAutoPropertyAccessor.Local - public IntEnumLegacyValues IntEnum { get; set; } - // ReSharper disable once UnusedAutoPropertyAccessor.Local - public ByteEnumLegacyValues ByteEnum { get; set; } - // ReSharper disable once UnusedAutoPropertyAccessor.Local - public LongEnumLegacyValues LongEnum { get; set; } - // ReSharper disable once UnusedAutoPropertyAccessor.Local - public ULongEnumLegacyValues ULongEnum { get; set; } - // ReSharper disable once UnusedAutoPropertyAccessor.Local - public IntEnumLegacyValues? NullableEnum { get; set; } - } - - private enum IntEnumLegacyValues - { - Foo = int.MinValue, - Bar, - Baz = int.MaxValue, - } - - private enum ByteEnumLegacyValues : byte - { - Seattle, - Redmond, - Bellevue = 255, - } - - private enum LongEnumLegacyValues : long - { - One = long.MinValue, - Two = 1, - Three = long.MaxValue, - } - - private enum ULongEnumLegacyValues : ulong - { - One = ulong.MinValue, - Two = 1, - Three = ulong.MaxValue, - } - - #endregion } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocJsonQuerySqlServerTestBase.cs b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocJsonQuerySqlServerTestBase.cs new file mode 100644 index 00000000000..ee179b3d6f4 --- /dev/null +++ b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocJsonQuerySqlServerTestBase.cs @@ -0,0 +1,396 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#nullable disable +using Microsoft.Data.SqlClient; +using Microsoft.EntityFrameworkCore.Diagnostics.Internal; +using Microsoft.EntityFrameworkCore.SqlServer.Diagnostics.Internal; + +namespace Microsoft.EntityFrameworkCore.Query; + +public abstract class AdHocJsonQuerySqlServerTestBase : AdHocJsonQueryTestBase +{ + protected override ITestStoreFactory TestStoreFactory + => SqlServerTestStoreFactory.Instance; + + protected override void ConfigureWarnings(WarningsConfigurationBuilder builder) + { + base.ConfigureWarnings(builder); + + builder.Log(CoreEventId.StringEnumValueInJson, SqlServerEventId.JsonTypeExperimental); + } + + protected override async Task Seed29219(DbContext ctx) + { + var entity1 = new MyEntity29219 + { + Id = 1, + Reference = new MyJsonEntity29219 { NonNullableScalar = 10, NullableScalar = 11 }, + Collection = + [ + new MyJsonEntity29219 { NonNullableScalar = 100, NullableScalar = 101 }, + new MyJsonEntity29219 { NonNullableScalar = 200, NullableScalar = 201 }, + new MyJsonEntity29219 { NonNullableScalar = 300, NullableScalar = null } + ] + }; + + var entity2 = new MyEntity29219 + { + Id = 2, + Reference = new MyJsonEntity29219 { NonNullableScalar = 20, NullableScalar = null }, + Collection = [new MyJsonEntity29219 { NonNullableScalar = 1001, NullableScalar = null }] + }; + + ctx.AddRange(entity1, entity2); + await ctx.SaveChangesAsync(); + + await ctx.Database.ExecuteSqlAsync( + $$""" +INSERT INTO [Entities] ([Id], [Reference], [Collection]) +VALUES(3, N'{ "NonNullableScalar" : 30 }', N'[{ "NonNullableScalar" : 10001 }]') +"""); + } + + protected override async Task Seed30028(DbContext ctx) + { + // complete + await ctx.Database.ExecuteSqlAsync( + $$$$""" +INSERT INTO [Entities] ([Id], [Json]) +VALUES( +1, +N'{"RootName":"e1","Collection":[{"BranchName":"e1 c1","Nested":{"LeafName":"e1 c1 l"}},{"BranchName":"e1 c2","Nested":{"LeafName":"e1 c2 l"}}],"OptionalReference":{"BranchName":"e1 or","Nested":{"LeafName":"e1 or l"}},"RequiredReference":{"BranchName":"e1 rr","Nested":{"LeafName":"e1 rr l"}}}') +"""); + + // missing collection + await ctx.Database.ExecuteSqlAsync( + $$$$""" +INSERT INTO [Entities] ([Id], [Json]) +VALUES( +2, +N'{"RootName":"e2","OptionalReference":{"BranchName":"e2 or","Nested":{"LeafName":"e2 or l"}},"RequiredReference":{"BranchName":"e2 rr","Nested":{"LeafName":"e2 rr l"}}}') +"""); + + // missing optional reference + await ctx.Database.ExecuteSqlAsync( + $$$$""" +INSERT INTO [Entities] ([Id], [Json]) +VALUES( +3, +N'{"RootName":"e3","Collection":[{"BranchName":"e3 c1","Nested":{"LeafName":"e3 c1 l"}},{"BranchName":"e3 c2","Nested":{"LeafName":"e3 c2 l"}}],"RequiredReference":{"BranchName":"e3 rr","Nested":{"LeafName":"e3 rr l"}}}') +"""); + + // missing required reference + await ctx.Database.ExecuteSqlAsync( + $$$$""" +INSERT INTO [Entities] ([Id], [Json]) +VALUES( +4, +N'{"RootName":"e4","Collection":[{"BranchName":"e4 c1","Nested":{"LeafName":"e4 c1 l"}},{"BranchName":"e4 c2","Nested":{"LeafName":"e4 c2 l"}}],"OptionalReference":{"BranchName":"e4 or","Nested":{"LeafName":"e4 or l"}}}') +"""); + } + + protected override Task Seed33046(DbContext ctx) + => ctx.Database.ExecuteSqlAsync( + $$""" +INSERT INTO [Reviews] ([Rounds], [Id]) +VALUES(N'[{"RoundNumber":11,"SubRounds":[{"SubRoundNumber":111},{"SubRoundNumber":112}]}]', 1) +"""); + + protected override Task SeedArrayOfPrimitives(DbContext ctx) + { + var entity1 = new MyEntityArrayOfPrimitives + { + Id = 1, + Reference = new MyJsonEntityArrayOfPrimitives + { + IntArray = [1, 2, 3], + ListOfString = + [ + "Foo", + "Bar", + "Baz" + ] + }, + Collection = + [ + new MyJsonEntityArrayOfPrimitives { IntArray = [111, 112, 113], ListOfString = ["Foo11", "Bar11"] }, + new MyJsonEntityArrayOfPrimitives { IntArray = [211, 212, 213], ListOfString = ["Foo12", "Bar12"] } + ] + }; + + var entity2 = new MyEntityArrayOfPrimitives + { + Id = 2, + Reference = new MyJsonEntityArrayOfPrimitives + { + IntArray = [10, 20, 30], + ListOfString = + [ + "A", + "B", + "C" + ] + }, + Collection = + [ + new MyJsonEntityArrayOfPrimitives { IntArray = [110, 120, 130], ListOfString = ["A1", "Z1"] }, + new MyJsonEntityArrayOfPrimitives { IntArray = [210, 220, 230], ListOfString = ["A2", "Z2"] } + ] + }; + + ctx.AddRange(entity1, entity2); + return ctx.SaveChangesAsync(); + } + + protected override Task SeedJunkInJson(DbContext ctx) + => ctx.Database.ExecuteSqlAsync( + $$$$""" +INSERT INTO [Entities] ([Collection], [CollectionWithCtor], [Reference], [ReferenceWithCtor], [Id]) +VALUES( +N'[{"JunkReference":{"Something":"SomeValue" },"Name":"c11","JunkProperty1":50,"Number":11.5,"JunkCollection1":[],"JunkCollection2":[{"Foo":"junk value"}],"NestedCollection":[{"DoB":"2002-04-01T00:00:00","DummyProp":"Dummy value"},{"DoB":"2002-04-02T00:00:00","DummyReference":{"Foo":5}}],"NestedReference":{"DoB":"2002-03-01T00:00:00"}},{"Name":"c12","Number":12.5,"NestedCollection":[{"DoB":"2002-06-01T00:00:00"},{"DoB":"2002-06-02T00:00:00"}],"NestedDummy":59,"NestedReference":{"DoB":"2002-05-01T00:00:00"}}]', +N'[{"MyBool":true,"Name":"c11 ctor","JunkReference":{"Something":"SomeValue","JunkCollection":[{"Foo":"junk value"}]},"NestedCollection":[{"DoB":"2002-08-01T00:00:00"},{"DoB":"2002-08-02T00:00:00"}],"NestedReference":{"DoB":"2002-07-01T00:00:00"}},{"MyBool":false,"Name":"c12 ctor","NestedCollection":[{"DoB":"2002-10-01T00:00:00"},{"DoB":"2002-10-02T00:00:00"}],"JunkCollection":[{"Foo":"junk value"}],"NestedReference":{"DoB":"2002-09-01T00:00:00"}}]', +N'{"Name":"r1","JunkCollection":[{"Foo":"junk value"}],"JunkReference":{"Something":"SomeValue" },"Number":1.5,"NestedCollection":[{"DoB":"2000-02-01T00:00:00","JunkReference":{"Something":"SomeValue"}},{"DoB":"2000-02-02T00:00:00"}],"NestedReference":{"DoB":"2000-01-01T00:00:00"}}', +N'{"MyBool":true,"JunkCollection":[{"Foo":"junk value"}],"Name":"r1 ctor","JunkReference":{"Something":"SomeValue" },"NestedCollection":[{"DoB":"2001-02-01T00:00:00"},{"DoB":"2001-02-02T00:00:00"}],"NestedReference":{"JunkCollection":[{"Foo":"junk value"}],"DoB":"2001-01-01T00:00:00"}}', +1) +"""); + + protected override Task SeedTrickyBuffering(DbContext ctx) + => ctx.Database.ExecuteSqlAsync( + $$$""" +INSERT INTO [Entities] ([Reference], [Id]) +VALUES( +N'{"Name": "r1", "Number": 7, "JunkReference":{"Something": "SomeValue" }, "JunkCollection": [{"Foo": "junk value"}], "NestedReference": {"DoB": "2000-01-01T00:00:00"}, "NestedCollection": [{"DoB": "2000-02-01T00:00:00", "JunkReference": {"Something": "SomeValue"}}, {"DoB": "2000-02-02T00:00:00"}]}',1) +"""); + + protected override Task SeedShadowProperties(DbContext ctx) + => ctx.Database.ExecuteSqlAsync( + $$""" +INSERT INTO [Entities] ([Collection], [CollectionWithCtor], [Reference], [ReferenceWithCtor], [Id], [Name]) +VALUES( +N'[{"Name":"e1_c1","ShadowDouble":5.5},{"ShadowDouble":20.5,"Name":"e1_c2"}]', +N'[{"Name":"e1_c1 ctor","ShadowNullableByte":6},{"ShadowNullableByte":null,"Name":"e1_c2 ctor"}]', +N'{"Name":"e1_r", "ShadowString":"Foo"}', +N'{"ShadowInt":143,"Name":"e1_r ctor"}', +1, +N'e1') +"""); + + protected override async Task SeedNotICollection(DbContext ctx) + { + await ctx.Database.ExecuteSqlAsync( + $$""" +INSERT INTO [Entities] ([Json], [Id]) +VALUES( +N'{"Collection":[{"Bar":11,"Foo":"c11"},{"Bar":12,"Foo":"c12"},{"Bar":13,"Foo":"c13"}]}', +1) +"""); + + await ctx.Database.ExecuteSqlAsync( + $$$""" +INSERT INTO [Entities] ([Json], [Id]) +VALUES( +N'{"Collection":[{"Bar":21,"Foo":"c21"},{"Bar":22,"Foo":"c22"}]}', +2) +"""); + } + + #region EnumLegacyValues + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual async Task Read_enum_property_with_legacy_values(bool async) + { + var contextFactory = await InitializeAsync( + onModelCreating: BuildModelEnumLegacyValues, + onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), + seed: SeedEnumLegacyValues); + + using (var context = contextFactory.CreateContext()) + { + var query = context.Set().Select( + x => new + { + x.Reference.IntEnum, + x.Reference.ByteEnum, + x.Reference.LongEnum, + x.Reference.NullableEnum + }); + + var exception = async + ? await (Assert.ThrowsAsync(() => query.ToListAsync())) + : Assert.Throws(() => query.ToList()); + + // Conversion failed when converting the nvarchar value '...' to data type int + Assert.Equal(245, exception.Number); + } + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual async Task Read_json_entity_with_enum_properties_with_legacy_values(bool async) + { + var contextFactory = await InitializeAsync( + onModelCreating: BuildModelEnumLegacyValues, + onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), + seed: SeedEnumLegacyValues, + shouldLogCategory: c => c == DbLoggerCategory.Query.Name); + + using (var context = contextFactory.CreateContext()) + { + var query = context.Set().Select(x => x.Reference).AsNoTracking(); + + var result = async + ? await query.ToListAsync() + : query.ToList(); + + Assert.Equal(1, result.Count); + Assert.Equal(ByteEnumLegacyValues.Redmond, result[0].ByteEnum); + Assert.Equal(IntEnumLegacyValues.Foo, result[0].IntEnum); + Assert.Equal(LongEnumLegacyValues.Three, result[0].LongEnum); + Assert.Equal(ULongEnumLegacyValues.Three, result[0].ULongEnum); + Assert.Equal(IntEnumLegacyValues.Bar, result[0].NullableEnum); + } + + var testLogger = new TestLogger(); + Assert.Single( + ListLoggerFactory.Log.Where( + l => l.Message == CoreResources.LogStringEnumValueInJson(testLogger).GenerateMessage(nameof(ByteEnumLegacyValues)))); + Assert.Single( + ListLoggerFactory.Log.Where( + l => l.Message == CoreResources.LogStringEnumValueInJson(testLogger).GenerateMessage(nameof(IntEnumLegacyValues)))); + Assert.Single( + ListLoggerFactory.Log.Where( + l => l.Message == CoreResources.LogStringEnumValueInJson(testLogger).GenerateMessage(nameof(LongEnumLegacyValues)))); + Assert.Single( + ListLoggerFactory.Log.Where( + l => l.Message == CoreResources.LogStringEnumValueInJson(testLogger).GenerateMessage(nameof(ULongEnumLegacyValues)))); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual async Task Read_json_entity_collection_with_enum_properties_with_legacy_values(bool async) + { + var contextFactory = await InitializeAsync( + onModelCreating: BuildModelEnumLegacyValues, + onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), + seed: SeedEnumLegacyValues, + shouldLogCategory: c => c == DbLoggerCategory.Query.Name); + + using (var context = contextFactory.CreateContext()) + { + var query = context.Set().Select(x => x.Collection).AsNoTracking(); + + var result = async + ? await query.ToListAsync() + : query.ToList(); + + Assert.Equal(1, result.Count); + Assert.Equal(2, result[0].Count); + Assert.Equal(ByteEnumLegacyValues.Bellevue, result[0][0].ByteEnum); + Assert.Equal(IntEnumLegacyValues.Foo, result[0][0].IntEnum); + Assert.Equal(LongEnumLegacyValues.One, result[0][0].LongEnum); + Assert.Equal(ULongEnumLegacyValues.One, result[0][0].ULongEnum); + Assert.Equal(IntEnumLegacyValues.Bar, result[0][0].NullableEnum); + Assert.Equal(ByteEnumLegacyValues.Seattle, result[0][1].ByteEnum); + Assert.Equal(IntEnumLegacyValues.Baz, result[0][1].IntEnum); + Assert.Equal(LongEnumLegacyValues.Two, result[0][1].LongEnum); + Assert.Equal(ULongEnumLegacyValues.Two, result[0][1].ULongEnum); + Assert.Null(result[0][1].NullableEnum); + } + + var testLogger = new TestLogger(); + Assert.Single( + ListLoggerFactory.Log.Where( + l => l.Message == CoreResources.LogStringEnumValueInJson(testLogger).GenerateMessage(nameof(ByteEnumLegacyValues)))); + Assert.Single( + ListLoggerFactory.Log.Where( + l => l.Message == CoreResources.LogStringEnumValueInJson(testLogger).GenerateMessage(nameof(IntEnumLegacyValues)))); + Assert.Single( + ListLoggerFactory.Log.Where( + l => l.Message == CoreResources.LogStringEnumValueInJson(testLogger).GenerateMessage(nameof(LongEnumLegacyValues)))); + Assert.Single( + ListLoggerFactory.Log.Where( + l => l.Message == CoreResources.LogStringEnumValueInJson(testLogger).GenerateMessage(nameof(ULongEnumLegacyValues)))); + } + + private Task SeedEnumLegacyValues(DbContext ctx) + => ctx.Database.ExecuteSqlAsync( + $$""" +INSERT INTO [Entities] ([Collection], [Reference], [Id], [Name]) +VALUES( +N'[{"ByteEnum":"Bellevue","IntEnum":"Foo","LongEnum":"One","ULongEnum":"One","Name":"e1_c1","NullableEnum":"Bar"},{"ByteEnum":"Seattle","IntEnum":"Baz","LongEnum":"Two","ULongEnum":"Two","Name":"e1_c2","NullableEnum":null}]', +N'{"ByteEnum":"Redmond","IntEnum":"Foo","LongEnum":"Three","ULongEnum":"Three","Name":"e1_r","NullableEnum":"Bar"}', +1, +N'e1') +"""); + + protected virtual void BuildModelEnumLegacyValues(ModelBuilder modelBuilder) + => modelBuilder.Entity( + b => + { + b.ToTable("Entities"); + b.Property(x => x.Id).ValueGeneratedNever(); + b.OwnsOne(x => x.Reference, b => b.ToJson().HasColumnType(JsonColumnType)); + b.OwnsMany(x => x.Collection, b => b.ToJson().HasColumnType(JsonColumnType)); + }); + + private class MyEntityEnumLegacyValues + { + public int Id { get; set; } + public string Name { get; set; } + + public MyJsonEntityEnumLegacyValues Reference { get; set; } + public List Collection { get; set; } + } + + private class MyJsonEntityEnumLegacyValues + { + public string Name { get; set; } + + // ReSharper disable once UnusedAutoPropertyAccessor.Local + public IntEnumLegacyValues IntEnum { get; set; } + + // ReSharper disable once UnusedAutoPropertyAccessor.Local + public ByteEnumLegacyValues ByteEnum { get; set; } + + // ReSharper disable once UnusedAutoPropertyAccessor.Local + public LongEnumLegacyValues LongEnum { get; set; } + + // ReSharper disable once UnusedAutoPropertyAccessor.Local + public ULongEnumLegacyValues ULongEnum { get; set; } + + // ReSharper disable once UnusedAutoPropertyAccessor.Local + public IntEnumLegacyValues? NullableEnum { get; set; } + } + + private enum IntEnumLegacyValues + { + Foo = int.MinValue, + Bar, + Baz = int.MaxValue, + } + + private enum ByteEnumLegacyValues : byte + { + Seattle, + Redmond, + Bellevue = 255, + } + + private enum LongEnumLegacyValues : long + { + One = long.MinValue, + Two = 1, + Three = long.MaxValue, + } + + private enum ULongEnumLegacyValues : ulong + { + One = ulong.MinValue, + Two = 1, + Three = ulong.MaxValue, + } + + #endregion +} diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocMiscellaneousQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocMiscellaneousQuerySqlServerTest.cs index b37228e5028..bebe075c633 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocMiscellaneousQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocMiscellaneousQuerySqlServerTest.cs @@ -100,7 +100,8 @@ await Parallel.ForAsync( }); } - private class Context5456(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context5456(DbContextOptions options) : DbContext(options) { public DbSet Blogs { get; set; } public DbSet Posts { get; set; } @@ -112,7 +113,7 @@ public Task SeedAsync() for (var i = 0; i < 100; i++) { Add( - new Blog { Posts = [new() { Comments = [new(), new()] }, new()], Author = new Author() }); + new Blog { Posts = [new Post { Comments = [new Comment(), new Comment()] }, new Post()], Author = new Author() }); } return SaveChangesAsync(); @@ -191,7 +192,8 @@ FROM [Customers] AS [c] """); } - private class Context8864(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context8864(DbContextOptions options) : DbContext(options) { public DbSet Customers { get; set; } @@ -295,7 +297,6 @@ RETURNS int END """); - await Database.ExecuteSqlRawAsync( """ CREATE FUNCTION dbo.AddTwo (@num int) @@ -427,7 +428,8 @@ WHEN NOT MATCHED THEN } } - private class Context12482(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context12482(DbContextOptions options) : DbContext(options) { public virtual DbSet BaseEntities { get; set; } @@ -550,7 +552,8 @@ FROM OPENJSON(@__testDateList_0) WITH ([value] smalldatetime '$') AS [t] """); } - private class Context13118(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context13118(DbContextOptions options) : DbContext(options) { public virtual DbSet ReproEntity { get; set; } @@ -567,7 +570,7 @@ public Task SeedAsync() } } - private class ReproEntity13118 + protected class ReproEntity13118 { public Guid Id { get; set; } public DateTime MyTime { get; set; } @@ -907,7 +910,8 @@ ORDER BY [r].[Id] """); } - private class Context15518(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context15518(DbContextOptions options) : DbContext(options) { public DbSet Repos { get; set; } @@ -966,7 +970,8 @@ CROSS JOIN ( } } - private class Context19206(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context19206(DbContextOptions options) : DbContext(options) { public DbSet Tests { get; set; } @@ -1018,7 +1023,8 @@ public virtual async Task Thread_safety_in_relational_command_cache() }); } - private class Context21666(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context21666(DbContextOptions options) : DbContext(options) { public DbSet Lists { get; set; } @@ -1059,7 +1065,8 @@ FROM [Locations] AS [l] """); } - private class Context23282(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context23282(DbContextOptions options) : DbContext(options) { public DbSet Locations { get; set; } @@ -1166,14 +1173,14 @@ ORDER BY [m0].[Id] """); } - private class Gender24216 + protected class Gender24216 { public long Id { get; set; } public string Description { get; set; } } - private class Message24216 + protected class Message24216 { public long Id { get; set; } @@ -1182,7 +1189,7 @@ private class Message24216 public DateTime Timestamp { get; set; } } - private class PersonStatus24216 + protected class PersonStatus24216 { public long Id { get; set; } @@ -1193,10 +1200,10 @@ private class PersonStatus24216 public string StatusMessage { get; set; } } - private class Context24216(DbContextOptions options) : DbContext(options) + // Protected so that it can be used by inheriting tests, and so that things like unused setters are not removed. + protected class Context24216(DbContextOptions options) : DbContext(options) { public DbSet Gender { get; set; } - public DbSet Message { get; set; } public IQueryable GetPersonStatusAsOf(long personId, DateTime asOf) @@ -1411,7 +1418,6 @@ public async Task SeedAsync() new Json30478 { Name = "c21", Nested = new JsonNested30478 { Number = 21 } }, new Json30478 { Name = "c22", Nested = new JsonNested30478 { Number = 22 } } - ] }; @@ -1421,7 +1427,6 @@ public async Task SeedAsync() RemoveRange(e1, e2); await SaveChangesAsync(); - await Database.ExecuteSqlRawAsync("ALTER TABLE [Entities] SET (SYSTEM_VERSIONING = OFF)"); await Database.ExecuteSqlRawAsync("ALTER TABLE [Entities] DROP PERIOD FOR SYSTEM_TIME"); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocNavigationsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocNavigationsQuerySqlServerTest.cs index b265e957cf7..268bedeab25 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocNavigationsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocNavigationsQuerySqlServerTest.cs @@ -82,13 +82,13 @@ public Task SeedAsync() { Posts = [ - new(), - new(), - new() + new Post(), + new Post(), + new Post() ] }, - new Blog { Posts = [new(), new()] }, - new Blog { Posts = [new()] }); + new Blog { Posts = [new Post(), new Post()] }, + new Blog { Posts = [new Post()] }); return SaveChangesAsync(); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocPrecompiledQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocPrecompiledQuerySqlServerTest.cs index bafbc35c492..2063c4bcd97 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocPrecompiledQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocPrecompiledQuerySqlServerTest.cs @@ -14,7 +14,8 @@ public override async Task Index_no_evaluatability() { await base.Index_no_evaluatability(); - AssertSql(""" + AssertSql( + """ SELECT [j].[Id], [j].[IntList], [j].[JsonThing] FROM [JsonEntities] AS [j] WHERE CAST(JSON_VALUE([j].[IntList], '$[' + CAST([j].[Id] AS nvarchar(max)) + ']') AS int) = 2 @@ -26,7 +27,8 @@ public override async Task Index_with_captured_variable() { await base.Index_with_captured_variable(); - AssertSql(""" + AssertSql( + """ @__id_0='1' SELECT [j].[Id], [j].[IntList], [j].[JsonThing] @@ -39,7 +41,8 @@ public override async Task JsonScalar() { await base.JsonScalar(); - AssertSql(""" + AssertSql( + """ SELECT [j].[Id], [j].[IntList], [j].[JsonThing] FROM [JsonEntities] AS [j] WHERE JSON_VALUE([j].[JsonThing], '$.StringProperty') = N'foo' diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServer160Test.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServer160Test.cs index 7702a3ac4e6..5628b696ada 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServer160Test.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServer160Test.cs @@ -69,7 +69,7 @@ where l1.Id < 3 SELECT ( SELECT TOP(1) [l1].[Name] FROM ( - SELECT DISTINCT TOP(1) [l0].[Id], [l0].[Level2_Optional_Id], [l0].[Level2_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse3Id], [l0].[OneToMany_Optional_Self_Inverse3Id], [l0].[OneToMany_Required_Inverse3Id], [l0].[OneToMany_Required_Self_Inverse3Id], [l0].[OneToOne_Optional_PK_Inverse3Id], [l0].[OneToOne_Optional_Self3Id] + SELECT TOP(1) [l0].[Id], [l0].[Name] FROM [LevelThree] AS [l0] ) AS [l1] ORDER BY [l1].[Id]) diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs index a1ecbbafe29..4b9b1070b00 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs @@ -35,7 +35,7 @@ where l1.Id < 3 select l3).Distinct().Skip(1).OrderBy(e => e.Id).FirstOrDefault().Name); AssertSql( -""" + """ SELECT ( SELECT TOP(1) [l2].[Name] FROM ( @@ -58,18 +58,18 @@ WHERE [l].[Id] < 3 public virtual async Task Distinct_take_without_orderby(bool async) { await AssertQuery( - async, - ss => from l1 in ss.Set() - where l1.Id < 3 - select (from l3 in ss.Set() - select l3).Distinct().Take(1).OrderBy(e => e.Id).FirstOrDefault().Name); + async, + ss => from l1 in ss.Set() + where l1.Id < 3 + select (from l3 in ss.Set() + select l3).Distinct().Take(1).OrderBy(e => e.Id).FirstOrDefault().Name); AssertSql( -""" + """ SELECT ( SELECT TOP(1) [l1].[Name] FROM ( - SELECT DISTINCT TOP(1) [l0].[Id], [l0].[Level2_Optional_Id], [l0].[Level2_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse3Id], [l0].[OneToMany_Optional_Self_Inverse3Id], [l0].[OneToMany_Required_Inverse3Id], [l0].[OneToMany_Required_Self_Inverse3Id], [l0].[OneToOne_Optional_PK_Inverse3Id], [l0].[OneToOne_Optional_Self3Id] + SELECT TOP(1) [l0].[Id], [l0].[Name] FROM [LevelThree] AS [l0] ) AS [l1] ORDER BY [l1].[Id]) @@ -4760,7 +4760,7 @@ public override async Task Multiple_optional_navs_should_not_deadlock(bool async await base.Multiple_optional_navs_should_not_deadlock(async); AssertSql( -""" + """ SELECT COUNT(*) FROM [LevelTwo] AS [l] LEFT JOIN [LevelOne] AS [l0] ON [l].[OneToMany_Optional_Inverse2Id] = [l0].[Id] @@ -4774,7 +4774,7 @@ public override async Task Null_check_removal_applied_recursively_complex(bool a await base.Null_check_removal_applied_recursively_complex(async); AssertSql( -""" + """ SELECT [l].[Id], [l].[Level2_Optional_Id], [l].[Level2_Required_Id], [l].[Name], [l].[OneToMany_Optional_Inverse3Id], [l].[OneToMany_Optional_Self_Inverse3Id], [l].[OneToMany_Required_Inverse3Id], [l].[OneToMany_Required_Self_Inverse3Id], [l].[OneToOne_Optional_PK_Inverse3Id], [l].[OneToOne_Optional_Self3Id], [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id], [l1].[Id], [l1].[Date], [l1].[Name], [l1].[OneToMany_Optional_Self_Inverse1Id], [l1].[OneToMany_Required_Self_Inverse1Id], [l1].[OneToOne_Optional_Self1Id], [l2].[Id], [l2].[Level3_Optional_Id], [l2].[Level3_Required_Id], [l2].[Name], [l2].[OneToMany_Optional_Inverse4Id], [l2].[OneToMany_Optional_Self_Inverse4Id], [l2].[OneToMany_Required_Inverse4Id], [l2].[OneToMany_Required_Self_Inverse4Id], [l2].[OneToOne_Optional_PK_Inverse4Id], [l2].[OneToOne_Optional_Self4Id] FROM [LevelThree] AS [l] INNER JOIN [LevelTwo] AS [l0] ON [l].[OneToMany_Required_Inverse3Id] = [l0].[Id] diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServer160Test.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServer160Test.cs index a9fa36d942e..3ea3c2abe3d 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServer160Test.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServer160Test.cs @@ -87,7 +87,7 @@ where l1.Id < 3 SELECT ( SELECT TOP(1) [s].[Level3_Name] FROM ( - SELECT DISTINCT TOP(1) [l4].[Id], [l4].[Level2_Optional_Id], [l4].[Level2_Required_Id], [l4].[Level3_Name], [l4].[OneToMany_Optional_Inverse3Id], [l4].[OneToMany_Required_Inverse3Id], [l4].[OneToOne_Optional_PK_Inverse3Id] + SELECT TOP(1) [l4].[Id], [l4].[Level2_Required_Id], [l4].[Level3_Name], [l4].[OneToMany_Required_Inverse3Id] FROM [Level1] AS [l0] LEFT JOIN ( SELECT [l1].[Id], [l1].[OneToOne_Required_PK_Date], [l1].[Level1_Required_Id], [l1].[OneToMany_Required_Inverse2Id] @@ -97,7 +97,7 @@ WHERE [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] END LEFT JOIN ( - SELECT [l3].[Id], [l3].[Level2_Optional_Id], [l3].[Level2_Required_Id], [l3].[Level3_Name], [l3].[OneToMany_Optional_Inverse3Id], [l3].[OneToMany_Required_Inverse3Id], [l3].[OneToOne_Optional_PK_Inverse3Id] + SELECT [l3].[Id], [l3].[Level2_Required_Id], [l3].[Level3_Name], [l3].[OneToMany_Required_Inverse3Id] FROM [Level1] AS [l3] WHERE [l3].[Level2_Required_Id] IS NOT NULL AND [l3].[OneToMany_Required_Inverse3Id] IS NOT NULL ) AS [l4] ON CASE @@ -1018,7 +1018,7 @@ WHERE [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] """); } - [ConditionalTheory()] + [ConditionalTheory] public override async Task GroupBy_aggregate_where_required_relationship_2(bool async) { await base.GroupBy_aggregate_where_required_relationship_2(async); @@ -1169,7 +1169,7 @@ WHERE [l5].[OneToOne_Required_PK_Date] IS NOT NULL AND [l5].[Level1_Required_Id] """); } - [ConditionalTheory()] + [ConditionalTheory] public override async Task GroupBy_aggregate_where_required_relationship(bool async) { await base.GroupBy_aggregate_where_required_relationship(async); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServerTest.cs index 2fbb10dca51..00aba8b691e 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServerTest.cs @@ -36,7 +36,7 @@ where l1.Id < 3 select l3).Distinct().Skip(1).OrderBy(e => e.Id).FirstOrDefault().Name); AssertSql( -""" + """ SELECT ( SELECT TOP(1) [s0].[Level3_Name] FROM ( @@ -78,18 +78,18 @@ WHERE [l].[Id] < 3 public virtual async Task Distinct_take_without_orderby(bool async) { await AssertQuery( - async, - ss => from l1 in ss.Set() - where l1.Id < 3 - select (from l3 in ss.Set() - select l3).Distinct().Take(1).OrderBy(e => e.Id).FirstOrDefault().Name); + async, + ss => from l1 in ss.Set() + where l1.Id < 3 + select (from l3 in ss.Set() + select l3).Distinct().Take(1).OrderBy(e => e.Id).FirstOrDefault().Name); AssertSql( -""" + """ SELECT ( SELECT TOP(1) [s].[Level3_Name] FROM ( - SELECT DISTINCT TOP(1) [l4].[Id], [l4].[Level2_Optional_Id], [l4].[Level2_Required_Id], [l4].[Level3_Name], [l4].[OneToMany_Optional_Inverse3Id], [l4].[OneToMany_Required_Inverse3Id], [l4].[OneToOne_Optional_PK_Inverse3Id] + SELECT TOP(1) [l4].[Id], [l4].[Level2_Required_Id], [l4].[Level3_Name], [l4].[OneToMany_Required_Inverse3Id] FROM [Level1] AS [l0] LEFT JOIN ( SELECT [l1].[Id], [l1].[OneToOne_Required_PK_Date], [l1].[Level1_Required_Id], [l1].[OneToMany_Required_Inverse2Id] @@ -99,7 +99,7 @@ WHERE [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id] END LEFT JOIN ( - SELECT [l3].[Id], [l3].[Level2_Optional_Id], [l3].[Level2_Required_Id], [l3].[Level3_Name], [l3].[OneToMany_Optional_Inverse3Id], [l3].[OneToMany_Required_Inverse3Id], [l3].[OneToOne_Optional_PK_Inverse3Id] + SELECT [l3].[Id], [l3].[Level2_Required_Id], [l3].[Level3_Name], [l3].[OneToMany_Required_Inverse3Id] FROM [Level1] AS [l3] WHERE [l3].[Level2_Required_Id] IS NOT NULL AND [l3].[OneToMany_Required_Inverse3Id] IS NOT NULL ) AS [l4] ON CASE @@ -1020,7 +1020,7 @@ WHERE [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] """); } - [ConditionalTheory()] + [ConditionalTheory] public override async Task GroupBy_aggregate_where_required_relationship_2(bool async) { await base.GroupBy_aggregate_where_required_relationship_2(async); @@ -1171,7 +1171,7 @@ WHERE [l5].[OneToOne_Required_PK_Date] IS NOT NULL AND [l5].[Level1_Required_Id] """); } - [ConditionalTheory()] + [ConditionalTheory] public override async Task GroupBy_aggregate_where_required_relationship(bool async) { await base.GroupBy_aggregate_where_required_relationship(async); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexTypeQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexTypeQuerySqlServerTest.cs index b62c0570bf0..c3aca53a5b9 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexTypeQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexTypeQuerySqlServerTest.cs @@ -481,7 +481,8 @@ WHERE [v0].[ShippingAddress_ZipCode] <> 7728 // purpose of knowing that it's there. public override async Task Project_struct_complex_type_via_optional_navigation(bool async) { - var exception = await Assert.ThrowsAsync(() => base.Project_struct_complex_type_via_optional_navigation(async)); + var exception = + await Assert.ThrowsAsync(() => base.Project_struct_complex_type_via_optional_navigation(async)); Assert.Equal(RelationalStrings.CannotProjectNullableComplexType("ValuedCustomer.ShippingAddress#AddressStruct"), exception.Message); } @@ -866,7 +867,7 @@ public override async Task Project_same_entity_with_nested_complex_type_twice_wi await base.Project_same_entity_with_nested_complex_type_twice_with_pushdown(async); AssertSql( -""" + """ SELECT [s].[Id], [s].[Name], [s].[BillingAddress_AddressLine1], [s].[BillingAddress_AddressLine2], [s].[BillingAddress_Tags], [s].[BillingAddress_ZipCode], [s].[BillingAddress_Country_Code], [s].[BillingAddress_Country_FullName], [s].[ShippingAddress_AddressLine1], [s].[ShippingAddress_AddressLine2], [s].[ShippingAddress_Tags], [s].[ShippingAddress_ZipCode], [s].[ShippingAddress_Country_Code], [s].[ShippingAddress_Country_FullName], [s].[Id0], [s].[Name0], [s].[BillingAddress_AddressLine10], [s].[BillingAddress_AddressLine20], [s].[BillingAddress_Tags0], [s].[BillingAddress_ZipCode0], [s].[BillingAddress_Country_Code0], [s].[BillingAddress_Country_FullName0], [s].[ShippingAddress_AddressLine10], [s].[ShippingAddress_AddressLine20], [s].[ShippingAddress_Tags0], [s].[ShippingAddress_ZipCode0], [s].[ShippingAddress_Country_Code0], [s].[ShippingAddress_Country_FullName0] FROM ( SELECT DISTINCT [c].[Id], [c].[Name], [c].[BillingAddress_AddressLine1], [c].[BillingAddress_AddressLine2], [c].[BillingAddress_Tags], [c].[BillingAddress_ZipCode], [c].[BillingAddress_Country_Code], [c].[BillingAddress_Country_FullName], [c].[ShippingAddress_AddressLine1], [c].[ShippingAddress_AddressLine2], [c].[ShippingAddress_Tags], [c].[ShippingAddress_ZipCode], [c].[ShippingAddress_Country_Code], [c].[ShippingAddress_Country_FullName], [c0].[Id] AS [Id0], [c0].[Name] AS [Name0], [c0].[BillingAddress_AddressLine1] AS [BillingAddress_AddressLine10], [c0].[BillingAddress_AddressLine2] AS [BillingAddress_AddressLine20], [c0].[BillingAddress_Tags] AS [BillingAddress_Tags0], [c0].[BillingAddress_ZipCode] AS [BillingAddress_ZipCode0], [c0].[BillingAddress_Country_Code] AS [BillingAddress_Country_Code0], [c0].[BillingAddress_Country_FullName] AS [BillingAddress_Country_FullName0], [c0].[ShippingAddress_AddressLine1] AS [ShippingAddress_AddressLine10], [c0].[ShippingAddress_AddressLine2] AS [ShippingAddress_AddressLine20], [c0].[ShippingAddress_Tags] AS [ShippingAddress_Tags0], [c0].[ShippingAddress_ZipCode] AS [ShippingAddress_ZipCode0], [c0].[ShippingAddress_Country_Code] AS [ShippingAddress_Country_Code0], [c0].[ShippingAddress_Country_FullName] AS [ShippingAddress_Country_FullName0] @@ -881,7 +882,7 @@ public override async Task Project_same_nested_complex_type_twice_with_pushdown( await base.Project_same_nested_complex_type_twice_with_pushdown(async); AssertSql( -""" + """ SELECT [s].[BillingAddress_AddressLine1], [s].[BillingAddress_AddressLine2], [s].[BillingAddress_Tags], [s].[BillingAddress_ZipCode], [s].[BillingAddress_Country_Code], [s].[BillingAddress_Country_FullName], [s].[BillingAddress_AddressLine10], [s].[BillingAddress_AddressLine20], [s].[BillingAddress_Tags0], [s].[BillingAddress_ZipCode0], [s].[BillingAddress_Country_Code0], [s].[BillingAddress_Country_FullName0] FROM ( SELECT DISTINCT [c].[BillingAddress_AddressLine1], [c].[BillingAddress_AddressLine2], [c].[BillingAddress_Tags], [c].[BillingAddress_ZipCode], [c].[BillingAddress_Country_Code], [c].[BillingAddress_Country_FullName], [c0].[BillingAddress_AddressLine1] AS [BillingAddress_AddressLine10], [c0].[BillingAddress_AddressLine2] AS [BillingAddress_AddressLine20], [c0].[BillingAddress_Tags] AS [BillingAddress_Tags0], [c0].[BillingAddress_ZipCode] AS [BillingAddress_ZipCode0], [c0].[BillingAddress_Country_Code] AS [BillingAddress_Country_Code0], [c0].[BillingAddress_Country_FullName] AS [BillingAddress_Country_FullName0] @@ -896,7 +897,7 @@ public override async Task Project_same_entity_with_nested_complex_type_twice_wi await base.Project_same_entity_with_nested_complex_type_twice_with_double_pushdown(async); AssertSql( -""" + """ @__p_0='50' SELECT [s0].[Id], [s0].[Name], [s0].[BillingAddress_AddressLine1], [s0].[BillingAddress_AddressLine2], [s0].[BillingAddress_Tags], [s0].[BillingAddress_ZipCode], [s0].[BillingAddress_Country_Code], [s0].[BillingAddress_Country_FullName], [s0].[ShippingAddress_AddressLine1], [s0].[ShippingAddress_AddressLine2], [s0].[ShippingAddress_Tags], [s0].[ShippingAddress_ZipCode], [s0].[ShippingAddress_Country_Code], [s0].[ShippingAddress_Country_FullName], [s0].[Id0], [s0].[Name0], [s0].[BillingAddress_AddressLine10], [s0].[BillingAddress_AddressLine20], [s0].[BillingAddress_Tags0], [s0].[BillingAddress_ZipCode0], [s0].[BillingAddress_Country_Code0], [s0].[BillingAddress_Country_FullName0], [s0].[ShippingAddress_AddressLine10], [s0].[ShippingAddress_AddressLine20], [s0].[ShippingAddress_Tags0], [s0].[ShippingAddress_ZipCode0], [s0].[ShippingAddress_Country_Code0], [s0].[ShippingAddress_Country_FullName0] @@ -917,7 +918,7 @@ public override async Task Project_same_nested_complex_type_twice_with_double_pu await base.Project_same_nested_complex_type_twice_with_double_pushdown(async); AssertSql( -""" + """ @__p_0='50' SELECT [s0].[BillingAddress_AddressLine1], [s0].[BillingAddress_AddressLine2], [s0].[BillingAddress_Tags], [s0].[BillingAddress_ZipCode], [s0].[BillingAddress_Country_Code], [s0].[BillingAddress_Country_FullName], [s0].[BillingAddress_AddressLine10], [s0].[BillingAddress_AddressLine20], [s0].[BillingAddress_Tags0], [s0].[BillingAddress_ZipCode0], [s0].[BillingAddress_Country_Code0], [s0].[BillingAddress_Country_FullName0] @@ -938,7 +939,7 @@ public override async Task Project_same_entity_with_struct_nested_complex_type_t await base.Project_same_entity_with_struct_nested_complex_type_twice_with_pushdown(async); AssertSql( -""" + """ SELECT [s].[Id], [s].[Name], [s].[BillingAddress_AddressLine1], [s].[BillingAddress_AddressLine2], [s].[BillingAddress_ZipCode], [s].[BillingAddress_Country_Code], [s].[BillingAddress_Country_FullName], [s].[ShippingAddress_AddressLine1], [s].[ShippingAddress_AddressLine2], [s].[ShippingAddress_ZipCode], [s].[ShippingAddress_Country_Code], [s].[ShippingAddress_Country_FullName], [s].[Id0], [s].[Name0], [s].[BillingAddress_AddressLine10], [s].[BillingAddress_AddressLine20], [s].[BillingAddress_ZipCode0], [s].[BillingAddress_Country_Code0], [s].[BillingAddress_Country_FullName0], [s].[ShippingAddress_AddressLine10], [s].[ShippingAddress_AddressLine20], [s].[ShippingAddress_ZipCode0], [s].[ShippingAddress_Country_Code0], [s].[ShippingAddress_Country_FullName0] FROM ( SELECT DISTINCT [v].[Id], [v].[Name], [v].[BillingAddress_AddressLine1], [v].[BillingAddress_AddressLine2], [v].[BillingAddress_ZipCode], [v].[BillingAddress_Country_Code], [v].[BillingAddress_Country_FullName], [v].[ShippingAddress_AddressLine1], [v].[ShippingAddress_AddressLine2], [v].[ShippingAddress_ZipCode], [v].[ShippingAddress_Country_Code], [v].[ShippingAddress_Country_FullName], [v0].[Id] AS [Id0], [v0].[Name] AS [Name0], [v0].[BillingAddress_AddressLine1] AS [BillingAddress_AddressLine10], [v0].[BillingAddress_AddressLine2] AS [BillingAddress_AddressLine20], [v0].[BillingAddress_ZipCode] AS [BillingAddress_ZipCode0], [v0].[BillingAddress_Country_Code] AS [BillingAddress_Country_Code0], [v0].[BillingAddress_Country_FullName] AS [BillingAddress_Country_FullName0], [v0].[ShippingAddress_AddressLine1] AS [ShippingAddress_AddressLine10], [v0].[ShippingAddress_AddressLine2] AS [ShippingAddress_AddressLine20], [v0].[ShippingAddress_ZipCode] AS [ShippingAddress_ZipCode0], [v0].[ShippingAddress_Country_Code] AS [ShippingAddress_Country_Code0], [v0].[ShippingAddress_Country_FullName] AS [ShippingAddress_Country_FullName0] @@ -953,7 +954,7 @@ public override async Task Project_same_struct_nested_complex_type_twice_with_pu await base.Project_same_struct_nested_complex_type_twice_with_pushdown(async); AssertSql( -""" + """ SELECT [s].[BillingAddress_AddressLine1], [s].[BillingAddress_AddressLine2], [s].[BillingAddress_ZipCode], [s].[BillingAddress_Country_Code], [s].[BillingAddress_Country_FullName], [s].[BillingAddress_AddressLine10], [s].[BillingAddress_AddressLine20], [s].[BillingAddress_ZipCode0], [s].[BillingAddress_Country_Code0], [s].[BillingAddress_Country_FullName0] FROM ( SELECT DISTINCT [v].[BillingAddress_AddressLine1], [v].[BillingAddress_AddressLine2], [v].[BillingAddress_ZipCode], [v].[BillingAddress_Country_Code], [v].[BillingAddress_Country_FullName], [v0].[BillingAddress_AddressLine1] AS [BillingAddress_AddressLine10], [v0].[BillingAddress_AddressLine2] AS [BillingAddress_AddressLine20], [v0].[BillingAddress_ZipCode] AS [BillingAddress_ZipCode0], [v0].[BillingAddress_Country_Code] AS [BillingAddress_Country_Code0], [v0].[BillingAddress_Country_FullName] AS [BillingAddress_Country_FullName0] @@ -968,7 +969,7 @@ public override async Task Project_same_entity_with_struct_nested_complex_type_t await base.Project_same_entity_with_struct_nested_complex_type_twice_with_double_pushdown(async); AssertSql( -""" + """ @__p_0='50' SELECT [s0].[Id], [s0].[Name], [s0].[BillingAddress_AddressLine1], [s0].[BillingAddress_AddressLine2], [s0].[BillingAddress_ZipCode], [s0].[BillingAddress_Country_Code], [s0].[BillingAddress_Country_FullName], [s0].[ShippingAddress_AddressLine1], [s0].[ShippingAddress_AddressLine2], [s0].[ShippingAddress_ZipCode], [s0].[ShippingAddress_Country_Code], [s0].[ShippingAddress_Country_FullName], [s0].[Id0], [s0].[Name0], [s0].[BillingAddress_AddressLine10], [s0].[BillingAddress_AddressLine20], [s0].[BillingAddress_ZipCode0], [s0].[BillingAddress_Country_Code0], [s0].[BillingAddress_Country_FullName0], [s0].[ShippingAddress_AddressLine10], [s0].[ShippingAddress_AddressLine20], [s0].[ShippingAddress_ZipCode0], [s0].[ShippingAddress_Country_Code0], [s0].[ShippingAddress_Country_FullName0] @@ -989,7 +990,7 @@ public override async Task Project_same_struct_nested_complex_type_twice_with_do await base.Project_same_struct_nested_complex_type_twice_with_double_pushdown(async); AssertSql( -""" + """ @__p_0='50' SELECT [s0].[BillingAddress_AddressLine1], [s0].[BillingAddress_AddressLine2], [s0].[BillingAddress_ZipCode], [s0].[BillingAddress_Country_Code], [s0].[BillingAddress_Country_FullName], [s0].[BillingAddress_AddressLine10], [s0].[BillingAddress_AddressLine20], [s0].[BillingAddress_ZipCode0], [s0].[BillingAddress_Country_Code0], [s0].[BillingAddress_Country_FullName0] @@ -1010,7 +1011,7 @@ public override async Task Union_of_same_entity_with_nested_complex_type_project await base.Union_of_same_entity_with_nested_complex_type_projected_twice_with_pushdown(async); AssertSql( -""" + """ @__p_0='50' SELECT TOP(@__p_0) [u].[Id], [u].[Name], [u].[BillingAddress_AddressLine1], [u].[BillingAddress_AddressLine2], [u].[BillingAddress_Tags], [u].[BillingAddress_ZipCode], [u].[BillingAddress_Country_Code], [u].[BillingAddress_Country_FullName], [u].[ShippingAddress_AddressLine1], [u].[ShippingAddress_AddressLine2], [u].[ShippingAddress_Tags], [u].[ShippingAddress_ZipCode], [u].[ShippingAddress_Country_Code], [u].[ShippingAddress_Country_FullName], [u].[Id0], [u].[Name0], [u].[BillingAddress_AddressLine10], [u].[BillingAddress_AddressLine20], [u].[BillingAddress_Tags0], [u].[BillingAddress_ZipCode0], [u].[BillingAddress_Country_Code0], [u].[BillingAddress_Country_FullName0], [u].[ShippingAddress_AddressLine10], [u].[ShippingAddress_AddressLine20], [u].[ShippingAddress_Tags0], [u].[ShippingAddress_ZipCode0], [u].[ShippingAddress_Country_Code0], [u].[ShippingAddress_Country_FullName0] @@ -1032,7 +1033,7 @@ public override async Task Union_of_same_entity_with_nested_complex_type_project await base.Union_of_same_entity_with_nested_complex_type_projected_twice_with_double_pushdown(async); AssertSql( -""" + """ @__p_0='50' SELECT TOP(@__p_0) [u1].[Id], [u1].[Name], [u1].[BillingAddress_AddressLine1], [u1].[BillingAddress_AddressLine2], [u1].[BillingAddress_Tags], [u1].[BillingAddress_ZipCode], [u1].[BillingAddress_Country_Code], [u1].[BillingAddress_Country_FullName], [u1].[ShippingAddress_AddressLine1], [u1].[ShippingAddress_AddressLine2], [u1].[ShippingAddress_Tags], [u1].[ShippingAddress_ZipCode], [u1].[ShippingAddress_Country_Code], [u1].[ShippingAddress_Country_FullName], [u1].[Id0], [u1].[Name0], [u1].[BillingAddress_AddressLine10], [u1].[BillingAddress_AddressLine20], [u1].[BillingAddress_Tags0], [u1].[BillingAddress_ZipCode0], [u1].[BillingAddress_Country_Code0], [u1].[BillingAddress_Country_FullName0], [u1].[ShippingAddress_AddressLine10], [u1].[ShippingAddress_AddressLine20], [u1].[ShippingAddress_Tags0], [u1].[ShippingAddress_ZipCode0], [u1].[ShippingAddress_Country_Code0], [u1].[ShippingAddress_Country_FullName0] @@ -1061,7 +1062,7 @@ public override async Task Union_of_same_nested_complex_type_projected_twice_wit await base.Union_of_same_nested_complex_type_projected_twice_with_pushdown(async); AssertSql( -""" + """ @__p_0='50' SELECT TOP(@__p_0) [u].[BillingAddress_AddressLine1], [u].[BillingAddress_AddressLine2], [u].[BillingAddress_Tags], [u].[BillingAddress_ZipCode], [u].[BillingAddress_Country_Code], [u].[BillingAddress_Country_FullName], [u].[BillingAddress_AddressLine10], [u].[BillingAddress_AddressLine20], [u].[BillingAddress_Tags0], [u].[BillingAddress_ZipCode0], [u].[BillingAddress_Country_Code0], [u].[BillingAddress_Country_FullName0] @@ -1083,7 +1084,7 @@ public override async Task Union_of_same_nested_complex_type_projected_twice_wit await base.Union_of_same_nested_complex_type_projected_twice_with_double_pushdown(async); AssertSql( -""" + """ @__p_0='50' SELECT TOP(@__p_0) [u1].[BillingAddress_AddressLine1], [u1].[BillingAddress_AddressLine2], [u1].[BillingAddress_Tags], [u1].[BillingAddress_ZipCode], [u1].[BillingAddress_Country_Code], [u1].[BillingAddress_Country_FullName], [u1].[BillingAddress_AddressLine10], [u1].[BillingAddress_AddressLine20], [u1].[BillingAddress_Tags0], [u1].[BillingAddress_ZipCode0], [u1].[BillingAddress_Country_Code0], [u1].[BillingAddress_Country_FullName0] @@ -1112,7 +1113,7 @@ public override async Task Same_entity_with_complex_type_projected_twice_with_pu await base.Same_entity_with_complex_type_projected_twice_with_pushdown_as_part_of_another_projection(async); AssertSql( -""" + """ SELECT [c].[Id], [s].[Id], [s].[Name], [s].[BillingAddress_AddressLine1], [s].[BillingAddress_AddressLine2], [s].[BillingAddress_Tags], [s].[BillingAddress_ZipCode], [s].[BillingAddress_Country_Code], [s].[BillingAddress_Country_FullName], [s].[ShippingAddress_AddressLine1], [s].[ShippingAddress_AddressLine2], [s].[ShippingAddress_Tags], [s].[ShippingAddress_ZipCode], [s].[ShippingAddress_Country_Code], [s].[ShippingAddress_Country_FullName], [s].[Id0], [s].[Name0], [s].[BillingAddress_AddressLine10], [s].[BillingAddress_AddressLine20], [s].[BillingAddress_Tags0], [s].[BillingAddress_ZipCode0], [s].[BillingAddress_Country_Code0], [s].[BillingAddress_Country_FullName0], [s].[ShippingAddress_AddressLine10], [s].[ShippingAddress_AddressLine20], [s].[ShippingAddress_Tags0], [s].[ShippingAddress_ZipCode0], [s].[ShippingAddress_Country_Code0], [s].[ShippingAddress_Country_FullName0], [s].[c] FROM [Customer] AS [c] OUTER APPLY ( @@ -1199,7 +1200,7 @@ public override async Task Projecting_property_of_complex_type_using_left_join_w await base.Projecting_property_of_complex_type_using_left_join_with_pushdown(async); AssertSql( -""" + """ SELECT [c1].[BillingAddress_ZipCode] FROM [CustomerGroup] AS [c] LEFT JOIN ( @@ -1215,7 +1216,7 @@ public override async Task Projecting_complex_from_optional_navigation_using_con await base.Projecting_complex_from_optional_navigation_using_conditional(async); AssertSql( -""" + """ @__p_0='20' SELECT [s0].[ShippingAddress_ZipCode] @@ -1236,7 +1237,7 @@ public override async Task Project_entity_with_complex_type_pushdown_and_then_le await base.Project_entity_with_complex_type_pushdown_and_then_left_join(async); AssertSql( -""" + """ @__p_0='20' @__p_1='30' diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/FromSqlQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/FromSqlQuerySqlServerTest.cs index 2736d073256..fe7d1a30e22 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/FromSqlQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/FromSqlQuerySqlServerTest.cs @@ -12,9 +12,7 @@ public class FromSqlQuerySqlServerTest : FromSqlQueryTestBase Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); public override async Task FromSqlRaw_queryable_simple(bool async) { @@ -70,7 +68,9 @@ public override async Task FromSqlRaw_queryable_composed_after_removing_whitespa FROM ( -""" + " " + """ +""" + + " " + + """ @@ -1002,9 +1002,10 @@ public virtual void FromSql_output_parameter_works_with_transient_errors() }; var orders = context.Set() - .FromSqlRaw(@"SET @returnValue = 3 -SELECT * FROM [Customers] WHERE [CustomerID] = 'ALFKI'", [output]) - .ToList(); + .FromSqlRaw( + @"SET @returnValue = 3 +SELECT * FROM [Customers] WHERE [CustomerID] = 'ALFKI'", output) + .ToList(); Assert.Equal(1, orders.Count); Assert.Equal(3, output.Value); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/FromSqlSprocQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/FromSqlSprocQuerySqlServerTest.cs index 563e83e40d8..5720d8d818f 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/FromSqlSprocQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/FromSqlSprocQuerySqlServerTest.cs @@ -9,9 +9,7 @@ public class FromSqlSprocQuerySqlServerTest : FromSqlSprocQueryTestBase fixture) : base(fixture) - { - fixture.TestSqlLoggerFactory.Clear(); - } + => fixture.TestSqlLoggerFactory.Clear(); public override async Task From_sql_queryable_stored_procedure(bool async) { diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/FunkyDataQueryAzureSynapseTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/FunkyDataQueryAzureSynapseTest.cs new file mode 100644 index 00000000000..fbd05867453 --- /dev/null +++ b/test/EFCore.SqlServer.FunctionalTests/Query/FunkyDataQueryAzureSynapseTest.cs @@ -0,0 +1,602 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.Query; + +#nullable disable + +public class FunkyDataQueryAzureSynapseTest : FunkyDataQuerySqlServerBaseTest +{ + public FunkyDataQueryAzureSynapseTest(FunkyDataQueryAzureSynapseFixture fixture, ITestOutputHelper testOutputHelper) + : base(fixture, testOutputHelper) + { + } + + public override async Task String_contains_on_argument_with_wildcard_constant(bool async) + { + await base.String_contains_on_argument_with_wildcard_constant(async); + + AssertSql( + """ +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NOT NULL AND CHARINDEX(N'%B', [f].[FirstName]) > 0 +""", + // + """ +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NOT NULL AND CHARINDEX(N'a_', [f].[FirstName]) > 0 +""", + // + """ +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE 0 = 1 +""", + // + """ +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NOT NULL +""", + // + """ +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NOT NULL AND CHARINDEX(N'_Ba_', [f].[FirstName]) > 0 +""", + // + """ +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NULL OR CHARINDEX(N'%B%a%r', [f].[FirstName]) <= 0 +""", + // + """ +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NULL +""", + // + """ +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +"""); + } + + public override async Task String_contains_on_argument_with_wildcard_parameter(bool async) + { + await base.String_contains_on_argument_with_wildcard_parameter(async); + + AssertSql( + """ +@__prm1_0='%B' (Size = 4000) + +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NOT NULL AND (CHARINDEX(@__prm1_0, [f].[FirstName]) > 0 OR @__prm1_0 LIKE N'') +""", + // + """ +@__prm2_0='a_' (Size = 4000) + +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NOT NULL AND (CHARINDEX(@__prm2_0, [f].[FirstName]) > 0 OR @__prm2_0 LIKE N'') +""", + // + """ +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE 0 = 1 +""", + // + """ +@__prm4_0='' (Size = 4000) + +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NOT NULL AND (CHARINDEX(@__prm4_0, [f].[FirstName]) > 0 OR @__prm4_0 LIKE N'') +""", + // + """ +@__prm5_0='_Ba_' (Size = 4000) + +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NOT NULL AND (CHARINDEX(@__prm5_0, [f].[FirstName]) > 0 OR @__prm5_0 LIKE N'') +""", + // + """ +@__prm6_0='%B%a%r' (Size = 4000) + +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NULL OR (CHARINDEX(@__prm6_0, [f].[FirstName]) <= 0 AND @__prm6_0 NOT LIKE N'') +""", + // + """ +@__prm7_0='' (Size = 4000) + +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NULL OR (CHARINDEX(@__prm7_0, [f].[FirstName]) <= 0 AND @__prm7_0 NOT LIKE N'') +""", + // + """ +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +"""); + } + + public override async Task String_contains_on_argument_with_wildcard_column(bool async) + { + await base.String_contains_on_argument_with_wildcard_column(async); + + AssertSql( + """ +SELECT [f].[FirstName] AS [fn], [f0].[LastName] AS [ln] +FROM [FunkyCustomers] AS [f] +CROSS JOIN [FunkyCustomers] AS [f0] +WHERE [f].[FirstName] IS NOT NULL AND [f0].[LastName] IS NOT NULL AND (CHARINDEX([f0].[LastName], [f].[FirstName]) > 0 OR [f0].[LastName] LIKE N'') +"""); + } + + public override async Task String_contains_on_argument_with_wildcard_column_negated(bool async) + { + await base.String_contains_on_argument_with_wildcard_column_negated(async); + + AssertSql( + """ +SELECT [f].[FirstName] AS [fn], [f0].[LastName] AS [ln] +FROM [FunkyCustomers] AS [f] +CROSS JOIN [FunkyCustomers] AS [f0] +WHERE [f].[FirstName] IS NULL OR [f0].[LastName] IS NULL OR (CHARINDEX([f0].[LastName], [f].[FirstName]) <= 0 AND [f0].[LastName] NOT LIKE N'') +"""); + } + + public override async Task String_starts_with_on_argument_with_wildcard_constant(bool async) + { + await base.String_starts_with_on_argument_with_wildcard_constant(async); + + AssertSql( + """ +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NOT NULL AND LEFT([f].[FirstName], LEN(N'%B')) = N'%B' +""", + // + """ +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NOT NULL AND LEFT([f].[FirstName], LEN(N'_B')) = N'_B' +""", + // + """ +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE 0 = 1 +""", + // + """ +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NOT NULL +""", + // + """ +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NOT NULL AND LEFT([f].[FirstName], LEN(N'_Ba_')) = N'_Ba_' +""", + // + """ +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NULL OR LEFT([f].[FirstName], LEN(N'%B%a%r')) <> N'%B%a%r' +""", + // + """ +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NULL +""", + // + """ +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +"""); + } + + public override async Task String_starts_with_on_argument_with_wildcard_parameter(bool async) + { + await base.String_starts_with_on_argument_with_wildcard_parameter(async); + + AssertSql( + """ +@__prm1_0='%B' (Size = 4000) + +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NOT NULL AND LEFT([f].[FirstName], LEN(@__prm1_0)) = @__prm1_0 +""", + // + """ +@__prm2_0='_B' (Size = 4000) + +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NOT NULL AND LEFT([f].[FirstName], LEN(@__prm2_0)) = @__prm2_0 +""", + // + """ +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE 0 = 1 +""", + // + """ +@__prm4_0='' (Size = 4000) + +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NOT NULL AND LEFT([f].[FirstName], LEN(@__prm4_0)) = @__prm4_0 +""", + // + """ +@__prm5_0='_Ba_' (Size = 4000) + +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NOT NULL AND LEFT([f].[FirstName], LEN(@__prm5_0)) = @__prm5_0 +""", + // + """ +@__prm6_0='%B%a%r' (Size = 4000) + +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NULL OR LEFT([f].[FirstName], LEN(@__prm6_0)) <> @__prm6_0 +""", + // + """ +@__prm7_0='' (Size = 4000) + +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NULL OR LEFT([f].[FirstName], LEN(@__prm7_0)) <> @__prm7_0 +""", + // + """ +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +"""); + } + + public override async Task String_starts_with_on_argument_with_bracket(bool async) + { + await base.String_starts_with_on_argument_with_bracket(async); + + AssertSql( + """ +SELECT [f].[Id], [f].[FirstName], [f].[LastName], [f].[NullableBool] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NOT NULL AND LEFT([f].[FirstName], LEN(N'[')) = N'[' +""", + // + """ +SELECT [f].[Id], [f].[FirstName], [f].[LastName], [f].[NullableBool] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NOT NULL AND LEFT([f].[FirstName], LEN(N'B[')) = N'B[' +""", + // + """ +SELECT [f].[Id], [f].[FirstName], [f].[LastName], [f].[NullableBool] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NOT NULL AND LEFT([f].[FirstName], LEN(N'B[[a^')) = N'B[[a^' +""", + // + """ +@__prm1_0='[' (Size = 4000) + +SELECT [f].[Id], [f].[FirstName], [f].[LastName], [f].[NullableBool] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NOT NULL AND LEFT([f].[FirstName], LEN(@__prm1_0)) = @__prm1_0 +""", + // + """ +@__prm2_0='B[' (Size = 4000) + +SELECT [f].[Id], [f].[FirstName], [f].[LastName], [f].[NullableBool] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NOT NULL AND LEFT([f].[FirstName], LEN(@__prm2_0)) = @__prm2_0 +""", + // + """ +@__prm3_0='B[[a^' (Size = 4000) + +SELECT [f].[Id], [f].[FirstName], [f].[LastName], [f].[NullableBool] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NOT NULL AND LEFT([f].[FirstName], LEN(@__prm3_0)) = @__prm3_0 +""", + // + """ +SELECT [f].[Id], [f].[FirstName], [f].[LastName], [f].[NullableBool] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NOT NULL AND [f].[LastName] IS NOT NULL AND LEFT([f].[FirstName], LEN([f].[LastName])) = [f].[LastName] +"""); + } + + public override async Task String_starts_with_on_argument_with_wildcard_column(bool async) + { + await base.String_starts_with_on_argument_with_wildcard_column(async); + + AssertSql( + """ +SELECT [f].[FirstName] AS [fn], [f0].[LastName] AS [ln] +FROM [FunkyCustomers] AS [f] +CROSS JOIN [FunkyCustomers] AS [f0] +WHERE [f].[FirstName] IS NOT NULL AND [f0].[LastName] IS NOT NULL AND LEFT([f].[FirstName], LEN([f0].[LastName])) = [f0].[LastName] +"""); + } + + public override async Task String_starts_with_on_argument_with_wildcard_column_negated(bool async) + { + await base.String_starts_with_on_argument_with_wildcard_column_negated(async); + + AssertSql( + """ +SELECT [f].[FirstName] AS [fn], [f0].[LastName] AS [ln] +FROM [FunkyCustomers] AS [f] +CROSS JOIN [FunkyCustomers] AS [f0] +WHERE [f].[FirstName] IS NULL OR [f0].[LastName] IS NULL OR LEFT([f].[FirstName], LEN([f0].[LastName])) <> [f0].[LastName] +"""); + } + + public override async Task String_ends_with_on_argument_with_wildcard_constant(bool async) + { + await base.String_ends_with_on_argument_with_wildcard_constant(async); + + AssertSql( + """ +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NOT NULL AND RIGHT([f].[FirstName], LEN(N'%r')) = N'%r' +""", + // + """ +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NOT NULL AND RIGHT([f].[FirstName], LEN(N'r_')) = N'r_' +""", + // + """ +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE 0 = 1 +""", + // + """ +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NOT NULL +""", + // + """ +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NOT NULL AND RIGHT([f].[FirstName], LEN(N'_r_')) = N'_r_' +""", + // + """ +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NULL OR RIGHT([f].[FirstName], LEN(N'a%r%')) <> N'a%r%' +""", + // + """ +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NULL +""", + // + """ +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +"""); + } + + public override async Task String_ends_with_on_argument_with_wildcard_parameter(bool async) + { + await base.String_ends_with_on_argument_with_wildcard_parameter(async); + + AssertSql( + """ +@__prm1_0='%r' (Size = 4000) + +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NOT NULL AND RIGHT([f].[FirstName], LEN(@__prm1_0)) = @__prm1_0 +""", + // + """ +@__prm2_0='r_' (Size = 4000) + +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NOT NULL AND RIGHT([f].[FirstName], LEN(@__prm2_0)) = @__prm2_0 +""", + // + """ +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE 0 = 1 +""", + // + """ +@__prm4_0='' (Size = 4000) + +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NOT NULL AND RIGHT([f].[FirstName], LEN(@__prm4_0)) = @__prm4_0 +""", + // + """ +@__prm5_0='_r_' (Size = 4000) + +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NOT NULL AND RIGHT([f].[FirstName], LEN(@__prm5_0)) = @__prm5_0 +""", + // + """ +@__prm6_0='a%r%' (Size = 4000) + +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NULL OR RIGHT([f].[FirstName], LEN(@__prm6_0)) <> @__prm6_0 +""", + // + """ +@__prm7_0='' (Size = 4000) + +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +WHERE [f].[FirstName] IS NULL OR RIGHT([f].[FirstName], LEN(@__prm7_0)) <> @__prm7_0 +""", + // + """ +SELECT [f].[FirstName] +FROM [FunkyCustomers] AS [f] +"""); + } + + public override async Task String_ends_with_on_argument_with_wildcard_column(bool async) + { + await base.String_ends_with_on_argument_with_wildcard_column(async); + + AssertSql( + """ +SELECT [f].[FirstName] AS [fn], [f0].[LastName] AS [ln] +FROM [FunkyCustomers] AS [f] +CROSS JOIN [FunkyCustomers] AS [f0] +WHERE [f].[FirstName] IS NOT NULL AND [f0].[LastName] IS NOT NULL AND RIGHT([f].[FirstName], LEN([f0].[LastName])) = [f0].[LastName] +"""); + } + + public override async Task String_ends_with_on_argument_with_wildcard_column_negated(bool async) + { + await base.String_ends_with_on_argument_with_wildcard_column_negated(async); + + AssertSql( + """ +SELECT [f].[FirstName] AS [fn], [f0].[LastName] AS [ln] +FROM [FunkyCustomers] AS [f] +CROSS JOIN [FunkyCustomers] AS [f0] +WHERE [f].[FirstName] IS NULL OR [f0].[LastName] IS NULL OR RIGHT([f].[FirstName], LEN([f0].[LastName])) <> [f0].[LastName] +"""); + } + + public override async Task String_ends_with_inside_conditional(bool async) + { + await base.String_ends_with_inside_conditional(async); + + AssertSql( + """ +SELECT [f].[FirstName] AS [fn], [f0].[LastName] AS [ln] +FROM [FunkyCustomers] AS [f] +CROSS JOIN [FunkyCustomers] AS [f0] +WHERE CASE + WHEN [f].[FirstName] IS NOT NULL AND [f0].[LastName] IS NOT NULL AND RIGHT([f].[FirstName], LEN([f0].[LastName])) = [f0].[LastName] THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END = CAST(1 AS bit) +"""); + } + + public override async Task String_ends_with_inside_conditional_negated(bool async) + { + await base.String_ends_with_inside_conditional_negated(async); + + AssertSql( + """ +SELECT [f].[FirstName] AS [fn], [f0].[LastName] AS [ln] +FROM [FunkyCustomers] AS [f] +CROSS JOIN [FunkyCustomers] AS [f0] +WHERE CASE + WHEN [f].[FirstName] IS NULL OR [f0].[LastName] IS NULL OR RIGHT([f].[FirstName], LEN([f0].[LastName])) <> [f0].[LastName] THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END = CAST(1 AS bit) +"""); + } + + public override async Task String_ends_with_equals_nullable_column(bool async) + { + await base.String_ends_with_equals_nullable_column(async); + + AssertSql( + """ +SELECT [f].[Id], [f].[FirstName], [f].[LastName], [f].[NullableBool], [f0].[Id], [f0].[FirstName], [f0].[LastName], [f0].[NullableBool] +FROM [FunkyCustomers] AS [f] +CROSS JOIN [FunkyCustomers] AS [f0] +WHERE CASE + WHEN [f].[FirstName] IS NOT NULL AND [f0].[LastName] IS NOT NULL AND RIGHT([f].[FirstName], LEN([f0].[LastName])) = [f0].[LastName] THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END = [f].[NullableBool] +"""); + } + + public override async Task String_ends_with_not_equals_nullable_column(bool async) + { + await base.String_ends_with_not_equals_nullable_column(async); + + AssertSql( + """ +SELECT [f].[Id], [f].[FirstName], [f].[LastName], [f].[NullableBool], [f0].[Id], [f0].[FirstName], [f0].[LastName], [f0].[NullableBool] +FROM [FunkyCustomers] AS [f] +CROSS JOIN [FunkyCustomers] AS [f0] +WHERE CASE + WHEN [f].[FirstName] IS NOT NULL AND [f0].[LastName] IS NOT NULL AND RIGHT([f].[FirstName], LEN([f0].[LastName])) = [f0].[LastName] THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END <> [f].[NullableBool] OR [f].[NullableBool] IS NULL +"""); + } + + public override async Task String_FirstOrDefault_and_LastOrDefault(bool async) + { + await base.String_FirstOrDefault_and_LastOrDefault(async); + + AssertSql( + """ +SELECT SUBSTRING([f].[FirstName], 1, 1) AS [first], SUBSTRING([f].[FirstName], LEN([f].[FirstName]), 1) AS [last] +FROM [FunkyCustomers] AS [f] +ORDER BY [f].[Id] +"""); + } + + public override async Task String_Contains_and_StartsWith_with_same_parameter(bool async) + { + await base.String_Contains_and_StartsWith_with_same_parameter(async); + + AssertSql( + """ +@__s_0='B' (Size = 4000) + +SELECT [f].[Id], [f].[FirstName], [f].[LastName], [f].[NullableBool] +FROM [FunkyCustomers] AS [f] +WHERE ([f].[FirstName] IS NOT NULL AND (CHARINDEX(@__s_0, [f].[FirstName]) > 0 OR @__s_0 LIKE N'')) OR ([f].[LastName] IS NOT NULL AND LEFT([f].[LastName], LEN(@__s_0)) = @__s_0) +"""); + } + + public class FunkyDataQueryAzureSynapseFixture : FunkyDataQueryFixtureBase, ITestSqlLoggerFactory + { + public TestSqlLoggerFactory TestSqlLoggerFactory + => (TestSqlLoggerFactory)ListLoggerFactory; + + protected override ITestStoreFactory TestStoreFactory + => AzureSynapseTestStoreFactory.Instance; + + protected override string StoreName + => nameof(FunkyDataQueryAzureSynapseTest); + } +} diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/FunkyDataQuerySqlServerBaseTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/FunkyDataQuerySqlServerBaseTest.cs new file mode 100644 index 00000000000..9e1793b3ac6 --- /dev/null +++ b/test/EFCore.SqlServer.FunctionalTests/Query/FunkyDataQuerySqlServerBaseTest.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.Query; + +#nullable disable + +public abstract class FunkyDataQuerySqlServerBaseTest : FunkyDataQueryTestBase + where TFixture : FunkyDataQueryTestBase.FunkyDataQueryFixtureBase, ITestSqlLoggerFactory, new() +{ + public FunkyDataQuerySqlServerBaseTest(TFixture fixture, ITestOutputHelper testOutputHelper) + : base(fixture) + { + Fixture.TestSqlLoggerFactory.Clear(); + Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); + } + + protected override QueryAsserter CreateQueryAsserter(TFixture fixture) + => new RelationalQueryAsserter( + fixture, RewriteExpectedQueryExpression, RewriteServerQueryExpression); + + protected override void ClearLog() + => Fixture.TestSqlLoggerFactory.Clear(); + + protected void AssertSql(params string[] expected) + => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); +} diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/FunkyDataQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/FunkyDataQuerySqlServerTest.cs index 45af4624f1e..f469d571141 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/FunkyDataQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/FunkyDataQuerySqlServerTest.cs @@ -5,19 +5,13 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class FunkyDataQuerySqlServerTest : FunkyDataQueryTestBase +public class FunkyDataQuerySqlServerTest : FunkyDataQuerySqlServerBaseTest { public FunkyDataQuerySqlServerTest(FunkyDataQuerySqlServerFixture fixture, ITestOutputHelper testOutputHelper) - : base(fixture) + : base(fixture, testOutputHelper) { - Fixture.TestSqlLoggerFactory.Clear(); - Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); } - protected override QueryAsserter CreateQueryAsserter(FunkyDataQuerySqlServerFixture fixture) - => new RelationalQueryAsserter( - fixture, RewriteExpectedQueryExpression, RewriteServerQueryExpression); - public override async Task String_contains_on_argument_with_wildcard_constant(bool async) { await base.String_contains_on_argument_with_wildcard_constant(async); @@ -172,44 +166,44 @@ SELECT [f].[FirstName] FROM [FunkyCustomers] AS [f] WHERE [f].[FirstName] LIKE N'\%B%' ESCAPE N'\' """, - // - """ + // + """ SELECT [f].[FirstName] FROM [FunkyCustomers] AS [f] WHERE [f].[FirstName] LIKE N'\_B%' ESCAPE N'\' """, - // - """ + // + """ SELECT [f].[FirstName] FROM [FunkyCustomers] AS [f] WHERE 0 = 1 """, - // - """ + // + """ SELECT [f].[FirstName] FROM [FunkyCustomers] AS [f] WHERE [f].[FirstName] IS NOT NULL """, - // - """ + // + """ SELECT [f].[FirstName] FROM [FunkyCustomers] AS [f] WHERE [f].[FirstName] LIKE N'\_Ba\_%' ESCAPE N'\' """, - // - """ + // + """ SELECT [f].[FirstName] FROM [FunkyCustomers] AS [f] WHERE [f].[FirstName] NOT LIKE N'\%B\%a\%r%' ESCAPE N'\' OR [f].[FirstName] IS NULL """, - // - """ + // + """ SELECT [f].[FirstName] FROM [FunkyCustomers] AS [f] WHERE [f].[FirstName] IS NULL """, - // - """ + // + """ SELECT [f].[FirstName] FROM [FunkyCustomers] AS [f] """); @@ -370,44 +364,44 @@ SELECT [f].[FirstName] FROM [FunkyCustomers] AS [f] WHERE [f].[FirstName] LIKE N'%\%r' ESCAPE N'\' """, - // - """ + // + """ SELECT [f].[FirstName] FROM [FunkyCustomers] AS [f] WHERE [f].[FirstName] LIKE N'%r\_' ESCAPE N'\' """, - // - """ + // + """ SELECT [f].[FirstName] FROM [FunkyCustomers] AS [f] WHERE 0 = 1 """, - // - """ + // + """ SELECT [f].[FirstName] FROM [FunkyCustomers] AS [f] WHERE [f].[FirstName] IS NOT NULL """, - // - """ + // + """ SELECT [f].[FirstName] FROM [FunkyCustomers] AS [f] WHERE [f].[FirstName] LIKE N'%\_r\_' ESCAPE N'\' """, - // - """ + // + """ SELECT [f].[FirstName] FROM [FunkyCustomers] AS [f] WHERE [f].[FirstName] NOT LIKE N'%a\%r\%' ESCAPE N'\' OR [f].[FirstName] IS NULL """, - // - """ + // + """ SELECT [f].[FirstName] FROM [FunkyCustomers] AS [f] WHERE [f].[FirstName] IS NULL """, - // - """ + // + """ SELECT [f].[FirstName] FROM [FunkyCustomers] AS [f] """); @@ -595,12 +589,6 @@ WHERE [f].[FirstName] LIKE @__s_0_contains ESCAPE N'\' OR [f].[LastName] LIKE @_ """); } - protected override void ClearLog() - => Fixture.TestSqlLoggerFactory.Clear(); - - private void AssertSql(params string[] expected) - => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); - public class FunkyDataQuerySqlServerFixture : FunkyDataQueryFixtureBase, ITestSqlLoggerFactory { public TestSqlLoggerFactory TestSqlLoggerFactory @@ -608,5 +596,8 @@ public TestSqlLoggerFactory TestSqlLoggerFactory protected override ITestStoreFactory TestStoreFactory => SqlServerTestStoreFactory.Instance; + + protected override string StoreName + => nameof(FunkyDataQuerySqlServerTest); } } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarFromSqlQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarFromSqlQuerySqlServerTest.cs index afa6ad9b26e..76303866868 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarFromSqlQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarFromSqlQuerySqlServerTest.cs @@ -9,9 +9,7 @@ public class GearsOfWarFromSqlQuerySqlServerTest : GearsOfWarFromSqlQueryTestBas { public GearsOfWarFromSqlQuerySqlServerTest(GearsOfWarQuerySqlServerFixture fixture, ITestOutputHelper testOutputHelper) : base(fixture) - { - fixture.TestSqlLoggerFactory.Clear(); - } + => fixture.TestSqlLoggerFactory.Clear(); public override void From_sql_queryable_simple_columns_out_of_order() { diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs index ee1bf84c519..0a079557a4a 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs @@ -1562,7 +1562,7 @@ public override async Task Where_subquery_distinct_singleordefault_boolean2(bool SELECT [g].[Nickname], [g].[SquadId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[Discriminator], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[Rank] FROM [Gears] AS [g] WHERE [g].[HasSoulPatch] = CAST(1 AS bit) AND COALESCE(( - SELECT DISTINCT TOP(1) [w].[IsAutomatic] + SELECT TOP(1) [w].[IsAutomatic] FROM [Weapons] AS [w] WHERE [g].[FullName] = [w].[OwnerFullName] AND [w].[Name] LIKE N'%Lancer%'), CAST(0 AS bit)) = CAST(1 AS bit) ORDER BY [g].[Nickname] @@ -4040,7 +4040,7 @@ public override async Task ToString_nullable_enum_property_projection(bool async await base.ToString_nullable_enum_property_projection(async); AssertSql( -""" + """ SELECT CASE [w].[AmmunitionType] WHEN 1 THEN N'Cartridge' WHEN 2 THEN N'Shell' @@ -4067,7 +4067,7 @@ public override async Task ToString_nullable_enum_contains(bool async) await base.ToString_nullable_enum_contains(async); AssertSql( -""" + """ SELECT [w].[Name] FROM [Weapons] AS [w] WHERE CASE [w].[AmmunitionType] @@ -5838,7 +5838,7 @@ public override async Task Select_subquery_distinct_singleordefault_boolean2(boo AssertSql( """ SELECT COALESCE(( - SELECT DISTINCT TOP(1) [w].[IsAutomatic] + SELECT TOP(1) [w].[IsAutomatic] FROM [Weapons] AS [w] WHERE [g].[FullName] = [w].[OwnerFullName] AND [w].[Name] LIKE N'%Lancer%'), CAST(0 AS bit)) FROM [Gears] AS [g] @@ -5889,7 +5889,7 @@ public override async Task Select_subquery_distinct_singleordefault_boolean_empt AssertSql( """ SELECT COALESCE(( - SELECT DISTINCT TOP(1) [w].[IsAutomatic] + SELECT TOP(1) [w].[IsAutomatic] FROM [Weapons] AS [w] WHERE [g].[FullName] = [w].[OwnerFullName] AND [w].[Name] = N'BFG'), CAST(0 AS bit)) FROM [Gears] AS [g] @@ -9254,7 +9254,7 @@ public override async Task Where_TimeOnly_FromDateTime_compared_to_property(bool await base.Where_TimeOnly_FromDateTime_compared_to_property(async); AssertSql( -""" + """ SELECT [t].[Id] AS [TagId], [m].[Id] AS [MissionId] FROM [Tags] AS [t] CROSS JOIN [Missions] AS [m] @@ -9267,7 +9267,7 @@ public override async Task Where_TimeOnly_FromDateTime_compared_to_parameter(boo await base.Where_TimeOnly_FromDateTime_compared_to_parameter(async); AssertSql( -""" + """ @__time_0='02:00' (DbType = Time) SELECT [t].[Id], [t].[GearNickName], [t].[GearSquadId], [t].[IssueDate], [t].[Note] @@ -9282,7 +9282,7 @@ public override async Task Where_TimeOnly_FromDateTime_compared_to_constant(bool await base.Where_TimeOnly_FromDateTime_compared_to_constant(async); AssertSql( -""" + """ SELECT [t].[Id], [t].[GearNickName], [t].[GearSquadId], [t].[IssueDate], [t].[Note] FROM [Tags] AS [t] WHERE CAST(DATEADD(hour, CAST(CAST(CAST(LEN([t].[Note]) AS int) AS float) AS int), [t].[IssueDate]) AS time) > '09:00:00' @@ -9294,7 +9294,7 @@ public override async Task Where_TimeOnly_FromTimeSpan_compared_to_property(bool await base.Where_TimeOnly_FromTimeSpan_compared_to_property(async); AssertSql( -""" + """ SELECT [m].[Id], [m].[BriefingDocument], [m].[BriefingDocumentFileExtension], [m].[CodeName], [m].[Date], [m].[Difficulty], [m].[Duration], [m].[Rating], [m].[Time], [m].[Timeline] FROM [Missions] AS [m] WHERE CAST([m].[Duration] AS time) < [m].[Time] @@ -9306,7 +9306,7 @@ public override async Task Where_TimeOnly_FromTimeSpan_compared_to_parameter(boo await base.Where_TimeOnly_FromTimeSpan_compared_to_parameter(async); AssertSql( -""" + """ @__time_0='01:02' (DbType = Time) SELECT [m].[Id], [m].[BriefingDocument], [m].[BriefingDocumentFileExtension], [m].[CodeName], [m].[Date], [m].[Difficulty], [m].[Duration], [m].[Rating], [m].[Time], [m].[Timeline] @@ -9320,7 +9320,7 @@ public override async Task Order_by_TimeOnly_FromTimeSpan(bool async) await base.Order_by_TimeOnly_FromTimeSpan(async); AssertSql( -""" + """ SELECT [m].[Id], [m].[BriefingDocument], [m].[BriefingDocumentFileExtension], [m].[CodeName], [m].[Date], [m].[Difficulty], [m].[Duration], [m].[Rating], [m].[Time], [m].[Timeline] FROM [Missions] AS [m] ORDER BY CAST([m].[Duration] AS time) @@ -9332,7 +9332,7 @@ public override async Task Where_DateOnly_FromDateTime_compared_to_property(bool await base.Where_DateOnly_FromDateTime_compared_to_property(async); AssertSql( -""" + """ SELECT [t].[Id] AS [TagId], [m].[Id] AS [MissionId] FROM [Tags] AS [t] CROSS JOIN [Missions] AS [m] @@ -9345,7 +9345,7 @@ public override async Task Where_DateOnly_FromDateTime_compared_to_constant_and_ await base.Where_DateOnly_FromDateTime_compared_to_constant_and_parameter(async); AssertSql( -""" + """ @__prm_0='10/11/0002' (DbType = Date) SELECT [t].[Id], [t].[GearNickName], [t].[GearSquadId], [t].[IssueDate], [t].[Note] diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/IncludeOneToOneSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/IncludeOneToOneSqlServerTest.cs index 5306ebbf7e2..8bad9f3ed48 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/IncludeOneToOneSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/IncludeOneToOneSqlServerTest.cs @@ -9,9 +9,7 @@ public class IncludeOneToOneSqlServerTest : IncludeOneToOneTestBase fixture.TestSqlLoggerFactory.Clear(); public override void Include_person() { diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/InheritanceRelationshipsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/InheritanceRelationshipsQuerySqlServerTest.cs index e33e06fcbae..a59684c3a3d 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/InheritanceRelationshipsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/InheritanceRelationshipsQuerySqlServerTest.cs @@ -13,9 +13,7 @@ public InheritanceRelationshipsQuerySqlServerTest( InheritanceRelationshipsQuerySqlServerFixture fixture, ITestOutputHelper testOutputHelper) : base(fixture) - { - fixture.TestSqlLoggerFactory.Clear(); - } + => fixture.TestSqlLoggerFactory.Clear(); [ConditionalFact] public virtual void Check_all_tests_overridden() diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/JsonQueryJsonTypeSqlServerFixture.cs b/test/EFCore.SqlServer.FunctionalTests/Query/JsonQueryJsonTypeSqlServerFixture.cs new file mode 100644 index 00000000000..81642e9c14f --- /dev/null +++ b/test/EFCore.SqlServer.FunctionalTests/Query/JsonQueryJsonTypeSqlServerFixture.cs @@ -0,0 +1,84 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#nullable disable +using Microsoft.EntityFrameworkCore.TestModels.JsonQuery; + +namespace Microsoft.EntityFrameworkCore.Query; + +public class JsonQueryJsonTypeSqlServerFixture : JsonQuerySqlServerFixture +{ + protected override string StoreName + => "JsonQueryJsonTypeTest"; + + protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) + { + base.OnModelCreating(modelBuilder, context); + + modelBuilder.Entity( + b => + { + b.OwnsOne(x => x.OwnedReferenceRoot).ToJson().HasColumnType("json"); + b.OwnsMany(x => x.OwnedCollectionRoot).ToJson().HasColumnType("json"); + }); + + modelBuilder.Entity( + b => + { + b.OwnsOne(x => x.OwnedReferenceRoot).ToJson("json_reference_custom_naming").HasColumnType("json"); + ; + b.OwnsMany(x => x.OwnedCollectionRoot).HasColumnType("json").ToJson("json_collection_custom_naming"); + }); + + modelBuilder.Entity().OwnsMany(x => x.OwnedCollection).ToJson().HasColumnType("json"); + + modelBuilder.Entity( + b => + { + b.OwnsOne(x => x.ReferenceOnBase).ToJson().HasColumnType("json"); + b.OwnsMany(x => x.CollectionOnBase).ToJson().HasColumnType("json"); + }); + + modelBuilder.Entity( + b => + { + b.HasBaseType(); + b.OwnsOne(x => x.ReferenceOnDerived).ToJson().HasColumnType("json"); + b.OwnsMany(x => x.CollectionOnDerived).ToJson().HasColumnType("json"); + }); + + modelBuilder.Entity( + b => + { + b.OwnsOne(x => x.Reference).ToJson().HasColumnType("json"); + b.OwnsMany(x => x.Collection).ToJson().HasColumnType("json"); + b.PrimitiveCollection(e => e.TestDefaultStringCollection).HasColumnType("json").IsRequired(); + b.PrimitiveCollection(e => e.TestMaxLengthStringCollection).HasColumnType("json").IsRequired(); + b.PrimitiveCollection(e => e.TestInt16Collection).HasColumnType("json").IsRequired(); + b.PrimitiveCollection(e => e.TestInt32Collection).HasColumnType("json").IsRequired(); + b.PrimitiveCollection(e => e.TestDecimalCollection).HasColumnType("json").IsRequired(); + b.PrimitiveCollection(e => e.TestDateTimeCollection).HasColumnType("json").IsRequired(); + b.PrimitiveCollection(e => e.TestDateTimeOffsetCollection).HasColumnType("json").IsRequired(); + b.PrimitiveCollection(e => e.TestTimeSpanCollection).HasColumnType("json").IsRequired(); + b.PrimitiveCollection(e => e.TestInt64Collection).HasColumnType("json").IsRequired(); + b.PrimitiveCollection(e => e.TestDoubleCollection).HasColumnType("json").IsRequired(); + b.PrimitiveCollection(e => e.TestSingleCollection).HasColumnType("json").IsRequired(); + b.PrimitiveCollection(e => e.TestBooleanCollection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestCharacterCollection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestByteCollection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestGuidCollection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestUnsignedInt16Collection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestUnsignedInt32Collection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestUnsignedInt64Collection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestSignedByteCollection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestNullableInt32Collection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestEnumCollection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestEnumWithIntConverterCollection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestNullableEnumCollection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestNullableEnumWithIntConverterCollection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestNullableEnumWithConverterThatHandlesNullsCollection).HasColumnType("json"); + }); + + modelBuilder.Entity().OwnsOne(x => x.Reference).ToJson().HasColumnType("json"); + } +} diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/JsonQueryJsonTypeSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/JsonQueryJsonTypeSqlServerTest.cs new file mode 100644 index 00000000000..600aaa36c4d --- /dev/null +++ b/test/EFCore.SqlServer.FunctionalTests/Query/JsonQueryJsonTypeSqlServerTest.cs @@ -0,0 +1,3265 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#nullable disable +using Microsoft.Data.SqlClient; +using Microsoft.EntityFrameworkCore.TestModels.JsonQuery; + +namespace Microsoft.EntityFrameworkCore.Query; + +[SqlServerCondition(SqlServerCondition.SupportsJsonType)] +public class JsonQueryJsonTypeSqlServerTest : JsonQueryRelationalTestBase +{ + public JsonQueryJsonTypeSqlServerTest(JsonQueryJsonTypeSqlServerFixture fixture, ITestOutputHelper testOutputHelper) + : base(fixture) + { + Fixture.TestSqlLoggerFactory.Clear(); + Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); + } + + public override async Task Basic_json_projection_owner_entity(bool async) + { + await base.Basic_json_projection_owner_entity(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Basic_json_projection_owner_entity_NoTracking(bool async) + { + await base.Basic_json_projection_owner_entity_NoTracking(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Basic_json_projection_owner_entity_NoTrackingWithIdentityResolution(bool async) + { + await base.Basic_json_projection_owner_entity_NoTrackingWithIdentityResolution(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Basic_json_projection_owner_entity_duplicated(bool async) + { + await base.Basic_json_projection_owner_entity_duplicated(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Basic_json_projection_owner_entity_duplicated_NoTracking(bool async) + { + await base.Basic_json_projection_owner_entity_duplicated_NoTracking(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[Name], [j].[OwnedCollection], [j].[OwnedCollection] +FROM [JsonEntitiesSingleOwned] AS [j] +"""); + } + + public override async Task Basic_json_projection_owner_entity_duplicated_NoTrackingWithIdentityResolution(bool async) + { + await base.Basic_json_projection_owner_entity_duplicated_NoTrackingWithIdentityResolution(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[Name], [j].[OwnedCollection], [j].[OwnedCollection] +FROM [JsonEntitiesSingleOwned] AS [j] +"""); + } + + public override async Task Basic_json_projection_owner_entity_twice(bool async) + { + await base.Basic_json_projection_owner_entity_twice(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Basic_json_projection_owner_entity_twice_NoTracking(bool async) + { + await base.Basic_json_projection_owner_entity_twice_NoTracking(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Basic_json_projection_owner_entity_twice_NoTrackingWithIdentityResolution(bool async) + { + await base.Basic_json_projection_owner_entity_twice_NoTrackingWithIdentityResolution(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Basic_json_projection_owned_reference_root(bool async) + { + await base.Basic_json_projection_owned_reference_root(async); + + AssertSql( + """ +SELECT [j].[OwnedReferenceRoot], [j].[Id] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Basic_json_projection_owned_reference_root_NoTrackingWithIdentityResolution(bool async) + { + await base.Basic_json_projection_owned_reference_root_NoTrackingWithIdentityResolution(async); + + AssertSql( + """ +SELECT [j].[OwnedReferenceRoot], [j].[Id] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Basic_json_projection_owned_reference_duplicated(bool async) + { + await base.Basic_json_projection_owned_reference_duplicated(async); + + AssertSql( + """ +SELECT [j].[OwnedReferenceRoot], [j].[Id], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch'), [j].[OwnedReferenceRoot], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch') +FROM [JsonEntitiesBasic] AS [j] +ORDER BY [j].[Id] +"""); + } + + public override async Task Basic_json_projection_owned_reference_duplicated_NoTrackingWithIdentityResolution(bool async) + { + await base.Basic_json_projection_owned_reference_duplicated_NoTrackingWithIdentityResolution(async); + + AssertSql( + """ +SELECT [j].[OwnedReferenceRoot], [j].[Id], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch'), [j].[OwnedReferenceRoot], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch') +FROM [JsonEntitiesBasic] AS [j] +ORDER BY [j].[Id] +"""); + } + + public override async Task Basic_json_projection_owned_reference_duplicated2(bool async) + { + await base.Basic_json_projection_owned_reference_duplicated2(async); + + AssertSql( + """ +SELECT [j].[OwnedReferenceRoot], [j].[Id], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedReferenceLeaf'), [j].[OwnedReferenceRoot], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedReferenceLeaf') +FROM [JsonEntitiesBasic] AS [j] +ORDER BY [j].[Id] +"""); + } + + public override async Task Basic_json_projection_owned_reference_duplicated2_NoTrackingWithIdentityResolution(bool async) + { + await base.Basic_json_projection_owned_reference_duplicated2_NoTrackingWithIdentityResolution(async); + + AssertSql( + """ +SELECT [j].[OwnedReferenceRoot], [j].[Id], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedReferenceLeaf'), [j].[OwnedReferenceRoot], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedReferenceLeaf') +FROM [JsonEntitiesBasic] AS [j] +ORDER BY [j].[Id] +"""); + } + + public override async Task Basic_json_projection_owned_collection_root(bool async) + { + await base.Basic_json_projection_owned_collection_root(async); + + AssertSql( + """ +SELECT [j].[OwnedCollectionRoot], [j].[Id] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Basic_json_projection_owned_collection_root_NoTrackingWithIdentityResolution(bool async) + { + await base.Basic_json_projection_owned_collection_root_NoTrackingWithIdentityResolution(async); + + AssertSql( + """ +SELECT [j].[OwnedCollectionRoot], [j].[Id] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Basic_json_projection_owned_reference_branch(bool async) + { + await base.Basic_json_projection_owned_reference_branch(async); + + AssertSql( + """ +SELECT JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch'), [j].[Id] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Basic_json_projection_owned_reference_branch_NoTrackingWithIdentityResolution(bool async) + { + await base.Basic_json_projection_owned_reference_branch_NoTrackingWithIdentityResolution(async); + + AssertSql( + """ +SELECT JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch'), [j].[Id] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Basic_json_projection_owned_collection_branch(bool async) + { + await base.Basic_json_projection_owned_collection_branch(async); + + AssertSql( + """ +SELECT JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch'), [j].[Id] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Basic_json_projection_owned_collection_branch_NoTrackingWithIdentityResolution(bool async) + { + await base.Basic_json_projection_owned_collection_branch_NoTrackingWithIdentityResolution(async); + + AssertSql( + """ +SELECT JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch'), [j].[Id] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Basic_json_projection_owned_reference_leaf(bool async) + { + await base.Basic_json_projection_owned_reference_leaf(async); + + AssertSql( + """ +SELECT JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedReferenceLeaf'), [j].[Id] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Basic_json_projection_owned_collection_leaf(bool async) + { + await base.Basic_json_projection_owned_collection_leaf(async); + + AssertSql( + """ +SELECT JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedCollectionLeaf'), [j].[Id] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Basic_json_projection_scalar(bool async) + { + await base.Basic_json_projection_scalar(async); + + AssertSql( + """ +SELECT JSON_VALUE([j].[OwnedReferenceRoot], '$.Name') +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Json_scalar_length(bool async) + { + await base.Json_scalar_length(async); + + AssertSql( + """ +SELECT [j].[Name] +FROM [JsonEntitiesBasic] AS [j] +WHERE CAST(LEN(JSON_VALUE([j].[OwnedReferenceRoot], '$.Name')) AS int) > 2 +"""); + } + + public override async Task Basic_json_projection_enum_inside_json_entity(bool async) + { + await base.Basic_json_projection_enum_inside_json_entity(async); + + AssertSql( + """ +SELECT [j].[Id], CAST(JSON_VALUE([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.Enum') AS int) AS [Enum] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Json_projection_enum_with_custom_conversion(bool async) + { + await base.Json_projection_enum_with_custom_conversion(async); + + AssertSql( + """ +SELECT [j].[Id], CAST(JSON_VALUE([j].[json_reference_custom_naming], '$."1CustomEnum"') AS int) AS [Enum] +FROM [JsonEntitiesCustomNaming] AS [j] +"""); + } + + public override async Task Json_projection_with_deduplication(bool async) + { + await base.Json_projection_with_deduplication(async); + + AssertSql( + """ +SELECT [j].[Id], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch'), JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedReferenceLeaf'), JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedCollectionLeaf'), JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch'), JSON_VALUE([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedReferenceLeaf.SomethingSomething') +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Json_projection_with_deduplication_reverse_order(bool async) + { + await base.Json_projection_with_deduplication_reverse_order(async); + + AssertSql( + """ +SELECT JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedReferenceLeaf'), [j].[Id], [j].[OwnedReferenceRoot], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Json_property_in_predicate(bool async) + { + await base.Json_property_in_predicate(async); + + AssertSql( + """ +SELECT [j].[Id] +FROM [JsonEntitiesBasic] AS [j] +WHERE CAST(JSON_VALUE([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.Fraction') AS decimal(18,2)) < 20.5 +"""); + } + + public override async Task Json_subquery_property_pushdown_length(bool async) + { + await base.Json_subquery_property_pushdown_length(async); + + AssertSql( + """ +@__p_0='3' + +SELECT CAST(LEN([j1].[c]) AS int) +FROM ( + SELECT DISTINCT [j0].[c] + FROM ( + SELECT TOP(@__p_0) JSON_VALUE([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedReferenceLeaf.SomethingSomething') AS [c] + FROM [JsonEntitiesBasic] AS [j] + ORDER BY [j].[Id] + ) AS [j0] +) AS [j1] +"""); + } + + public override async Task Json_subquery_reference_pushdown_reference(bool async) + { + // TODO:SQLJSON Json type is not comparable + Assert.Equal( + "The json data type cannot be selected as DISTINCT because it is not comparable.", + (await Assert.ThrowsAsync(() => base.Json_subquery_reference_pushdown_reference(async))).Message); + + AssertSql( + """ +@__p_0='10' + +SELECT JSON_QUERY([j1].[c], '$.OwnedReferenceBranch'), [j1].[Id] +FROM ( + SELECT DISTINCT [j0].[c] AS [c], [j0].[Id] + FROM ( + SELECT TOP(@__p_0) [j].[OwnedReferenceRoot] AS [c], [j].[Id] + FROM [JsonEntitiesBasic] AS [j] + ORDER BY [j].[Id] + ) AS [j0] +) AS [j1] +"""); + } + + public override async Task Json_subquery_reference_pushdown_reference_anonymous_projection(bool async) + { + await base.Json_subquery_reference_pushdown_reference_anonymous_projection(async); + + AssertSql( + """ +@__p_0='10' + +SELECT JSON_QUERY([t0].[c], '$.OwnedReferenceSharedBranch'), [t0].[Id], CAST(LEN([t0].[c0]) AS int) +FROM ( + SELECT DISTINCT JSON_QUERY([t].[c],'$') AS [c], [t].[Id], [t].[c0] + FROM ( + SELECT TOP(@__p_0) JSON_QUERY([j].[json_reference_shared], '$') AS [c], [j].[Id], CAST(JSON_VALUE([j].[json_reference_shared], '$.OwnedReferenceSharedBranch.OwnedReferenceSharedLeaf.SomethingSomething') AS nvarchar(max)) AS [c0] + FROM [JsonEntitiesBasic] AS [j] + ORDER BY [j].[Id] + ) AS [t] +) AS [t0] +"""); + } + + public override async Task Json_subquery_reference_pushdown_reference_pushdown_anonymous_projection(bool async) + { + await base.Json_subquery_reference_pushdown_reference_pushdown_anonymous_projection(async); + + AssertSql( + """ +@__p_0='10' + +SELECT JSON_QUERY([t2].[c],'$.OwnedReferenceSharedLeaf'), [t2].[Id], JSON_QUERY([t2].[c], '$.OwnedCollectionSharedLeaf'), [t2].[Length] +FROM ( + SELECT DISTINCT JSON_QUERY([t1].[c],'$') AS [c], [t1].[Id], [t1].[Length] + FROM ( + SELECT TOP(@__p_0) JSON_QUERY([t0].[c], '$.OwnedReferenceSharedBranch') AS [c], [t0].[Id], CAST(LEN([t0].[Scalar]) AS int) AS [Length] + FROM ( + SELECT DISTINCT JSON_QUERY([t].[c],'$') AS [c], [t].[Id], [t].[Scalar] + FROM ( + SELECT TOP(@__p_0) JSON_QUERY([j].[json_reference_shared], '$') AS [c], [j].[Id], CAST(JSON_VALUE([j].[json_reference_shared], '$.OwnedReferenceSharedBranch.OwnedReferenceSharedLeaf.SomethingSomething') AS nvarchar(max)) AS [Scalar] + FROM [JsonEntitiesBasic] AS [j] + ORDER BY [j].[Id] + ) AS [t] + ) AS [t0] + ORDER BY CAST(LEN([t0].[Scalar]) AS int) + ) AS [t1] +) AS [t2] +"""); + } + + public override async Task Json_subquery_reference_pushdown_reference_pushdown_reference(bool async) + { + // TODO:SQLJSON Json type is not comparable + Assert.StartsWith( + "The json data type cannot be selected as DISTINCT because it is not comparable.", + (await Assert.ThrowsAsync(() => base.Json_subquery_reference_pushdown_reference_pushdown_reference(async))) + .Message); + + AssertSql( + """ +@__p_0='10' + +SELECT JSON_QUERY([j3].[c], '$.OwnedReferenceLeaf'), [j3].[Id] +FROM ( + SELECT DISTINCT [j2].[c] AS [c], [j2].[Id] + FROM ( + SELECT TOP(@__p_0) JSON_QUERY([j1].[c], '$.OwnedReferenceBranch') AS [c], [j1].[Id] + FROM ( + SELECT DISTINCT [j0].[c] AS [c], [j0].[Id], [j0].[c] AS [c0] + FROM ( + SELECT TOP(@__p_0) [j].[OwnedReferenceRoot] AS [c], [j].[Id] + FROM [JsonEntitiesBasic] AS [j] + ORDER BY [j].[Id] + ) AS [j0] + ) AS [j1] + ORDER BY JSON_VALUE([j1].[c0], '$.Name') + ) AS [j2] +) AS [j3] +"""); + } + + public override async Task Json_subquery_reference_pushdown_reference_pushdown_collection(bool async) + { + // TODO:SQLJSON Json type is not comparable + Assert.StartsWith( + "The json data type cannot be selected as DISTINCT because it is not comparable.", + (await Assert.ThrowsAsync(() => base.Json_subquery_reference_pushdown_reference_pushdown_collection(async))) + .Message); + + AssertSql( + """ +@__p_0='10' + +SELECT JSON_QUERY([j3].[c], '$.OwnedCollectionLeaf'), [j3].[Id] +FROM ( + SELECT DISTINCT [j2].[c] AS [c], [j2].[Id] + FROM ( + SELECT TOP(@__p_0) JSON_QUERY([j1].[c], '$.OwnedReferenceBranch') AS [c], [j1].[Id] + FROM ( + SELECT DISTINCT [j0].[c] AS [c], [j0].[Id], [j0].[c] AS [c0] + FROM ( + SELECT TOP(@__p_0) [j].[OwnedReferenceRoot] AS [c], [j].[Id] + FROM [JsonEntitiesBasic] AS [j] + ORDER BY [j].[Id] + ) AS [j0] + ) AS [j1] + ORDER BY JSON_VALUE([j1].[c0], '$.Name') + ) AS [j2] +) AS [j3] +"""); + } + + public override async Task Json_subquery_reference_pushdown_property(bool async) + { + // TODO:SQLJSON Json type is not comparable + Assert.Equal( + "The json data type cannot be selected as DISTINCT because it is not comparable.", + (await Assert.ThrowsAsync(() => base.Json_subquery_reference_pushdown_property(async))).Message); + + AssertSql( + """ +@__p_0='10' + +SELECT JSON_VALUE([j1].[c], '$.SomethingSomething') +FROM ( + SELECT DISTINCT [j0].[c] AS [c], [j0].[Id] + FROM ( + SELECT TOP(@__p_0) JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedReferenceLeaf') AS [c], [j].[Id] + FROM [JsonEntitiesBasic] AS [j] + ORDER BY [j].[Id] + ) AS [j0] +) AS [j1] +"""); + } + + public override async Task Custom_naming_projection_owner_entity(bool async) + { + await base.Custom_naming_projection_owner_entity(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[Title], [j].[json_collection_custom_naming], [j].[json_reference_custom_naming] +FROM [JsonEntitiesCustomNaming] AS [j] +"""); + } + + public override async Task Custom_naming_projection_owned_reference(bool async) + { + await base.Custom_naming_projection_owned_reference(async); + + AssertSql( + """ +SELECT JSON_QUERY([j].[json_reference_custom_naming], '$."Custom#OwnedReferenceBranch\u0060-=[]\\;\u0027,./~!@#$%^\u0026*()_\u002B{}|:\u0022\u003C\u003E?\u72EC\u89D2\u517D\u03C0\u7368\u89D2\u7378"'), [j].[Id] +FROM [JsonEntitiesCustomNaming] AS [j] +"""); + } + + public override async Task Custom_naming_projection_owned_collection(bool async) + { + await base.Custom_naming_projection_owned_collection(async); + + AssertSql( + """ +SELECT [j].[json_collection_custom_naming], [j].[Id] +FROM [JsonEntitiesCustomNaming] AS [j] +ORDER BY [j].[Id] +"""); + } + + public override async Task Custom_naming_projection_owned_scalar(bool async) + { + await base.Custom_naming_projection_owned_scalar(async); + + AssertSql( + """ +SELECT CAST(JSON_VALUE([j].[json_reference_custom_naming], '$."Custom#OwnedReferenceBranch\u0060-=[]\\;\u0027,./~!@#$%^\u0026*()_\u002B{}|:\u0022\u003C\u003E?\u72EC\u89D2\u517D\u03C0\u7368\u89D2\u7378"."\u30E6\u30CB\u30B3\u30FC\u30F3Fraction\u4E00\u89D2\u7363"') AS float) +FROM [JsonEntitiesCustomNaming] AS [j] +"""); + } + + public override async Task Custom_naming_projection_everything(bool async) + { + await base.Custom_naming_projection_everything(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[Title], [j].[json_collection_custom_naming], [j].[json_reference_custom_naming], [j].[json_reference_custom_naming], JSON_QUERY([j].[json_reference_custom_naming], '$."Custom#OwnedReferenceBranch\u0060-=[]\\;\u0027,./~!@#$%^\u0026*()_\u002B{}|:\u0022\u003C\u003E?\u72EC\u89D2\u517D\u03C0\u7368\u89D2\u7378"'), [j].[json_collection_custom_naming], JSON_QUERY([j].[json_reference_custom_naming], '$.CustomOwnedCollectionBranch'), JSON_VALUE([j].[json_reference_custom_naming], '$.CustomName'), CAST(JSON_VALUE([j].[json_reference_custom_naming], '$."Custom#OwnedReferenceBranch\u0060-=[]\\;\u0027,./~!@#$%^\u0026*()_\u002B{}|:\u0022\u003C\u003E?\u72EC\u89D2\u517D\u03C0\u7368\u89D2\u7378"."\u30E6\u30CB\u30B3\u30FC\u30F3Fraction\u4E00\u89D2\u7363"') AS float) +FROM [JsonEntitiesCustomNaming] AS [j] +"""); + } + + public override async Task Project_entity_with_single_owned(bool async) + { + await base.Project_entity_with_single_owned(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[Name], [j].[OwnedCollection] +FROM [JsonEntitiesSingleOwned] AS [j] +"""); + } + + public override async Task Left_join_json_entities(bool async) + { + // TODO:SQLJSON Returns empty (invalid) JSON (See BadJson.cs) + if (async) + { + Assert.Equal( + "Unable to cast object of type 'System.DBNull' to type 'System.String'.", + (await Assert.ThrowsAsync(() => base.Left_join_json_entities(true))).Message); + } + else + { + Assert.Equal( + RelationalStrings.JsonEmptyString, + (await Assert.ThrowsAsync(() => base.Left_join_json_entities(false))) + .Message); + } + + AssertSql( + """ +SELECT [j].[Id], [j].[Name], [j].[OwnedCollection], [j0].[Id], [j0].[EntityBasicId], [j0].[Name], [j0].[OwnedCollectionRoot], [j0].[OwnedReferenceRoot] +FROM [JsonEntitiesSingleOwned] AS [j] +LEFT JOIN [JsonEntitiesBasic] AS [j0] ON [j].[Id] = [j0].[Id] +"""); + } + + public override async Task Left_join_json_entities_complex_projection(bool async) + { + // TODO:SQLJSON Returns empty (invalid) JSON (See BadJson.cs) + if (async) + { + Assert.Equal( + "Unable to cast object of type 'System.DBNull' to type 'System.String'.", + (await Assert.ThrowsAsync(() => base.Left_join_json_entities_complex_projection(true))).Message); + } + else + { + Assert.Equal( + RelationalStrings.JsonEmptyString, + (await Assert.ThrowsAsync(() => base.Left_join_json_entities_complex_projection(false))) + .Message); + } + + AssertSql( + """ +SELECT [j].[Id], [j0].[Id], [j0].[OwnedReferenceRoot], JSON_QUERY([j0].[OwnedReferenceRoot], '$.OwnedReferenceBranch'), JSON_QUERY([j0].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedReferenceLeaf'), JSON_QUERY([j0].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedCollectionLeaf') +FROM [JsonEntitiesSingleOwned] AS [j] +LEFT JOIN [JsonEntitiesBasic] AS [j0] ON [j].[Id] = [j0].[Id] +"""); + } + + public override async Task Left_join_json_entities_json_being_inner(bool async) + { + await base.Left_join_json_entities_json_being_inner(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot], [j0].[Id], [j0].[Name], [j0].[OwnedCollection] +FROM [JsonEntitiesBasic] AS [j] +LEFT JOIN [JsonEntitiesSingleOwned] AS [j0] ON [j].[Id] = [j0].[Id] +"""); + } + + public override async Task Left_join_json_entities_complex_projection_json_being_inner(bool async) + { + await base.Left_join_json_entities_complex_projection_json_being_inner(async); + + AssertSql( + """ +SELECT [j].[Id], [j0].[Id], [j].[OwnedReferenceRoot], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch'), JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedReferenceLeaf'), JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedCollectionLeaf'), [j0].[Name] +FROM [JsonEntitiesBasic] AS [j] +LEFT JOIN [JsonEntitiesSingleOwned] AS [j0] ON [j].[Id] = [j0].[Id] +"""); + } + + public override async Task Project_json_entity_FirstOrDefault_subquery(bool async) + { + await base.Project_json_entity_FirstOrDefault_subquery(async); + + AssertSql( + """ +SELECT [j1].[c], [j1].[Id] +FROM [JsonEntitiesBasic] AS [j] +OUTER APPLY ( + SELECT TOP(1) JSON_QUERY([j0].[OwnedReferenceRoot], '$.OwnedReferenceBranch') AS [c], [j0].[Id] + FROM [JsonEntitiesBasic] AS [j0] + ORDER BY [j0].[Id] +) AS [j1] +ORDER BY [j].[Id] +"""); + } + + public override async Task Project_json_entity_FirstOrDefault_subquery_with_binding_on_top(bool async) + { + await base.Project_json_entity_FirstOrDefault_subquery_with_binding_on_top(async); + + AssertSql( + """ +SELECT ( + SELECT TOP(1) CAST(JSON_VALUE([j0].[OwnedReferenceRoot], '$.OwnedReferenceBranch.Date') AS datetime2) + FROM [JsonEntitiesBasic] AS [j0] + ORDER BY [j0].[Id]) +FROM [JsonEntitiesBasic] AS [j] +ORDER BY [j].[Id] +"""); + } + + public override async Task Project_json_entity_FirstOrDefault_subquery_with_entity_comparison_on_top(bool async) + { + await base.Project_json_entity_FirstOrDefault_subquery_with_entity_comparison_on_top(async); + + AssertSql( + @""); + } + + public override async Task Project_json_entity_FirstOrDefault_subquery_deduplication(bool async) + { + await base.Project_json_entity_FirstOrDefault_subquery_deduplication(async); + + AssertSql( + """ +SELECT [j1].[c], [j1].[Id], [j1].[c0], [j1].[Id0], [j1].[c1], [j1].[c2], [j1].[c3], [j1].[c4] +FROM [JsonEntitiesBasic] AS [j] +OUTER APPLY ( + SELECT TOP(1) JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch') AS [c], [j].[Id], [j0].[OwnedReferenceRoot] AS [c0], [j0].[Id] AS [Id0], JSON_QUERY([j0].[OwnedReferenceRoot], '$.OwnedReferenceBranch') AS [c1], JSON_VALUE([j0].[OwnedReferenceRoot], '$.Name') AS [c2], CAST(JSON_VALUE([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.Enum') AS int) AS [c3], 1 AS [c4] + FROM [JsonEntitiesBasic] AS [j0] + ORDER BY [j0].[Id] +) AS [j1] +ORDER BY [j].[Id] +"""); + } + + public override async Task Project_json_entity_FirstOrDefault_subquery_deduplication_and_outer_reference(bool async) + { + await base.Project_json_entity_FirstOrDefault_subquery_deduplication_and_outer_reference(async); + + AssertSql( + """ +SELECT [j1].[c], [j1].[Id], [j1].[c0], [j1].[Id0], [j1].[c1], [j1].[c2], [j1].[c3], [j1].[c4] +FROM [JsonEntitiesBasic] AS [j] +OUTER APPLY ( + SELECT TOP(1) JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch') AS [c], [j].[Id], [j0].[OwnedReferenceRoot] AS [c0], [j0].[Id] AS [Id0], JSON_QUERY([j0].[OwnedReferenceRoot], '$.OwnedReferenceBranch') AS [c1], JSON_VALUE([j0].[OwnedReferenceRoot], '$.Name') AS [c2], CAST(JSON_VALUE([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.Enum') AS int) AS [c3], 1 AS [c4] + FROM [JsonEntitiesBasic] AS [j0] + ORDER BY [j0].[Id] +) AS [j1] +ORDER BY [j].[Id] +"""); + } + + public override async Task Project_json_entity_FirstOrDefault_subquery_deduplication_outer_reference_and_pruning(bool async) + { + await base.Project_json_entity_FirstOrDefault_subquery_deduplication_outer_reference_and_pruning(async); + + AssertSql( + """ +SELECT [j1].[c], [j1].[Id], [j1].[c0] +FROM [JsonEntitiesBasic] AS [j] +OUTER APPLY ( + SELECT TOP(1) JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch') AS [c], [j].[Id], 1 AS [c0] + FROM [JsonEntitiesBasic] AS [j0] + ORDER BY [j0].[Id] +) AS [j1] +ORDER BY [j].[Id] +"""); + } + + public override async Task Json_entity_with_inheritance_basic_projection(bool async) + { + // TODO:SQLJSON Returns empty (invalid) JSON (See BadJson.cs) + if (async) + { + Assert.Equal( + "Unable to cast object of type 'System.DBNull' to type 'System.String'.", + (await Assert.ThrowsAsync(() => base.Json_entity_with_inheritance_basic_projection(true))).Message); + } + else + { + Assert.Equal( + RelationalStrings.JsonEmptyString, + (await Assert.ThrowsAsync(() => base.Json_entity_with_inheritance_basic_projection(false))) + .Message); + } + + AssertSql( + """ +SELECT [j].[Id], [j].[Discriminator], [j].[Name], [j].[Fraction], [j].[CollectionOnBase], [j].[ReferenceOnBase], [j].[CollectionOnDerived], [j].[ReferenceOnDerived] +FROM [JsonEntitiesInheritance] AS [j] +"""); + } + + public override async Task Json_entity_with_inheritance_project_derived(bool async) + { + await base.Json_entity_with_inheritance_project_derived(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[Discriminator], [j].[Name], [j].[Fraction], [j].[CollectionOnBase], [j].[ReferenceOnBase], [j].[CollectionOnDerived], [j].[ReferenceOnDerived] +FROM [JsonEntitiesInheritance] AS [j] +WHERE [j].[Discriminator] = N'JsonEntityInheritanceDerived' +"""); + } + + public override async Task Json_entity_with_inheritance_project_navigations(bool async) + { + await base.Json_entity_with_inheritance_project_navigations(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[ReferenceOnBase], [j].[CollectionOnBase] +FROM [JsonEntitiesInheritance] AS [j] +"""); + } + + public override async Task Json_entity_with_inheritance_project_navigations_on_derived(bool async) + { + await base.Json_entity_with_inheritance_project_navigations_on_derived(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[ReferenceOnBase], [j].[ReferenceOnDerived], [j].[CollectionOnBase], [j].[CollectionOnDerived] +FROM [JsonEntitiesInheritance] AS [j] +WHERE [j].[Discriminator] = N'JsonEntityInheritanceDerived' +"""); + } + + public override async Task Json_entity_backtracking(bool async) + { + await base.Json_entity_backtracking(async); + + AssertSql( + @""); + } + + public override async Task Json_collection_index_in_projection_basic(bool async) + { + await base.Json_collection_index_in_projection_basic(async); + + AssertSql( + """ +SELECT JSON_QUERY([j].[OwnedCollectionRoot], '$[1]'), [j].[Id] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Json_collection_ElementAt_in_projection(bool async) + { + await base.Json_collection_ElementAt_in_projection(async); + + AssertSql( + """ +SELECT JSON_QUERY([j].[OwnedCollectionRoot], '$[1]'), [j].[Id] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Json_collection_ElementAtOrDefault_in_projection(bool async) + { + await base.Json_collection_ElementAtOrDefault_in_projection(async); + + AssertSql( + """ +SELECT JSON_QUERY([j].[OwnedCollectionRoot], '$[1]'), [j].[Id] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Json_collection_index_in_projection_project_collection(bool async) + { + await base.Json_collection_index_in_projection_project_collection(async); + + AssertSql( + """ +SELECT JSON_QUERY([j].[OwnedCollectionRoot], '$[1].OwnedCollectionBranch'), [j].[Id] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Json_collection_ElementAt_project_collection(bool async) + { + await base.Json_collection_ElementAt_project_collection(async); + + AssertSql( + """ +SELECT JSON_QUERY([j].[OwnedCollectionRoot], '$[1].OwnedCollectionBranch'), [j].[Id] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Json_collection_ElementAtOrDefault_project_collection(bool async) + { + await base.Json_collection_ElementAtOrDefault_project_collection(async); + + AssertSql( + """ +SELECT JSON_QUERY([j].[OwnedCollectionRoot], '$[1].OwnedCollectionBranch'), [j].[Id] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + [SqlServerCondition(SqlServerCondition.SupportsJsonPathExpressions)] + public override async Task Json_collection_index_in_projection_using_parameter(bool async) + { + await base.Json_collection_index_in_projection_using_parameter(async); + + AssertSql( + """ +@__prm_0='0' + +SELECT JSON_QUERY([j].[OwnedCollectionRoot], '$[' + CAST(@__prm_0 AS nvarchar(max)) + ']'), [j].[Id], @__prm_0 +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + [SqlServerCondition(SqlServerCondition.SupportsJsonPathExpressions)] + public override async Task Json_collection_index_in_projection_using_column(bool async) + { + await base.Json_collection_index_in_projection_using_column(async); + + AssertSql( + """ +SELECT JSON_QUERY([j].[OwnedCollectionRoot], '$[' + CAST([j].[Id] AS nvarchar(max)) + ']'), [j].[Id] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Json_collection_index_in_projection_using_untranslatable_client_method(bool async) + { + var message = (await Assert.ThrowsAsync( + () => base.Json_collection_index_in_projection_using_untranslatable_client_method(async))).Message; + + Assert.Contains( + CoreStrings.QueryUnableToTranslateMethod( + "Microsoft.EntityFrameworkCore.Query.JsonQueryTestBase", + "MyMethod"), + message); + } + + public override async Task Json_collection_index_in_projection_using_untranslatable_client_method2(bool async) + { + var message = (await Assert.ThrowsAsync( + () => base.Json_collection_index_in_projection_using_untranslatable_client_method2(async))).Message; + + Assert.Contains( + CoreStrings.QueryUnableToTranslateMethod( + "Microsoft.EntityFrameworkCore.Query.JsonQueryTestBase", + "MyMethod"), + message); + } + + public override async Task Json_collection_index_outside_bounds(bool async) + { + // TODO:SQLJSON Returns empty (invalid) JSON (See BadJson.cs) + if (async) + { + Assert.Equal( + "Unable to cast object of type 'System.DBNull' to type 'System.String'.", + (await Assert.ThrowsAsync(() => base.Json_collection_index_outside_bounds(true))).Message); + } + else + { + Assert.Equal( + RelationalStrings.JsonEmptyString, + (await Assert.ThrowsAsync(() => base.Json_collection_index_outside_bounds(false))) + .Message); + } + + AssertSql( + """ +SELECT JSON_QUERY([j].[OwnedCollectionRoot], '$[25]'), [j].[Id] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Json_collection_index_outside_bounds2(bool async) + { + // TODO:SQLJSON Returns empty (invalid) JSON (See BadJson.cs) + if (async) + { + Assert.Equal( + "Unable to cast object of type 'System.DBNull' to type 'System.String'.", + (await Assert.ThrowsAsync(() => base.Json_collection_index_outside_bounds2(true))).Message); + } + else + { + Assert.Equal( + RelationalStrings.JsonEmptyString, + (await Assert.ThrowsAsync(() => base.Json_collection_index_outside_bounds2(false))) + .Message); + } + + AssertSql( + """ +SELECT JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedCollectionLeaf[25]'), [j].[Id] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Json_collection_index_outside_bounds_with_property_access(bool async) + { + await base.Json_collection_index_outside_bounds_with_property_access(async); + + AssertSql( + """ +SELECT CAST(JSON_VALUE([j].[OwnedCollectionRoot], '$[25].Number') AS int) +FROM [JsonEntitiesBasic] AS [j] +ORDER BY [j].[Id] +"""); + } + + [SqlServerCondition(SqlServerCondition.SupportsJsonPathExpressions)] + public override async Task Json_collection_index_in_projection_nested(bool async) + { + await base.Json_collection_index_in_projection_nested(async); + + AssertSql( + """ +@__prm_0='1' + +SELECT JSON_QUERY([j].[OwnedCollectionRoot], '$[0].OwnedCollectionBranch[' + CAST(@__prm_0 AS nvarchar(max)) + ']'), [j].[Id], @__prm_0 +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + [SqlServerCondition(SqlServerCondition.SupportsJsonPathExpressions)] + public override async Task Json_collection_index_in_projection_nested_project_scalar(bool async) + { + await base.Json_collection_index_in_projection_nested_project_scalar(async); + + AssertSql( + """ +@__prm_0='1' + +SELECT CAST(JSON_VALUE([j].[OwnedCollectionRoot], '$[0].OwnedCollectionBranch[' + CAST(@__prm_0 AS nvarchar(max)) + '].Date') AS datetime2) +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + [SqlServerCondition(SqlServerCondition.SupportsJsonPathExpressions)] + public override async Task Json_collection_index_in_projection_nested_project_reference(bool async) + { + await base.Json_collection_index_in_projection_nested_project_reference(async); + + AssertSql( + """ +@__prm_0='1' + +SELECT JSON_QUERY([j].[OwnedCollectionRoot], '$[0].OwnedCollectionBranch[' + CAST(@__prm_0 AS nvarchar(max)) + '].OwnedReferenceLeaf'), [j].[Id], @__prm_0 +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + [SqlServerCondition(SqlServerCondition.SupportsJsonPathExpressions)] + public override async Task Json_collection_index_in_projection_nested_project_collection(bool async) + { + await base.Json_collection_index_in_projection_nested_project_collection(async); + + AssertSql( + """ +@__prm_0='1' + +SELECT JSON_QUERY([j].[OwnedCollectionRoot], '$[0].OwnedCollectionBranch[' + CAST(@__prm_0 AS nvarchar(max)) + '].OwnedCollectionLeaf'), [j].[Id], @__prm_0 +FROM [JsonEntitiesBasic] AS [j] +ORDER BY [j].[Id] +"""); + } + + [SqlServerCondition(SqlServerCondition.SupportsJsonPathExpressions)] + public override async Task Json_collection_index_in_projection_nested_project_collection_anonymous_projection(bool async) + { + await base.Json_collection_index_in_projection_nested_project_collection_anonymous_projection(async); + + AssertSql( + """ +@__prm_0='1' + +SELECT [j].[Id], JSON_QUERY([j].[OwnedCollectionRoot], '$[0].OwnedCollectionBranch[' + CAST(@__prm_0 AS nvarchar(max)) + '].OwnedCollectionLeaf'), @__prm_0 +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Json_collection_index_in_predicate_using_constant(bool async) + { + await base.Json_collection_index_in_predicate_using_constant(async); + + AssertSql( + """ +SELECT [j].[Id] +FROM [JsonEntitiesBasic] AS [j] +WHERE JSON_VALUE([j].[OwnedCollectionRoot], '$[0].Name') <> N'Foo' OR JSON_VALUE([j].[OwnedCollectionRoot], '$[0].Name') IS NULL +"""); + } + + [SqlServerCondition(SqlServerCondition.SupportsJsonPathExpressions)] + public override async Task Json_collection_index_in_predicate_using_variable(bool async) + { + await base.Json_collection_index_in_predicate_using_variable(async); + + AssertSql( + """ +@__prm_0='1' + +SELECT [j].[Id] +FROM [JsonEntitiesBasic] AS [j] +WHERE JSON_VALUE([j].[OwnedCollectionRoot], '$[' + CAST(@__prm_0 AS nvarchar(max)) + '].Name') <> N'Foo' OR JSON_VALUE([j].[OwnedCollectionRoot], '$[' + CAST(@__prm_0 AS nvarchar(max)) + '].Name') IS NULL +"""); + } + + [SqlServerCondition(SqlServerCondition.SupportsJsonPathExpressions)] + public override async Task Json_collection_index_in_predicate_using_column(bool async) + { + await base.Json_collection_index_in_predicate_using_column(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +WHERE JSON_VALUE([j].[OwnedCollectionRoot], '$[' + CAST([j].[Id] AS nvarchar(max)) + '].Name') = N'e1_c2' +"""); + } + + [SqlServerCondition(SqlServerCondition.SupportsJsonPathExpressions)] + public override async Task Json_collection_index_in_predicate_using_complex_expression1(bool async) + { + await base.Json_collection_index_in_predicate_using_complex_expression1(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +WHERE JSON_VALUE([j].[OwnedCollectionRoot], '$[' + CAST(CASE + WHEN [j].[Id] = 1 THEN 0 + ELSE 1 +END AS nvarchar(max)) + '].Name') = N'e1_c1' +"""); + } + + [SqlServerCondition(SqlServerCondition.SupportsJsonPathExpressions)] + public override async Task Json_collection_index_in_predicate_using_complex_expression2(bool async) + { + await base.Json_collection_index_in_predicate_using_complex_expression2(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +WHERE JSON_VALUE([j].[OwnedCollectionRoot], '$[' + CAST(( + SELECT MAX([j0].[Id]) + FROM [JsonEntitiesBasic] AS [j0]) AS nvarchar(max)) + '].Name') = N'e1_c2' +"""); + } + + public override async Task Json_collection_ElementAt_in_predicate(bool async) + { + await base.Json_collection_ElementAt_in_predicate(async); + + AssertSql( + """ +SELECT [j].[Id] +FROM [JsonEntitiesBasic] AS [j] +WHERE JSON_VALUE([j].[OwnedCollectionRoot], '$[1].Name') <> N'Foo' OR JSON_VALUE([j].[OwnedCollectionRoot], '$[1].Name') IS NULL +"""); + } + + [SqlServerCondition(SqlServerCondition.SupportsJsonPathExpressions)] + public override async Task Json_collection_index_in_predicate_nested_mix(bool async) + { + await base.Json_collection_index_in_predicate_nested_mix(async); + + AssertSql( + """ +@__prm_0='0' + +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +WHERE JSON_VALUE([j].[OwnedCollectionRoot], '$[1].OwnedCollectionBranch[' + CAST(@__prm_0 AS nvarchar(max)) + '].OwnedCollectionLeaf[' + CAST([j].[Id] - 1 AS nvarchar(max)) + '].SomethingSomething') = N'e1_c2_c1_c1' +"""); + } + + public override async Task Json_collection_ElementAt_and_pushdown(bool async) + { + await base.Json_collection_ElementAt_and_pushdown(async); + + AssertSql( + """ +SELECT [j].[Id], CAST(JSON_VALUE([j].[OwnedCollectionRoot], '$[0].Number') AS int) AS [CollectionElement] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Json_collection_Any_with_predicate(bool async) + { + await base.Json_collection_Any_with_predicate(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +WHERE EXISTS ( + SELECT 1 + FROM OPENJSON(CAST([j].[OwnedReferenceRoot] AS nvarchar(max)), '$.OwnedCollectionBranch') WITH ([OwnedReferenceLeaf] nvarchar(max) '$.OwnedReferenceLeaf' AS JSON) AS [o] + WHERE JSON_VALUE([o].[OwnedReferenceLeaf], '$.SomethingSomething') = N'e1_r_c1_r') +"""); + } + + public override async Task Json_collection_Where_ElementAt(bool async) + { + await base.Json_collection_Where_ElementAt(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +WHERE ( + SELECT JSON_VALUE([o].[value], '$.OwnedReferenceLeaf.SomethingSomething') + FROM OPENJSON(CAST([j].[OwnedReferenceRoot] AS nvarchar(max)), '$.OwnedCollectionBranch') AS [o] + WHERE CAST(JSON_VALUE([o].[value], '$.Enum') AS int) = -3 + ORDER BY CAST([o].[key] AS int) + OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY) = N'e1_r_c2_r' +"""); + } + + public override async Task Json_collection_Skip(bool async) + { + await base.Json_collection_Skip(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +WHERE ( + SELECT [o0].[c] + FROM ( + SELECT JSON_VALUE([o].[value], '$.OwnedReferenceLeaf.SomethingSomething') AS [c], CAST([o].[key] AS int) AS [c0] + FROM OPENJSON(CAST([j].[OwnedReferenceRoot] AS nvarchar(max)), '$.OwnedCollectionBranch') AS [o] + ORDER BY CAST([o].[key] AS int) + OFFSET 1 ROWS + ) AS [o0] + ORDER BY [o0].[c0] + OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY) = N'e1_r_c2_r' +"""); + } + + public override async Task Json_collection_OrderByDescending_Skip_ElementAt(bool async) + { + await base.Json_collection_OrderByDescending_Skip_ElementAt(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +WHERE ( + SELECT [o0].[c] + FROM ( + SELECT JSON_VALUE([o].[OwnedReferenceLeaf], '$.SomethingSomething') AS [c], [o].[Date] AS [c0] + FROM OPENJSON(CAST([j].[OwnedReferenceRoot] AS nvarchar(max)), '$.OwnedCollectionBranch') WITH ( + [Date] datetime2 '$.Date', + [Enum] int '$.Enum', + [Fraction] decimal(18,2) '$.Fraction', + [OwnedReferenceLeaf] nvarchar(max) '$.OwnedReferenceLeaf' AS JSON + ) AS [o] + ORDER BY [o].[Date] DESC + OFFSET 1 ROWS + ) AS [o0] + ORDER BY [o0].[c0] DESC + OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY) = N'e1_r_c1_r' +"""); + } + + public override async Task Json_collection_Distinct_Count_with_predicate(bool async) + { + await base.Json_collection_Distinct_Count_with_predicate(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +WHERE ( + SELECT COUNT(*) + FROM ( + SELECT DISTINCT [j].[Id], [o].[Date], [o].[Enum], [o].[Enums], [o].[Fraction], [o].[NullableEnum], [o].[NullableEnums], [o].[OwnedCollectionLeaf] AS [c], [o].[OwnedReferenceLeaf] AS [c0] + FROM OPENJSON(CAST([j].[OwnedReferenceRoot] AS nvarchar(max)), '$.OwnedCollectionBranch') WITH ( + [Date] datetime2 '$.Date', + [Enum] int '$.Enum', + [Enums] nvarchar(max) '$.Enums' AS JSON, + [Fraction] decimal(18,2) '$.Fraction', + [NullableEnum] int '$.NullableEnum', + [NullableEnums] nvarchar(max) '$.NullableEnums' AS JSON, + [OwnedCollectionLeaf] nvarchar(max) '$.OwnedCollectionLeaf' AS JSON, + [OwnedReferenceLeaf] nvarchar(max) '$.OwnedReferenceLeaf' AS JSON + ) AS [o] + WHERE JSON_VALUE([o].[OwnedReferenceLeaf], '$.SomethingSomething') = N'e1_r_c2_r' + ) AS [o0]) = 1 +"""); + } + + public override async Task Json_collection_within_collection_Count(bool async) + { + await base.Json_collection_within_collection_Count(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +WHERE EXISTS ( + SELECT 1 + FROM OPENJSON(CAST([j].[OwnedCollectionRoot] AS nvarchar(max)), '$') WITH ([OwnedCollectionBranch] nvarchar(max) '$.OwnedCollectionBranch' AS JSON) AS [o] + WHERE ( + SELECT COUNT(*) + FROM OPENJSON(CAST([o].[OwnedCollectionBranch] AS nvarchar(max)), '$') AS [o0]) = 2) +"""); + } + + public override async Task Json_collection_in_projection_with_composition_count(bool async) + { + await base.Json_collection_in_projection_with_composition_count(async); + + AssertSql( + """ +SELECT ( + SELECT COUNT(*) + FROM OPENJSON(CAST([j].[OwnedCollectionRoot] AS nvarchar(max)), '$') AS [o]) +FROM [JsonEntitiesBasic] AS [j] +ORDER BY [j].[Id] +"""); + } + + public override async Task Json_collection_in_projection_with_anonymous_projection_of_scalars(bool async) + { + await base.Json_collection_in_projection_with_anonymous_projection_of_scalars(async); + + AssertSql( + """ +SELECT [j].[Id], JSON_VALUE([o].[value], '$.Name'), CAST(JSON_VALUE([o].[value], '$.Number') AS int), [o].[key] +FROM [JsonEntitiesBasic] AS [j] +OUTER APPLY OPENJSON(CAST([j].[OwnedCollectionRoot] AS nvarchar(max)), '$') AS [o] +ORDER BY [j].[Id], CAST([o].[key] AS int) +"""); + } + + public override async Task Json_collection_in_projection_with_composition_where_and_anonymous_projection_of_scalars(bool async) + { + await base.Json_collection_in_projection_with_composition_where_and_anonymous_projection_of_scalars(async); + + AssertSql( + """ +SELECT [j].[Id], [o0].[Name], [o0].[Number], [o0].[key] +FROM [JsonEntitiesBasic] AS [j] +OUTER APPLY ( + SELECT JSON_VALUE([o].[value], '$.Name') AS [Name], CAST(JSON_VALUE([o].[value], '$.Number') AS int) AS [Number], [o].[key], CAST([o].[key] AS int) AS [c] + FROM OPENJSON(CAST([j].[OwnedCollectionRoot] AS nvarchar(max)), '$') AS [o] + WHERE JSON_VALUE([o].[value], '$.Name') = N'Foo' +) AS [o0] +ORDER BY [j].[Id], [o0].[c] +"""); + } + + public override async Task Json_collection_in_projection_with_composition_where_and_anonymous_projection_of_primitive_arrays(bool async) + { + await base.Json_collection_in_projection_with_composition_where_and_anonymous_projection_of_primitive_arrays(async); + + AssertSql( + """ +SELECT [j].[Id], [o0].[Names], [o0].[Numbers], [o0].[key] +FROM [JsonEntitiesBasic] AS [j] +OUTER APPLY ( + SELECT JSON_QUERY([o].[value], '$.Names') AS [Names], JSON_QUERY([o].[value], '$.Numbers') AS [Numbers], [o].[key], CAST([o].[key] AS int) AS [c] + FROM OPENJSON(CAST([j].[OwnedCollectionRoot] AS nvarchar(max)), '$') AS [o] + WHERE JSON_VALUE([o].[value], '$.Name') = N'Foo' +) AS [o0] +ORDER BY [j].[Id], [o0].[c] +"""); + } + + public override async Task Json_collection_filter_in_projection(bool async) + { + await base.Json_collection_filter_in_projection(async); + + AssertSql( + """ +SELECT [j].[Id], [o0].[Id], [o0].[Name], [o0].[Names], [o0].[Number], [o0].[Numbers], [o0].[c], [o0].[c0], [o0].[key] +FROM [JsonEntitiesBasic] AS [j] +OUTER APPLY ( + SELECT [j].[Id], JSON_VALUE([o].[value], '$.Name') AS [Name], JSON_QUERY([o].[value], '$.Names') AS [Names], CAST(JSON_VALUE([o].[value], '$.Number') AS int) AS [Number], JSON_QUERY([o].[value], '$.Numbers') AS [Numbers], JSON_QUERY([o].[value], '$.OwnedCollectionBranch') AS [c], JSON_QUERY([o].[value], '$.OwnedReferenceBranch') AS [c0], [o].[key], CAST([o].[key] AS int) AS [c1] + FROM OPENJSON(CAST([j].[OwnedCollectionRoot] AS nvarchar(max)), '$') AS [o] + WHERE JSON_VALUE([o].[value], '$.Name') <> N'Foo' OR JSON_VALUE([o].[value], '$.Name') IS NULL +) AS [o0] +ORDER BY [j].[Id], [o0].[c1] +"""); + } + + public override async Task Json_nested_collection_filter_in_projection(bool async) + { + await base.Json_nested_collection_filter_in_projection(async); + + AssertSql( + """ +SELECT [j].[Id], [s].[key], [s].[Id], [s].[Date], [s].[Enum], [s].[Enums], [s].[Fraction], [s].[NullableEnum], [s].[NullableEnums], [s].[c], [s].[c0], [s].[key0] +FROM [JsonEntitiesBasic] AS [j] +OUTER APPLY ( + SELECT [o].[key], [o1].[Id], [o1].[Date], [o1].[Enum], [o1].[Enums], [o1].[Fraction], [o1].[NullableEnum], [o1].[NullableEnums], [o1].[c], [o1].[c0], [o1].[key] AS [key0], CAST([o].[key] AS int) AS [c1], [o1].[c1] AS [c10] + FROM OPENJSON(CAST([j].[OwnedCollectionRoot] AS nvarchar(max)), '$') AS [o] + OUTER APPLY ( + SELECT [j].[Id], CAST(JSON_VALUE([o0].[value], '$.Date') AS datetime2) AS [Date], CAST(JSON_VALUE([o0].[value], '$.Enum') AS int) AS [Enum], JSON_QUERY([o0].[value], '$.Enums') AS [Enums], CAST(JSON_VALUE([o0].[value], '$.Fraction') AS decimal(18,2)) AS [Fraction], CAST(JSON_VALUE([o0].[value], '$.NullableEnum') AS int) AS [NullableEnum], JSON_QUERY([o0].[value], '$.NullableEnums') AS [NullableEnums], JSON_QUERY([o0].[value], '$.OwnedCollectionLeaf') AS [c], JSON_QUERY([o0].[value], '$.OwnedReferenceLeaf') AS [c0], [o0].[key], CAST([o0].[key] AS int) AS [c1] + FROM OPENJSON(CAST(JSON_QUERY([o].[value], '$.OwnedCollectionBranch') AS nvarchar(max)), '$') AS [o0] + WHERE CAST(JSON_VALUE([o0].[value], '$.Date') AS datetime2) <> '2000-01-01T00:00:00.0000000' + ) AS [o1] +) AS [s] +ORDER BY [j].[Id], [s].[c1], [s].[key], [s].[c10] +"""); + } + + public override async Task Json_nested_collection_anonymous_projection_in_projection(bool async) + { + await base.Json_nested_collection_anonymous_projection_in_projection(async); + + AssertSql( + """ +SELECT [j].[Id], [s].[key], [s].[c], [s].[c0], [s].[c1], [s].[c2], [s].[c3], [s].[Id], [s].[c4], [s].[key0] +FROM [JsonEntitiesBasic] AS [j] +OUTER APPLY ( + SELECT [o].[key], CAST(JSON_VALUE([o0].[value], '$.Date') AS datetime2) AS [c], CAST(JSON_VALUE([o0].[value], '$.Enum') AS int) AS [c0], JSON_QUERY([o0].[value], '$.Enums') AS [c1], CAST(JSON_VALUE([o0].[value], '$.Fraction') AS decimal(18,2)) AS [c2], JSON_QUERY([o0].[value], '$.OwnedReferenceLeaf') AS [c3], [j].[Id], JSON_QUERY([o0].[value], '$.OwnedCollectionLeaf') AS [c4], [o0].[key] AS [key0], CAST([o].[key] AS int) AS [c5], CAST([o0].[key] AS int) AS [c6] + FROM OPENJSON(CAST([j].[OwnedCollectionRoot] AS nvarchar(max)), '$') AS [o] + OUTER APPLY OPENJSON(CAST(JSON_QUERY([o].[value], '$.OwnedCollectionBranch') AS nvarchar(max)), '$') AS [o0] +) AS [s] +ORDER BY [j].[Id], [s].[c5], [s].[key], [s].[c6] +"""); + } + + public override async Task Json_collection_skip_take_in_projection(bool async) + { + await base.Json_collection_skip_take_in_projection(async); + + AssertSql( + """ +SELECT [j].[Id], [o0].[Id], [o0].[Name], [o0].[Names], [o0].[Number], [o0].[Numbers], [o0].[c], [o0].[c0], [o0].[key] +FROM [JsonEntitiesBasic] AS [j] +OUTER APPLY ( + SELECT [j].[Id], JSON_VALUE([o].[value], '$.Name') AS [Name], JSON_QUERY([o].[value], '$.Names') AS [Names], CAST(JSON_VALUE([o].[value], '$.Number') AS int) AS [Number], JSON_QUERY([o].[value], '$.Numbers') AS [Numbers], JSON_QUERY([o].[value], '$.OwnedCollectionBranch') AS [c], JSON_QUERY([o].[value], '$.OwnedReferenceBranch') AS [c0], [o].[key], JSON_VALUE([o].[value], '$.Name') AS [c1] + FROM OPENJSON(CAST([j].[OwnedCollectionRoot] AS nvarchar(max)), '$') AS [o] + ORDER BY JSON_VALUE([o].[value], '$.Name') + OFFSET 1 ROWS FETCH NEXT 5 ROWS ONLY +) AS [o0] +ORDER BY [j].[Id], [o0].[c1] +"""); + } + + public override async Task Json_collection_skip_take_in_projection_project_into_anonymous_type(bool async) + { + await base.Json_collection_skip_take_in_projection_project_into_anonymous_type(async); + + AssertSql( + """ +SELECT [j].[Id], [o0].[c], [o0].[c0], [o0].[c1], [o0].[c2], [o0].[c3], [o0].[Id], [o0].[c4], [o0].[key] +FROM [JsonEntitiesBasic] AS [j] +OUTER APPLY ( + SELECT JSON_VALUE([o].[value], '$.Name') AS [c], JSON_QUERY([o].[value], '$.Names') AS [c0], CAST(JSON_VALUE([o].[value], '$.Number') AS int) AS [c1], JSON_QUERY([o].[value], '$.Numbers') AS [c2], JSON_QUERY([o].[value], '$.OwnedCollectionBranch') AS [c3], [j].[Id], JSON_QUERY([o].[value], '$.OwnedReferenceBranch') AS [c4], [o].[key] + FROM OPENJSON(CAST([j].[OwnedCollectionRoot] AS nvarchar(max)), '$') AS [o] + ORDER BY JSON_VALUE([o].[value], '$.Name') + OFFSET 1 ROWS FETCH NEXT 5 ROWS ONLY +) AS [o0] +ORDER BY [j].[Id], [o0].[c] +"""); + } + + public override async Task Json_collection_skip_take_in_projection_with_json_reference_access_as_final_operation(bool async) + { + await base.Json_collection_skip_take_in_projection_with_json_reference_access_as_final_operation(async); + + AssertSql( + """ +SELECT [j].[Id], [o0].[c], [o0].[Id], [o0].[key] +FROM [JsonEntitiesBasic] AS [j] +OUTER APPLY ( + SELECT JSON_QUERY([o].[value], '$.OwnedReferenceBranch') AS [c], [j].[Id], [o].[key], JSON_VALUE([o].[value], '$.Name') AS [c0] + FROM OPENJSON(CAST([j].[OwnedCollectionRoot] AS nvarchar(max)), '$') AS [o] + ORDER BY JSON_VALUE([o].[value], '$.Name') + OFFSET 1 ROWS FETCH NEXT 5 ROWS ONLY +) AS [o0] +ORDER BY [j].[Id], [o0].[c0] +"""); + } + + public override async Task Json_collection_distinct_in_projection(bool async) + { + await base.Json_collection_distinct_in_projection(async); + + AssertSql( + """ +SELECT [j].[Id], [o0].[Id], [o0].[Name], [o0].[Names], [o0].[Number], [o0].[Numbers], [o0].[c], [o0].[c0] +FROM [JsonEntitiesBasic] AS [j] +OUTER APPLY ( + SELECT DISTINCT [j].[Id], [o].[Name], [o].[Names], [o].[Number], [o].[Numbers], [o].[OwnedCollectionBranch] AS [c], [o].[OwnedReferenceBranch] AS [c0] + FROM OPENJSON(CAST([j].[OwnedCollectionRoot] AS nvarchar(max)), '$') WITH ( + [Name] nvarchar(max) '$.Name', + [Names] nvarchar(max) '$.Names' AS JSON, + [Number] int '$.Number', + [Numbers] nvarchar(max) '$.Numbers' AS JSON, + [OwnedCollectionBranch] nvarchar(max) '$.OwnedCollectionBranch' AS JSON, + [OwnedReferenceBranch] nvarchar(max) '$.OwnedReferenceBranch' AS JSON + ) AS [o] +) AS [o0] +ORDER BY [j].[Id], [o0].[Name], [o0].[Names], [o0].[Number] +"""); + } + + public override async Task Json_collection_anonymous_projection_distinct_in_projection(bool async) + { + await base.Json_collection_anonymous_projection_distinct_in_projection(async); + + AssertSql(""); + } + + public override async Task Json_collection_leaf_filter_in_projection(bool async) + { + await base.Json_collection_leaf_filter_in_projection(async); + + AssertSql( + """ +SELECT [j].[Id], [o0].[Id], [o0].[SomethingSomething], [o0].[key] +FROM [JsonEntitiesBasic] AS [j] +OUTER APPLY ( + SELECT [j].[Id], JSON_VALUE([o].[value], '$.SomethingSomething') AS [SomethingSomething], [o].[key], CAST([o].[key] AS int) AS [c] + FROM OPENJSON(CAST([j].[OwnedReferenceRoot] AS nvarchar(max)), '$.OwnedReferenceBranch.OwnedCollectionLeaf') AS [o] + WHERE JSON_VALUE([o].[value], '$.SomethingSomething') <> N'Baz' OR JSON_VALUE([o].[value], '$.SomethingSomething') IS NULL +) AS [o0] +ORDER BY [j].[Id], [o0].[c] +"""); + } + + public override async Task Json_multiple_collection_projections(bool async) + { + await base.Json_multiple_collection_projections(async); + + AssertSql( + """ +SELECT [j].[Id], [o4].[Id], [o4].[SomethingSomething], [o4].[key], [o1].[Id], [o1].[Name], [o1].[Names], [o1].[Number], [o1].[Numbers], [o1].[c], [o1].[c0], [s].[key], [s].[Id], [s].[Date], [s].[Enum], [s].[Enums], [s].[Fraction], [s].[NullableEnum], [s].[NullableEnums], [s].[c], [s].[c0], [s].[key0], [j0].[Id], [j0].[Name], [j0].[ParentId] +FROM [JsonEntitiesBasic] AS [j] +OUTER APPLY ( + SELECT [j].[Id], JSON_VALUE([o].[value], '$.SomethingSomething') AS [SomethingSomething], [o].[key], CAST([o].[key] AS int) AS [c] + FROM OPENJSON(CAST([j].[OwnedReferenceRoot] AS nvarchar(max)), '$.OwnedReferenceBranch.OwnedCollectionLeaf') AS [o] + WHERE JSON_VALUE([o].[value], '$.SomethingSomething') <> N'Baz' OR JSON_VALUE([o].[value], '$.SomethingSomething') IS NULL +) AS [o4] +OUTER APPLY ( + SELECT DISTINCT [j].[Id], [o0].[Name], [o0].[Names], [o0].[Number], [o0].[Numbers], [o0].[OwnedCollectionBranch] AS [c], [o0].[OwnedReferenceBranch] AS [c0] + FROM OPENJSON(CAST([j].[OwnedCollectionRoot] AS nvarchar(max)), '$') WITH ( + [Name] nvarchar(max) '$.Name', + [Names] nvarchar(max) '$.Names' AS JSON, + [Number] int '$.Number', + [Numbers] nvarchar(max) '$.Numbers' AS JSON, + [OwnedCollectionBranch] nvarchar(max) '$.OwnedCollectionBranch' AS JSON, + [OwnedReferenceBranch] nvarchar(max) '$.OwnedReferenceBranch' AS JSON + ) AS [o0] +) AS [o1] +OUTER APPLY ( + SELECT [o2].[key], [o5].[Id], [o5].[Date], [o5].[Enum], [o5].[Enums], [o5].[Fraction], [o5].[NullableEnum], [o5].[NullableEnums], [o5].[c], [o5].[c0], [o5].[key] AS [key0], CAST([o2].[key] AS int) AS [c1], [o5].[c1] AS [c10] + FROM OPENJSON(CAST([j].[OwnedCollectionRoot] AS nvarchar(max)), '$') AS [o2] + OUTER APPLY ( + SELECT [j].[Id], CAST(JSON_VALUE([o3].[value], '$.Date') AS datetime2) AS [Date], CAST(JSON_VALUE([o3].[value], '$.Enum') AS int) AS [Enum], JSON_QUERY([o3].[value], '$.Enums') AS [Enums], CAST(JSON_VALUE([o3].[value], '$.Fraction') AS decimal(18,2)) AS [Fraction], CAST(JSON_VALUE([o3].[value], '$.NullableEnum') AS int) AS [NullableEnum], JSON_QUERY([o3].[value], '$.NullableEnums') AS [NullableEnums], JSON_QUERY([o3].[value], '$.OwnedCollectionLeaf') AS [c], JSON_QUERY([o3].[value], '$.OwnedReferenceLeaf') AS [c0], [o3].[key], CAST([o3].[key] AS int) AS [c1] + FROM OPENJSON(CAST(JSON_QUERY([o2].[value], '$.OwnedCollectionBranch') AS nvarchar(max)), '$') AS [o3] + WHERE CAST(JSON_VALUE([o3].[value], '$.Date') AS datetime2) <> '2000-01-01T00:00:00.0000000' + ) AS [o5] +) AS [s] +LEFT JOIN [JsonEntitiesBasicForCollection] AS [j0] ON [j].[Id] = [j0].[ParentId] +ORDER BY [j].[Id], [o4].[c], [o4].[key], [o1].[Name], [o1].[Names], [o1].[Number], [o1].[Numbers], [s].[c1], [s].[key], [s].[c10], [s].[key0] +"""); + } + + public override async Task Json_branch_collection_distinct_and_other_collection(bool async) + { + await base.Json_branch_collection_distinct_and_other_collection(async); + + AssertSql( + """ +SELECT [j].[Id], [o0].[Id], [o0].[Date], [o0].[Enum], [o0].[Enums], [o0].[Fraction], [o0].[NullableEnum], [o0].[NullableEnums], [o0].[c], [o0].[c0], [j0].[Id], [j0].[Name], [j0].[ParentId] +FROM [JsonEntitiesBasic] AS [j] +OUTER APPLY ( + SELECT DISTINCT [j].[Id], [o].[Date], [o].[Enum], [o].[Enums], [o].[Fraction], [o].[NullableEnum], [o].[NullableEnums], [o].[OwnedCollectionLeaf] AS [c], [o].[OwnedReferenceLeaf] AS [c0] + FROM OPENJSON(CAST([j].[OwnedReferenceRoot] AS nvarchar(max)), '$.OwnedCollectionBranch') WITH ( + [Date] datetime2 '$.Date', + [Enum] int '$.Enum', + [Enums] nvarchar(max) '$.Enums' AS JSON, + [Fraction] decimal(18,2) '$.Fraction', + [NullableEnum] int '$.NullableEnum', + [NullableEnums] nvarchar(max) '$.NullableEnums' AS JSON, + [OwnedCollectionLeaf] nvarchar(max) '$.OwnedCollectionLeaf' AS JSON, + [OwnedReferenceLeaf] nvarchar(max) '$.OwnedReferenceLeaf' AS JSON + ) AS [o] +) AS [o0] +LEFT JOIN [JsonEntitiesBasicForCollection] AS [j0] ON [j].[Id] = [j0].[ParentId] +ORDER BY [j].[Id], [o0].[Date], [o0].[Enum], [o0].[Enums], [o0].[Fraction], [o0].[NullableEnum], [o0].[NullableEnums] +"""); + } + + public override async Task Json_leaf_collection_distinct_and_other_collection(bool async) + { + await base.Json_leaf_collection_distinct_and_other_collection(async); + + AssertSql( + """ +SELECT [j].[Id], [o0].[Id], [o0].[SomethingSomething], [j0].[Id], [j0].[Name], [j0].[ParentId] +FROM [JsonEntitiesBasic] AS [j] +OUTER APPLY ( + SELECT DISTINCT [j].[Id], [o].[SomethingSomething] + FROM OPENJSON(CAST([j].[OwnedReferenceRoot] AS nvarchar(max)), '$.OwnedReferenceBranch.OwnedCollectionLeaf') WITH ([SomethingSomething] nvarchar(max) '$.SomethingSomething') AS [o] +) AS [o0] +LEFT JOIN [JsonEntitiesBasicForCollection] AS [j0] ON [j].[Id] = [j0].[ParentId] +ORDER BY [j].[Id], [o0].[SomethingSomething] +"""); + } + + public override async Task Json_collection_SelectMany(bool async) + { + await base.Json_collection_SelectMany(async); + + AssertSql( + """ +SELECT [j].[Id], [o].[Name], [o].[Names], [o].[Number], [o].[Numbers], [o].[OwnedCollectionBranch], [o].[OwnedReferenceBranch] +FROM [JsonEntitiesBasic] AS [j] +CROSS APPLY OPENJSON(CAST([j].[OwnedCollectionRoot] AS nvarchar(max)), '$') WITH ( + [Name] nvarchar(max) '$.Name', + [Names] nvarchar(max) '$.Names' AS JSON, + [Number] int '$.Number', + [Numbers] nvarchar(max) '$.Numbers' AS JSON, + [OwnedCollectionBranch] nvarchar(max) '$.OwnedCollectionBranch' AS JSON, + [OwnedReferenceBranch] nvarchar(max) '$.OwnedReferenceBranch' AS JSON +) AS [o] +"""); + } + + public override async Task Json_nested_collection_SelectMany(bool async) + { + await base.Json_nested_collection_SelectMany(async); + + AssertSql( + """ +SELECT [j].[Id], [o].[Date], [o].[Enum], [o].[Enums], [o].[Fraction], [o].[NullableEnum], [o].[NullableEnums], [o].[OwnedCollectionLeaf], [o].[OwnedReferenceLeaf] +FROM [JsonEntitiesBasic] AS [j] +CROSS APPLY OPENJSON(CAST([j].[OwnedReferenceRoot] AS nvarchar(max)), '$.OwnedCollectionBranch') WITH ( + [Date] datetime2 '$.Date', + [Enum] int '$.Enum', + [Enums] nvarchar(max) '$.Enums' AS JSON, + [Fraction] decimal(18,2) '$.Fraction', + [NullableEnum] int '$.NullableEnum', + [NullableEnums] nvarchar(max) '$.NullableEnums' AS JSON, + [OwnedCollectionLeaf] nvarchar(max) '$.OwnedCollectionLeaf' AS JSON, + [OwnedReferenceLeaf] nvarchar(max) '$.OwnedReferenceLeaf' AS JSON +) AS [o] +"""); + } + + public override async Task Json_collection_of_primitives_SelectMany(bool async) + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "OpenJson support not yet supported for JSON native data type.", + (await Assert.ThrowsAsync( + () => base.Json_collection_of_primitives_SelectMany(async))).Message); + + AssertSql( + """ +SELECT [n].[value] +FROM [JsonEntitiesBasic] AS [j] +CROSS APPLY OPENJSON(JSON_QUERY([j].[OwnedReferenceRoot], '$.Names')) WITH ([value] nvarchar(max) '$') AS [n] +"""); + } + + public override async Task Json_collection_of_primitives_index_used_in_predicate(bool async) + { + await base.Json_collection_of_primitives_index_used_in_predicate(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +WHERE JSON_VALUE([j].[OwnedReferenceRoot], '$.Names[0]') = N'e1_r1' +"""); + } + + public override async Task Json_collection_of_primitives_index_used_in_projection(bool async) + { + await base.Json_collection_of_primitives_index_used_in_projection(async); + + AssertSql( + """ +SELECT CAST(JSON_VALUE([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.Enums[0]') AS int) +FROM [JsonEntitiesBasic] AS [j] +ORDER BY [j].[Id] +"""); + } + + public override async Task Json_collection_of_primitives_index_used_in_orderby(bool async) + { + await base.Json_collection_of_primitives_index_used_in_orderby(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +ORDER BY CAST(JSON_VALUE([j].[OwnedReferenceRoot], '$.Numbers[0]') AS int) +"""); + } + + public override async Task Json_collection_of_primitives_contains_in_predicate(bool async) + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "OpenJson support not yet supported for JSON native data type.", + (await Assert.ThrowsAsync( + () => base.Json_collection_of_primitives_contains_in_predicate(async))).Message); + + AssertSql( + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +WHERE N'e1_r1' IN ( + SELECT [n].[value] + FROM OPENJSON(JSON_QUERY([j].[OwnedReferenceRoot], '$.Names')) WITH ([value] nvarchar(max) '$') AS [n] +) +"""); + } + + [SqlServerCondition(SqlServerCondition.SupportsJsonPathExpressions)] + public override async Task Json_collection_index_with_parameter_Select_ElementAt(bool async) + { + await base.Json_collection_index_with_parameter_Select_ElementAt(async); + + AssertSql( + """ +@__prm_0='0' + +SELECT [j].[Id], ( + SELECT N'Foo' + FROM OPENJSON(CAST([j].[OwnedCollectionRoot] AS nvarchar(max)), '$[' + CAST(@__prm_0 AS nvarchar(max)) + '].OwnedCollectionBranch') AS [o] + ORDER BY CAST([o].[key] AS int) + OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY) AS [CollectionElement] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + [SqlServerCondition(SqlServerCondition.SupportsJsonPathExpressions)] + public override async Task Json_collection_index_with_expression_Select_ElementAt(bool async) + { + await base.Json_collection_index_with_expression_Select_ElementAt(async); + + AssertSql( + """ +@__prm_0='0' + +SELECT JSON_VALUE([j].[OwnedCollectionRoot], '$[' + CAST(@__prm_0 + [j].[Id] AS nvarchar(max)) + '].OwnedCollectionBranch[0].OwnedReferenceLeaf.SomethingSomething') +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Json_collection_Select_entity_collection_ElementAt(bool async) + { + await base.Json_collection_Select_entity_collection_ElementAt(async); + + AssertSql( + """ +SELECT JSON_QUERY([j].[OwnedCollectionRoot], '$[0].OwnedCollectionBranch'), [j].[Id] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Json_collection_Select_entity_ElementAt(bool async) + { + await base.Json_collection_Select_entity_ElementAt(async); + + AssertSql( + """ +SELECT JSON_QUERY([j].[OwnedCollectionRoot], '$[0].OwnedReferenceBranch'), [j].[Id] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Json_collection_Select_entity_in_anonymous_object_ElementAt(bool async) + { + await base.Json_collection_Select_entity_in_anonymous_object_ElementAt(async); + + AssertSql( + """ +SELECT [o0].[c], [o0].[Id], [o0].[c0] +FROM [JsonEntitiesBasic] AS [j] +OUTER APPLY ( + SELECT JSON_QUERY([o].[value], '$.OwnedReferenceBranch') AS [c], [j].[Id], 1 AS [c0] + FROM OPENJSON(CAST([j].[OwnedCollectionRoot] AS nvarchar(max)), '$') AS [o] + ORDER BY CAST([o].[key] AS int) + OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY +) AS [o0] +ORDER BY [j].[Id] +"""); + } + + public override async Task Json_collection_Select_entity_with_initializer_ElementAt(bool async) + { + await base.Json_collection_Select_entity_with_initializer_ElementAt(async); + + AssertSql( + """ +SELECT [o0].[Id], [o0].[c] +FROM [JsonEntitiesBasic] AS [j] +OUTER APPLY ( + SELECT [j].[Id], 1 AS [c] + FROM OPENJSON(CAST([j].[OwnedCollectionRoot] AS nvarchar(max)), '$') AS [o] + ORDER BY CAST([o].[key] AS int) + OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY +) AS [o0] +"""); + } + + public override async Task Json_projection_deduplication_with_collection_indexer_in_original(bool async) + { + await base.Json_projection_deduplication_with_collection_indexer_in_original(async); + + AssertSql( + """ +SELECT [j].[Id], JSON_QUERY([j].[OwnedCollectionRoot], '$[0].OwnedReferenceBranch'), JSON_QUERY([j].[OwnedCollectionRoot], '$[0]'), JSON_QUERY([j].[OwnedCollectionRoot], '$[0].OwnedReferenceBranch.OwnedCollectionLeaf') +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + [SqlServerCondition(SqlServerCondition.SupportsJsonPathExpressions)] + public override async Task Json_projection_deduplication_with_collection_indexer_in_target(bool async) + { + await base.Json_projection_deduplication_with_collection_indexer_in_target(async); + + AssertSql( + """ +@__prm_0='1' + +SELECT [j].[Id], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch[1]'), [j].[OwnedReferenceRoot], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedCollectionLeaf[' + CAST(@__prm_0 AS nvarchar(max)) + ']'), @__prm_0 +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + [SqlServerCondition(SqlServerCondition.SupportsJsonPathExpressions)] + public override async Task Json_projection_deduplication_with_collection_in_original_and_collection_indexer_in_target(bool async) + { + await base.Json_projection_deduplication_with_collection_in_original_and_collection_indexer_in_target(async); + + AssertSql( + """ +@__prm_0='1' + +SELECT JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch[0].OwnedCollectionLeaf[' + CAST(@__prm_0 AS nvarchar(max)) + ']'), [j].[Id], @__prm_0, JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch[' + CAST(@__prm_0 AS nvarchar(max)) + ']'), JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch'), JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch[0]') +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Json_collection_index_in_projection_using_constant_when_owner_is_present(bool async) + { + await base.Json_collection_index_in_projection_using_constant_when_owner_is_present(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot], JSON_QUERY([j].[OwnedCollectionRoot], '$[1]') +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Json_collection_index_in_projection_using_constant_when_owner_is_not_present(bool async) + { + await base.Json_collection_index_in_projection_using_constant_when_owner_is_not_present(async); + + AssertSql( + """ +SELECT [j].[Id], JSON_QUERY([j].[OwnedCollectionRoot], '$[1]') +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + [SqlServerCondition(SqlServerCondition.SupportsJsonPathExpressions)] + public override async Task Json_collection_index_in_projection_using_parameter_when_owner_is_present(bool async) + { + await base.Json_collection_index_in_projection_using_parameter_when_owner_is_present(async); + + AssertSql( + """ +@__prm_0='1' + +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot], JSON_QUERY([j].[OwnedCollectionRoot], '$[' + CAST(@__prm_0 AS nvarchar(max)) + ']'), @__prm_0 +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + [SqlServerCondition(SqlServerCondition.SupportsJsonPathExpressions)] + public override async Task Json_collection_index_in_projection_using_parameter_when_owner_is_not_present(bool async) + { + await base.Json_collection_index_in_projection_using_parameter_when_owner_is_not_present(async); + + AssertSql( + """ +@__prm_0='1' + +SELECT [j].[Id], JSON_QUERY([j].[OwnedCollectionRoot], '$[' + CAST(@__prm_0 AS nvarchar(max)) + ']'), @__prm_0 +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Json_collection_after_collection_index_in_projection_using_constant_when_owner_is_present(bool async) + { + await base.Json_collection_after_collection_index_in_projection_using_constant_when_owner_is_present(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot], JSON_QUERY([j].[OwnedCollectionRoot], '$[1].OwnedCollectionBranch') +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Json_collection_after_collection_index_in_projection_using_constant_when_owner_is_not_present(bool async) + { + await base.Json_collection_after_collection_index_in_projection_using_constant_when_owner_is_not_present(async); + + AssertSql( + """ +SELECT [j].[Id], JSON_QUERY([j].[OwnedCollectionRoot], '$[1].OwnedCollectionBranch') +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + [SqlServerCondition(SqlServerCondition.SupportsJsonPathExpressions)] + public override async Task Json_collection_after_collection_index_in_projection_using_parameter_when_owner_is_present(bool async) + { + await base.Json_collection_after_collection_index_in_projection_using_parameter_when_owner_is_present(async); + + AssertSql( + """ +@__prm_0='1' + +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot], JSON_QUERY([j].[OwnedCollectionRoot], '$[' + CAST(@__prm_0 AS nvarchar(max)) + '].OwnedCollectionBranch'), @__prm_0 +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + [SqlServerCondition(SqlServerCondition.SupportsJsonPathExpressions)] + public override async Task Json_collection_after_collection_index_in_projection_using_parameter_when_owner_is_not_present(bool async) + { + await base.Json_collection_after_collection_index_in_projection_using_parameter_when_owner_is_not_present(async); + + AssertSql( + """ +@__prm_0='1' + +SELECT [j].[Id], JSON_QUERY([j].[OwnedCollectionRoot], '$[' + CAST(@__prm_0 AS nvarchar(max)) + '].OwnedCollectionBranch'), @__prm_0 +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + [SqlServerCondition(SqlServerCondition.SupportsJsonPathExpressions)] + public override async Task Json_collection_index_in_projection_when_owner_is_present_misc1(bool async) + { + await base.Json_collection_index_in_projection_when_owner_is_present_misc1(async); + + AssertSql( + """ +@__prm_0='1' + +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot], JSON_QUERY([j].[OwnedCollectionRoot], '$[1].OwnedCollectionBranch[' + CAST(@__prm_0 AS nvarchar(max)) + ']'), @__prm_0 +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + [SqlServerCondition(SqlServerCondition.SupportsJsonPathExpressions)] + public override async Task Json_collection_index_in_projection_when_owner_is_not_present_misc1(bool async) + { + await base.Json_collection_index_in_projection_when_owner_is_not_present_misc1(async); + + AssertSql( + """ +@__prm_0='1' + +SELECT [j].[Id], JSON_QUERY([j].[OwnedCollectionRoot], '$[1].OwnedCollectionBranch[' + CAST(@__prm_0 AS nvarchar(max)) + ']'), @__prm_0 +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Json_collection_index_in_projection_when_owner_is_present_misc2(bool async) + { + await base.Json_collection_index_in_projection_when_owner_is_present_misc2(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedCollectionLeaf[1]') +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Json_collection_index_in_projection_when_owner_is_not_present_misc2(bool async) + { + await base.Json_collection_index_in_projection_when_owner_is_not_present_misc2(async); + + AssertSql( + """ +SELECT [j].[Id], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedCollectionLeaf[1]') +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + [SqlServerCondition(SqlServerCondition.SupportsJsonPathExpressions)] + public override async Task Json_collection_index_in_projection_when_owner_is_present_multiple(bool async) + { + await base.Json_collection_index_in_projection_when_owner_is_present_multiple(async); + + AssertSql( + """ +@__prm_0='1' + +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot], JSON_QUERY([j].[OwnedCollectionRoot], '$[' + CAST(@__prm_0 AS nvarchar(max)) + '].OwnedCollectionBranch[1]'), @__prm_0, JSON_QUERY([j].[OwnedCollectionRoot], '$[1].OwnedCollectionBranch[1].OwnedReferenceLeaf'), JSON_QUERY([j].[OwnedCollectionRoot], '$[1].OwnedReferenceBranch'), JSON_QUERY([j].[OwnedCollectionRoot], '$[' + CAST(@__prm_0 AS nvarchar(max)) + '].OwnedReferenceBranch'), JSON_QUERY([j].[OwnedCollectionRoot], '$[' + CAST(@__prm_0 AS nvarchar(max)) + '].OwnedCollectionBranch[' + CAST([j].[Id] AS nvarchar(max)) + ']'), JSON_QUERY([j].[OwnedCollectionRoot], '$[' + CAST([j].[Id] AS nvarchar(max)) + '].OwnedCollectionBranch[1].OwnedReferenceLeaf'), JSON_QUERY([j].[OwnedCollectionRoot], '$[1].OwnedReferenceBranch'), JSON_QUERY([j].[OwnedCollectionRoot], '$[' + CAST([j].[Id] AS nvarchar(max)) + '].OwnedReferenceBranch'), JSON_QUERY([j].[OwnedCollectionRoot], '$[' + CAST([j].[Id] AS nvarchar(max)) + '].OwnedCollectionBranch[' + CAST([j].[Id] AS nvarchar(max)) + ']') +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + [SqlServerCondition(SqlServerCondition.SupportsJsonPathExpressions)] + public override async Task Json_collection_index_in_projection_when_owner_is_not_present_multiple(bool async) + { + await base.Json_collection_index_in_projection_when_owner_is_not_present_multiple(async); + + AssertSql( + """ +@__prm_0='1' + +SELECT [j].[Id], JSON_QUERY([j].[OwnedCollectionRoot], '$[' + CAST(@__prm_0 AS nvarchar(max)) + '].OwnedCollectionBranch[1]'), @__prm_0, JSON_QUERY([j].[OwnedCollectionRoot], '$[1].OwnedCollectionBranch[1].OwnedReferenceLeaf'), JSON_QUERY([j].[OwnedCollectionRoot], '$[1].OwnedReferenceBranch'), JSON_QUERY([j].[OwnedCollectionRoot], '$[' + CAST(@__prm_0 AS nvarchar(max)) + '].OwnedReferenceBranch'), JSON_QUERY([j].[OwnedCollectionRoot], '$[' + CAST(@__prm_0 AS nvarchar(max)) + '].OwnedCollectionBranch[' + CAST([j].[Id] AS nvarchar(max)) + ']'), JSON_QUERY([j].[OwnedCollectionRoot], '$[' + CAST([j].[Id] AS nvarchar(max)) + '].OwnedCollectionBranch[1].OwnedReferenceLeaf'), JSON_QUERY([j].[OwnedCollectionRoot], '$[1].OwnedReferenceBranch'), JSON_QUERY([j].[OwnedCollectionRoot], '$[' + CAST([j].[Id] AS nvarchar(max)) + '].OwnedReferenceBranch'), JSON_QUERY([j].[OwnedCollectionRoot], '$[' + CAST([j].[Id] AS nvarchar(max)) + '].OwnedCollectionBranch[' + CAST([j].[Id] AS nvarchar(max)) + ']') +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Json_scalar_required_null_semantics(bool async) + { + await base.Json_scalar_required_null_semantics(async); + + AssertSql( + """ +SELECT [j].[Name] +FROM [JsonEntitiesBasic] AS [j] +WHERE CAST(JSON_VALUE([j].[OwnedReferenceRoot], '$.Number') AS int) <> CAST(LEN(JSON_VALUE([j].[OwnedReferenceRoot], '$.Name')) AS int) OR JSON_VALUE([j].[OwnedReferenceRoot], '$.Name') IS NULL +"""); + } + + public override async Task Json_scalar_optional_null_semantics(bool async) + { + await base.Json_scalar_optional_null_semantics(async); + + AssertSql( + """ +SELECT [j].[Name] +FROM [JsonEntitiesBasic] AS [j] +WHERE (JSON_VALUE([j].[OwnedReferenceRoot], '$.Name') <> JSON_VALUE([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedReferenceLeaf.SomethingSomething') OR JSON_VALUE([j].[OwnedReferenceRoot], '$.Name') IS NULL OR JSON_VALUE([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedReferenceLeaf.SomethingSomething') IS NULL) AND (JSON_VALUE([j].[OwnedReferenceRoot], '$.Name') IS NOT NULL OR JSON_VALUE([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedReferenceLeaf.SomethingSomething') IS NOT NULL) +"""); + } + + public override async Task Group_by_on_json_scalar(bool async) + { + await base.Group_by_on_json_scalar(async); + + AssertSql( + """ +SELECT [j0].[Key], COUNT(*) AS [Count] +FROM ( + SELECT JSON_VALUE([j].[OwnedReferenceRoot], '$.Name') AS [Key] + FROM [JsonEntitiesBasic] AS [j] +) AS [j0] +GROUP BY [j0].[Key] +"""); + } + + public override async Task Group_by_on_json_scalar_using_collection_indexer(bool async) + { + await base.Group_by_on_json_scalar_using_collection_indexer(async); + + AssertSql( + """ +SELECT [j0].[Key], COUNT(*) AS [Count] +FROM ( + SELECT JSON_VALUE([j].[OwnedCollectionRoot], '$[0].Name') AS [Key] + FROM [JsonEntitiesBasic] AS [j] +) AS [j0] +GROUP BY [j0].[Key] +"""); + } + + public override async Task Group_by_First_on_json_scalar(bool async) + { + await base.Group_by_First_on_json_scalar(async); + + AssertSql( + """ +SELECT [j5].[Id], [j5].[EntityBasicId], [j5].[Name], [j5].[c], [j5].[c0] +FROM ( + SELECT [j0].[Key] + FROM ( + SELECT JSON_VALUE([j].[OwnedReferenceRoot], '$.Name') AS [Key] + FROM [JsonEntitiesBasic] AS [j] + ) AS [j0] + GROUP BY [j0].[Key] +) AS [j3] +LEFT JOIN ( + SELECT [j4].[Id], [j4].[EntityBasicId], [j4].[Name], [j4].[c] AS [c], [j4].[c0] AS [c0], [j4].[Key] + FROM ( + SELECT [j1].[Id], [j1].[EntityBasicId], [j1].[Name], [j1].[c] AS [c], [j1].[c0] AS [c0], [j1].[Key], ROW_NUMBER() OVER(PARTITION BY [j1].[Key] ORDER BY [j1].[Id]) AS [row] + FROM ( + SELECT [j2].[Id], [j2].[EntityBasicId], [j2].[Name], [j2].[OwnedCollectionRoot] AS [c], [j2].[OwnedReferenceRoot] AS [c0], JSON_VALUE([j2].[OwnedReferenceRoot], '$.Name') AS [Key] + FROM [JsonEntitiesBasic] AS [j2] + ) AS [j1] + ) AS [j4] + WHERE [j4].[row] <= 1 +) AS [j5] ON [j3].[Key] = [j5].[Key] +"""); + } + + public override async Task Group_by_FirstOrDefault_on_json_scalar(bool async) + { + await base.Group_by_FirstOrDefault_on_json_scalar(async); + + AssertSql( + """ +SELECT [j5].[Id], [j5].[EntityBasicId], [j5].[Name], [j5].[c], [j5].[c0] +FROM ( + SELECT [j0].[Key] + FROM ( + SELECT JSON_VALUE([j].[OwnedReferenceRoot], '$.Name') AS [Key] + FROM [JsonEntitiesBasic] AS [j] + ) AS [j0] + GROUP BY [j0].[Key] +) AS [j3] +LEFT JOIN ( + SELECT [j4].[Id], [j4].[EntityBasicId], [j4].[Name], [j4].[c] AS [c], [j4].[c0] AS [c0], [j4].[Key] + FROM ( + SELECT [j1].[Id], [j1].[EntityBasicId], [j1].[Name], [j1].[c] AS [c], [j1].[c0] AS [c0], [j1].[Key], ROW_NUMBER() OVER(PARTITION BY [j1].[Key] ORDER BY [j1].[Id]) AS [row] + FROM ( + SELECT [j2].[Id], [j2].[EntityBasicId], [j2].[Name], [j2].[OwnedCollectionRoot] AS [c], [j2].[OwnedReferenceRoot] AS [c0], JSON_VALUE([j2].[OwnedReferenceRoot], '$.Name') AS [Key] + FROM [JsonEntitiesBasic] AS [j2] + ) AS [j1] + ) AS [j4] + WHERE [j4].[row] <= 1 +) AS [j5] ON [j3].[Key] = [j5].[Key] +"""); + } + + public override async Task Group_by_Skip_Take_on_json_scalar(bool async) + { + // TODO:SQLJSON Returns empty (invalid) JSON (See BadJson.cs) + if (async) + { + Assert.Equal( + "Unable to cast object of type 'System.DBNull' to type 'System.String'.", + (await Assert.ThrowsAsync(() => base.Group_by_Skip_Take_on_json_scalar(true))).Message); + } + else + { + await base.Group_by_Skip_Take_on_json_scalar(false); + } + + AssertSql( + """ +SELECT [j3].[Key], [j5].[Id], [j5].[EntityBasicId], [j5].[Name], [j5].[c], [j5].[c0] +FROM ( + SELECT [j0].[Key] + FROM ( + SELECT JSON_VALUE([j].[OwnedReferenceRoot], '$.Name') AS [Key] + FROM [JsonEntitiesBasic] AS [j] + ) AS [j0] + GROUP BY [j0].[Key] +) AS [j3] +LEFT JOIN ( + SELECT [j4].[Id], [j4].[EntityBasicId], [j4].[Name], [j4].[c], [j4].[c0], [j4].[Key] + FROM ( + SELECT [j1].[Id], [j1].[EntityBasicId], [j1].[Name], [j1].[c] AS [c], [j1].[c0] AS [c0], [j1].[Key], ROW_NUMBER() OVER(PARTITION BY [j1].[Key] ORDER BY [j1].[Id]) AS [row] + FROM ( + SELECT [j2].[Id], [j2].[EntityBasicId], [j2].[Name], [j2].[OwnedCollectionRoot] AS [c], [j2].[OwnedReferenceRoot] AS [c0], JSON_VALUE([j2].[OwnedReferenceRoot], '$.Name') AS [Key] + FROM [JsonEntitiesBasic] AS [j2] + ) AS [j1] + ) AS [j4] + WHERE 1 < [j4].[row] AND [j4].[row] <= 6 +) AS [j5] ON [j3].[Key] = [j5].[Key] +ORDER BY [j3].[Key], [j5].[Key], [j5].[Id] +"""); + } + + public override async Task Group_by_json_scalar_Orderby_json_scalar_FirstOrDefault(bool async) + { + await base.Group_by_json_scalar_Orderby_json_scalar_FirstOrDefault(async); + + AssertSql( + @""); + } + + public override async Task Group_by_json_scalar_Skip_First_project_json_scalar(bool async) + { + await base.Group_by_json_scalar_Skip_First_project_json_scalar(async); + + AssertSql( + """ +SELECT ( + SELECT TOP(1) CAST(JSON_VALUE([j1].[c0], '$.OwnedReferenceBranch.Enum') AS int) + FROM ( + SELECT [j2].[OwnedReferenceRoot] AS [c0], JSON_VALUE([j2].[OwnedReferenceRoot], '$.Name') AS [Key] + FROM [JsonEntitiesBasic] AS [j2] + ) AS [j1] + WHERE [j0].[Key] = [j1].[Key] OR ([j0].[Key] IS NULL AND [j1].[Key] IS NULL)) +FROM ( + SELECT JSON_VALUE([j].[OwnedReferenceRoot], '$.Name') AS [Key] + FROM [JsonEntitiesBasic] AS [j] +) AS [j0] +GROUP BY [j0].[Key] +"""); + } + + public override async Task Json_with_include_on_json_entity(bool async) + { + await base.Json_with_include_on_json_entity(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Json_with_include_on_entity_reference(bool async) + { + await base.Json_with_include_on_entity_reference(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot], [j0].[Id], [j0].[Name], [j0].[ParentId] +FROM [JsonEntitiesBasic] AS [j] +LEFT JOIN [JsonEntitiesBasicForReference] AS [j0] ON [j].[Id] = [j0].[ParentId] +"""); + } + + public override async Task Json_with_include_on_entity_collection(bool async) + { + await base.Json_with_include_on_entity_collection(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot], [j0].[Id], [j0].[Name], [j0].[ParentId] +FROM [JsonEntitiesBasic] AS [j] +LEFT JOIN [JsonEntitiesBasicForCollection] AS [j0] ON [j].[Id] = [j0].[ParentId] +ORDER BY [j].[Id] +"""); + } + + public override async Task Entity_including_collection_with_json(bool async) + { + await base.Entity_including_collection_with_json(async); + + AssertSql( + """ +SELECT [e].[Id], [e].[Name], [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [EntitiesBasic] AS [e] +LEFT JOIN [JsonEntitiesBasic] AS [j] ON [e].[Id] = [j].[EntityBasicId] +ORDER BY [e].[Id] +"""); + } + + public override async Task Json_with_include_on_entity_collection_and_reference(bool async) + { + await base.Json_with_include_on_entity_collection_and_reference(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot], [j0].[Id], [j0].[Name], [j0].[ParentId], [j1].[Id], [j1].[Name], [j1].[ParentId] +FROM [JsonEntitiesBasic] AS [j] +LEFT JOIN [JsonEntitiesBasicForReference] AS [j0] ON [j].[Id] = [j0].[ParentId] +LEFT JOIN [JsonEntitiesBasicForCollection] AS [j1] ON [j].[Id] = [j1].[ParentId] +ORDER BY [j].[Id], [j0].[Id] +"""); + } + + public override async Task Json_with_projection_of_json_reference_leaf_and_entity_collection(bool async) + { + await base.Json_with_projection_of_json_reference_leaf_and_entity_collection(async); + + AssertSql( + """ +SELECT JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedReferenceLeaf'), [j].[Id], [j0].[Id], [j0].[Name], [j0].[ParentId] +FROM [JsonEntitiesBasic] AS [j] +LEFT JOIN [JsonEntitiesBasicForCollection] AS [j0] ON [j].[Id] = [j0].[ParentId] +ORDER BY [j].[Id] +"""); + } + + public override async Task Json_with_projection_of_json_reference_and_entity_collection(bool async) + { + await base.Json_with_projection_of_json_reference_and_entity_collection(async); + + AssertSql( + """ +SELECT [j].[OwnedReferenceRoot], [j].[Id], [j0].[Id], [j0].[Name], [j0].[ParentId] +FROM [JsonEntitiesBasic] AS [j] +LEFT JOIN [JsonEntitiesBasicForCollection] AS [j0] ON [j].[Id] = [j0].[ParentId] +ORDER BY [j].[Id] +"""); + } + + public override async Task Json_with_projection_of_multiple_json_references_and_entity_collection(bool async) + { + await base.Json_with_projection_of_multiple_json_references_and_entity_collection(async); + + AssertSql( + """ +SELECT [j].[OwnedReferenceRoot], [j].[Id], JSON_QUERY([j].[OwnedCollectionRoot], '$[0].OwnedReferenceBranch'), [j0].[Id], [j0].[Name], [j0].[ParentId], JSON_QUERY([j].[OwnedCollectionRoot], '$[1].OwnedReferenceBranch.OwnedReferenceLeaf'), JSON_QUERY([j].[OwnedCollectionRoot], '$[0].OwnedCollectionBranch[0].OwnedReferenceLeaf') +FROM [JsonEntitiesBasic] AS [j] +LEFT JOIN [JsonEntitiesBasicForCollection] AS [j0] ON [j].[Id] = [j0].[ParentId] +ORDER BY [j].[Id] +"""); + } + + public override async Task Json_with_projection_of_json_collection_leaf_and_entity_collection(bool async) + { + await base.Json_with_projection_of_json_collection_leaf_and_entity_collection(async); + + AssertSql( + """ +SELECT JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedCollectionLeaf'), [j].[Id], [j0].[Id], [j0].[Name], [j0].[ParentId] +FROM [JsonEntitiesBasic] AS [j] +LEFT JOIN [JsonEntitiesBasicForCollection] AS [j0] ON [j].[Id] = [j0].[ParentId] +ORDER BY [j].[Id] +"""); + } + + public override async Task Json_with_projection_of_json_collection_and_entity_collection(bool async) + { + await base.Json_with_projection_of_json_collection_and_entity_collection(async); + + AssertSql( + """ +SELECT [j].[OwnedCollectionRoot], [j].[Id], [j0].[Id], [j0].[Name], [j0].[ParentId] +FROM [JsonEntitiesBasic] AS [j] +LEFT JOIN [JsonEntitiesBasicForCollection] AS [j0] ON [j].[Id] = [j0].[ParentId] +ORDER BY [j].[Id] +"""); + } + + public override async Task Json_with_projection_of_json_collection_element_and_entity_collection(bool async) + { + await base.Json_with_projection_of_json_collection_element_and_entity_collection(async); + + AssertSql( + """ +SELECT JSON_QUERY([j].[OwnedCollectionRoot], '$[0]'), [j].[Id], [j0].[Id], [j0].[Name], [j0].[ParentId], [j1].[Id], [j1].[Name], [j1].[ParentId] +FROM [JsonEntitiesBasic] AS [j] +LEFT JOIN [JsonEntitiesBasicForReference] AS [j0] ON [j].[Id] = [j0].[ParentId] +LEFT JOIN [JsonEntitiesBasicForCollection] AS [j1] ON [j].[Id] = [j1].[ParentId] +ORDER BY [j].[Id], [j0].[Id] +"""); + } + + public override async Task Json_with_projection_of_mix_of_json_collections_json_references_and_entity_collection(bool async) + { + await base.Json_with_projection_of_mix_of_json_collections_json_references_and_entity_collection(async); + + AssertSql( + """ +SELECT JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedCollectionLeaf'), [j].[Id], [j0].[Id], [j0].[Name], [j0].[ParentId], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedReferenceLeaf'), [j1].[Id], [j1].[Name], [j1].[ParentId], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedCollectionLeaf[0]'), JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch'), [j].[OwnedCollectionRoot], JSON_QUERY([j].[OwnedCollectionRoot], '$[0].OwnedReferenceBranch'), JSON_QUERY([j].[OwnedCollectionRoot], '$[0].OwnedCollectionBranch') +FROM [JsonEntitiesBasic] AS [j] +LEFT JOIN [JsonEntitiesBasicForReference] AS [j0] ON [j].[Id] = [j0].[ParentId] +LEFT JOIN [JsonEntitiesBasicForCollection] AS [j1] ON [j].[Id] = [j1].[ParentId] +ORDER BY [j].[Id], [j0].[Id] +"""); + +// AssertSql( +//""" +//SELECT JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedCollectionLeaf'), [j].[Id], [j0].[Id], [j0].[Name], [j0].[ParentId], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedReferenceLeaf'), [j1].[Id], [j1].[Name], [j1].[ParentId], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch'), [j].[OwnedCollectionRoot] +//FROM [JsonEntitiesBasic] AS [j] +//LEFT JOIN [JsonEntitiesBasicForReference] AS [j0] ON [j].[Id] = [j0].[ParentId] +//LEFT JOIN [JsonEntitiesBasicForCollection] AS [j1] ON [j].[Id] = [j1].[ParentId] +//ORDER BY [j].[Id], [j0].[Id] +//"""); + } + + public override async Task Json_all_types_entity_projection(bool async) + { + await base.Json_all_types_entity_projection(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +"""); + } + + public override async Task Json_all_types_projection_from_owned_entity_reference(bool async) + { + await base.Json_all_types_projection_from_owned_entity_reference(async); + + AssertSql( + """ +SELECT [j].[Reference], [j].[Id] +FROM [JsonEntitiesAllTypes] AS [j] +"""); + } + + public override async Task Json_all_types_projection_individual_properties(bool async) + { + await base.Json_all_types_projection_individual_properties(async); + + AssertSql( + """ +SELECT JSON_VALUE([j].[Reference], '$.TestDefaultString') AS [TestDefaultString], JSON_VALUE([j].[Reference], '$.TestMaxLengthString') AS [TestMaxLengthString], CAST(JSON_VALUE([j].[Reference], '$.TestBoolean') AS bit) AS [TestBoolean], CAST(JSON_VALUE([j].[Reference], '$.TestByte') AS tinyint) AS [TestByte], JSON_VALUE([j].[Reference], '$.TestCharacter') AS [TestCharacter], CAST(JSON_VALUE([j].[Reference], '$.TestDateTime') AS datetime2) AS [TestDateTime], CAST(JSON_VALUE([j].[Reference], '$.TestDateTimeOffset') AS datetimeoffset) AS [TestDateTimeOffset], CAST(JSON_VALUE([j].[Reference], '$.TestDecimal') AS decimal(18,3)) AS [TestDecimal], CAST(JSON_VALUE([j].[Reference], '$.TestDouble') AS float) AS [TestDouble], CAST(JSON_VALUE([j].[Reference], '$.TestGuid') AS uniqueidentifier) AS [TestGuid], CAST(JSON_VALUE([j].[Reference], '$.TestInt16') AS smallint) AS [TestInt16], CAST(JSON_VALUE([j].[Reference], '$.TestInt32') AS int) AS [TestInt32], CAST(JSON_VALUE([j].[Reference], '$.TestInt64') AS bigint) AS [TestInt64], CAST(JSON_VALUE([j].[Reference], '$.TestSignedByte') AS smallint) AS [TestSignedByte], CAST(JSON_VALUE([j].[Reference], '$.TestSingle') AS real) AS [TestSingle], CAST(JSON_VALUE([j].[Reference], '$.TestTimeSpan') AS time) AS [TestTimeSpan], CAST(JSON_VALUE([j].[Reference], '$.TestDateOnly') AS date) AS [TestDateOnly], CAST(JSON_VALUE([j].[Reference], '$.TestTimeOnly') AS time) AS [TestTimeOnly], CAST(JSON_VALUE([j].[Reference], '$.TestUnsignedInt16') AS int) AS [TestUnsignedInt16], CAST(JSON_VALUE([j].[Reference], '$.TestUnsignedInt32') AS bigint) AS [TestUnsignedInt32], CAST(JSON_VALUE([j].[Reference], '$.TestUnsignedInt64') AS decimal(20,0)) AS [TestUnsignedInt64], CAST(JSON_VALUE([j].[Reference], '$.TestEnum') AS int) AS [TestEnum], CAST(JSON_VALUE([j].[Reference], '$.TestEnumWithIntConverter') AS int) AS [TestEnumWithIntConverter], CAST(JSON_VALUE([j].[Reference], '$.TestNullableEnum') AS int) AS [TestNullableEnum], CAST(JSON_VALUE([j].[Reference], '$.TestNullableEnumWithIntConverter') AS int) AS [TestNullableEnumWithIntConverter], JSON_VALUE([j].[Reference], '$.TestNullableEnumWithConverterThatHandlesNulls') AS [TestNullableEnumWithConverterThatHandlesNulls] +FROM [JsonEntitiesAllTypes] AS [j] +"""); + } + + public override async Task Json_boolean_predicate(bool async) + { + await base.Json_boolean_predicate(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE CAST(JSON_VALUE([j].[Reference], '$.TestBoolean') AS bit) = CAST(1 AS bit) +"""); + } + + public override async Task Json_boolean_predicate_negated(bool async) + { + await base.Json_boolean_predicate_negated(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE CAST(JSON_VALUE([j].[Reference], '$.TestBoolean') AS bit) = CAST(0 AS bit) +"""); + } + + public override async Task Json_boolean_projection(bool async) + { + await base.Json_boolean_projection(async); + + AssertSql( + """ +SELECT CAST(JSON_VALUE([j].[Reference], '$.TestBoolean') AS bit) +FROM [JsonEntitiesAllTypes] AS [j] +"""); + } + + public override async Task Json_boolean_projection_negated(bool async) + { + await base.Json_boolean_projection_negated(async); + + AssertSql( + """ +SELECT ~CAST(JSON_VALUE([j].[Reference], '$.TestBoolean') AS bit) +FROM [JsonEntitiesAllTypes] AS [j] +"""); + } + + public override async Task Json_predicate_on_default_string(bool async) + { + await base.Json_predicate_on_default_string(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE JSON_VALUE([j].[Reference], '$.TestDefaultString') <> N'MyDefaultStringInReference1' OR JSON_VALUE([j].[Reference], '$.TestDefaultString') IS NULL +"""); + } + + public override async Task Json_predicate_on_max_length_string(bool async) + { + await base.Json_predicate_on_max_length_string(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE JSON_VALUE([j].[Reference], '$.TestMaxLengthString') <> N'Foo' OR JSON_VALUE([j].[Reference], '$.TestMaxLengthString') IS NULL +"""); + } + + public override async Task Json_predicate_on_string_condition(bool async) + { + await base.Json_predicate_on_string_condition(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE CASE + WHEN CAST(JSON_VALUE([j].[Reference], '$.TestBoolean') AS bit) = CAST(0 AS bit) THEN JSON_VALUE([j].[Reference], '$.TestMaxLengthString') + ELSE JSON_VALUE([j].[Reference], '$.TestDefaultString') +END = N'MyDefaultStringInReference1' +"""); + } + + public override async Task Json_predicate_on_byte(bool async) + { + await base.Json_predicate_on_byte(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE CAST(JSON_VALUE([j].[Reference], '$.TestByte') AS tinyint) <> CAST(3 AS tinyint) OR CAST(JSON_VALUE([j].[Reference], '$.TestByte') AS tinyint) IS NULL +"""); + } + + public override async Task Json_predicate_on_byte_array(bool async) + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "OpenJson support not yet supported for JSON native data type.", + (await Assert.ThrowsAsync( + () => base.Json_predicate_on_byte_array(async))).Message); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +OUTER APPLY OPENJSON([j].[Reference]) WITH ([TestByteArray] varbinary(max) '$.TestByteArray') AS [t] +WHERE [t].[TestByteArray] <> 0x010203 OR [t].[TestByteArray] IS NULL +"""); + } + + public override async Task Json_predicate_on_character(bool async) + { + await base.Json_predicate_on_character(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE JSON_VALUE([j].[Reference], '$.TestCharacter') <> N'z' OR JSON_VALUE([j].[Reference], '$.TestCharacter') IS NULL +"""); + } + + public override async Task Json_predicate_on_datetime(bool async) + { + await base.Json_predicate_on_datetime(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE CAST(JSON_VALUE([j].[Reference], '$.TestDateTime') AS datetime2) <> '2000-01-03T00:00:00.0000000' OR CAST(JSON_VALUE([j].[Reference], '$.TestDateTime') AS datetime2) IS NULL +"""); + } + + public override async Task Json_predicate_on_datetimeoffset(bool async) + { + await base.Json_predicate_on_datetimeoffset(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE CAST(JSON_VALUE([j].[Reference], '$.TestDateTimeOffset') AS datetimeoffset) <> '2000-01-04T00:00:00.0000000+03:02' OR CAST(JSON_VALUE([j].[Reference], '$.TestDateTimeOffset') AS datetimeoffset) IS NULL +"""); + } + + public override async Task Json_predicate_on_decimal(bool async) + { + await base.Json_predicate_on_decimal(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE CAST(JSON_VALUE([j].[Reference], '$.TestDecimal') AS decimal(18,3)) <> 1.35 OR CAST(JSON_VALUE([j].[Reference], '$.TestDecimal') AS decimal(18,3)) IS NULL +"""); + } + + public override async Task Json_predicate_on_double(bool async) + { + await base.Json_predicate_on_double(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE CAST(JSON_VALUE([j].[Reference], '$.TestDouble') AS float) <> 33.25E0 OR CAST(JSON_VALUE([j].[Reference], '$.TestDouble') AS float) IS NULL +"""); + } + + public override async Task Json_predicate_on_enum(bool async) + { + await base.Json_predicate_on_enum(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE CAST(JSON_VALUE([j].[Reference], '$.TestEnum') AS int) <> 2 OR CAST(JSON_VALUE([j].[Reference], '$.TestEnum') AS int) IS NULL +"""); + } + + public override async Task Json_predicate_on_enumwithintconverter(bool async) + { + await base.Json_predicate_on_enumwithintconverter(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE CAST(JSON_VALUE([j].[Reference], '$.TestEnumWithIntConverter') AS int) <> -3 OR CAST(JSON_VALUE([j].[Reference], '$.TestEnumWithIntConverter') AS int) IS NULL +"""); + } + + public override async Task Json_predicate_on_guid(bool async) + { + await base.Json_predicate_on_guid(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE CAST(JSON_VALUE([j].[Reference], '$.TestGuid') AS uniqueidentifier) <> '00000000-0000-0000-0000-000000000000' OR CAST(JSON_VALUE([j].[Reference], '$.TestGuid') AS uniqueidentifier) IS NULL +"""); + } + + public override async Task Json_predicate_on_int16(bool async) + { + await base.Json_predicate_on_int16(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE CAST(JSON_VALUE([j].[Reference], '$.TestInt16') AS smallint) <> CAST(3 AS smallint) OR CAST(JSON_VALUE([j].[Reference], '$.TestInt16') AS smallint) IS NULL +"""); + } + + public override async Task Json_predicate_on_int32(bool async) + { + await base.Json_predicate_on_int32(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE CAST(JSON_VALUE([j].[Reference], '$.TestInt32') AS int) <> 33 OR CAST(JSON_VALUE([j].[Reference], '$.TestInt32') AS int) IS NULL +"""); + } + + public override async Task Json_predicate_on_int64(bool async) + { + await base.Json_predicate_on_int64(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE CAST(JSON_VALUE([j].[Reference], '$.TestInt64') AS bigint) <> CAST(333 AS bigint) OR CAST(JSON_VALUE([j].[Reference], '$.TestInt64') AS bigint) IS NULL +"""); + } + + public override async Task Json_predicate_on_nullableenum1(bool async) + { + await base.Json_predicate_on_nullableenum1(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE CAST(JSON_VALUE([j].[Reference], '$.TestNullableEnum') AS int) <> -1 OR CAST(JSON_VALUE([j].[Reference], '$.TestNullableEnum') AS int) IS NULL +"""); + } + + public override async Task Json_predicate_on_nullableenum2(bool async) + { + await base.Json_predicate_on_nullableenum2(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE CAST(JSON_VALUE([j].[Reference], '$.TestNullableEnum') AS int) IS NOT NULL +"""); + } + + public override async Task Json_predicate_on_nullableenumwithconverter1(bool async) + { + await base.Json_predicate_on_nullableenumwithconverter1(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE CAST(JSON_VALUE([j].[Reference], '$.TestNullableEnumWithIntConverter') AS int) <> 2 OR CAST(JSON_VALUE([j].[Reference], '$.TestNullableEnumWithIntConverter') AS int) IS NULL +"""); + } + + public override async Task Json_predicate_on_nullableenumwithconverter2(bool async) + { + await base.Json_predicate_on_nullableenumwithconverter2(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE CAST(JSON_VALUE([j].[Reference], '$.TestNullableEnumWithIntConverter') AS int) IS NOT NULL +"""); + } + + public override async Task Json_predicate_on_nullableenumwithconverterthathandlesnulls1(bool async) + { + await base.Json_predicate_on_nullableenumwithconverterthathandlesnulls1(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE JSON_VALUE([j].[Reference], '$.TestNullableEnumWithConverterThatHandlesNulls') <> N'One' OR JSON_VALUE([j].[Reference], '$.TestNullableEnumWithConverterThatHandlesNulls') IS NULL +"""); + } + + public override async Task Json_predicate_on_nullableenumwithconverterthathandlesnulls2(bool async) + { + await base.Json_predicate_on_nullableenumwithconverterthathandlesnulls2(async); + + AssertSql( + """ +x +"""); + } + + public override async Task Json_predicate_on_nullableint321(bool async) + { + await base.Json_predicate_on_nullableint321(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE CAST(JSON_VALUE([j].[Reference], '$.TestNullableInt32') AS int) <> 100 OR CAST(JSON_VALUE([j].[Reference], '$.TestNullableInt32') AS int) IS NULL +"""); + } + + public override async Task Json_predicate_on_nullableint322(bool async) + { + await base.Json_predicate_on_nullableint322(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE CAST(JSON_VALUE([j].[Reference], '$.TestNullableInt32') AS int) IS NOT NULL +"""); + } + + public override async Task Json_predicate_on_signedbyte(bool async) + { + await base.Json_predicate_on_signedbyte(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE CAST(JSON_VALUE([j].[Reference], '$.TestSignedByte') AS smallint) <> CAST(100 AS smallint) OR CAST(JSON_VALUE([j].[Reference], '$.TestSignedByte') AS smallint) IS NULL +"""); + } + + public override async Task Json_predicate_on_single(bool async) + { + await base.Json_predicate_on_single(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE CAST(JSON_VALUE([j].[Reference], '$.TestSingle') AS real) <> CAST(10.4 AS real) OR CAST(JSON_VALUE([j].[Reference], '$.TestSingle') AS real) IS NULL +"""); + } + + public override async Task Json_predicate_on_timespan(bool async) + { + await base.Json_predicate_on_timespan(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE CAST(JSON_VALUE([j].[Reference], '$.TestTimeSpan') AS time) <> '03:02:00' OR CAST(JSON_VALUE([j].[Reference], '$.TestTimeSpan') AS time) IS NULL +"""); + } + + public override async Task Json_predicate_on_dateonly(bool async) + { + await base.Json_predicate_on_dateonly(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE CAST(JSON_VALUE([j].[Reference], '$.TestDateOnly') AS date) <> '0003-02-01' OR CAST(JSON_VALUE([j].[Reference], '$.TestDateOnly') AS date) IS NULL +"""); + } + + public override async Task Json_predicate_on_timeonly(bool async) + { + await base.Json_predicate_on_timeonly(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE CAST(JSON_VALUE([j].[Reference], '$.TestTimeOnly') AS time) <> '03:02:00' OR CAST(JSON_VALUE([j].[Reference], '$.TestTimeOnly') AS time) IS NULL +"""); + } + + public override async Task Json_predicate_on_unisgnedint16(bool async) + { + await base.Json_predicate_on_unisgnedint16(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE CAST(JSON_VALUE([j].[Reference], '$.TestUnsignedInt16') AS int) <> 100 OR CAST(JSON_VALUE([j].[Reference], '$.TestUnsignedInt16') AS int) IS NULL +"""); + } + + public override async Task Json_predicate_on_unsignedint32(bool async) + { + await base.Json_predicate_on_unsignedint32(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE CAST(JSON_VALUE([j].[Reference], '$.TestUnsignedInt32') AS bigint) <> CAST(1000 AS bigint) OR CAST(JSON_VALUE([j].[Reference], '$.TestUnsignedInt32') AS bigint) IS NULL +"""); + } + + public override async Task Json_predicate_on_unsignedint64(bool async) + { + await base.Json_predicate_on_unsignedint64(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE CAST(JSON_VALUE([j].[Reference], '$.TestUnsignedInt64') AS decimal(20,0)) <> 10000.0 OR CAST(JSON_VALUE([j].[Reference], '$.TestUnsignedInt64') AS decimal(20,0)) IS NULL +"""); + } + + public override async Task Json_predicate_on_bool_converted_to_int_zero_one(bool async) + { + await base.Json_predicate_on_bool_converted_to_int_zero_one(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[Reference] +FROM [JsonEntitiesConverters] AS [j] +WHERE CAST(JSON_VALUE([j].[Reference], '$.BoolConvertedToIntZeroOne') AS int) = 1 +"""); + } + + public override async Task Json_predicate_on_bool_converted_to_int_zero_one_with_explicit_comparison(bool async) + { + await base.Json_predicate_on_bool_converted_to_int_zero_one_with_explicit_comparison(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[Reference] +FROM [JsonEntitiesConverters] AS [j] +WHERE CAST(JSON_VALUE([j].[Reference], '$.BoolConvertedToIntZeroOne') AS int) = 0 +"""); + } + + public override async Task Json_predicate_on_bool_converted_to_string_True_False(bool async) + { + await base.Json_predicate_on_bool_converted_to_string_True_False(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[Reference] +FROM [JsonEntitiesConverters] AS [j] +WHERE JSON_VALUE([j].[Reference], '$.BoolConvertedToStringTrueFalse') = N'True' +"""); + } + + public override async Task Json_predicate_on_bool_converted_to_string_True_False_with_explicit_comparison(bool async) + { + await base.Json_predicate_on_bool_converted_to_string_True_False_with_explicit_comparison(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[Reference] +FROM [JsonEntitiesConverters] AS [j] +WHERE JSON_VALUE([j].[Reference], '$.BoolConvertedToStringTrueFalse') = N'True' +"""); + } + + public override async Task Json_predicate_on_bool_converted_to_string_Y_N(bool async) + { + await base.Json_predicate_on_bool_converted_to_string_Y_N(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[Reference] +FROM [JsonEntitiesConverters] AS [j] +WHERE JSON_VALUE([j].[Reference], '$.BoolConvertedToStringYN') = N'Y' +"""); + } + + public override async Task Json_predicate_on_bool_converted_to_string_Y_N_with_explicit_comparison(bool async) + { + await base.Json_predicate_on_bool_converted_to_string_Y_N_with_explicit_comparison(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[Reference] +FROM [JsonEntitiesConverters] AS [j] +WHERE JSON_VALUE([j].[Reference], '$.BoolConvertedToStringYN') = N'N' +"""); + } + + public override async Task Json_predicate_on_int_zero_one_converted_to_bool(bool async) + { + await base.Json_predicate_on_int_zero_one_converted_to_bool(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[Reference] +FROM [JsonEntitiesConverters] AS [j] +WHERE CAST(JSON_VALUE([j].[Reference], '$.IntZeroOneConvertedToBool') AS bit) = CAST(1 AS bit) +"""); + } + + public override async Task Json_predicate_on_string_True_False_converted_to_bool(bool async) + { + await base.Json_predicate_on_string_True_False_converted_to_bool(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[Reference] +FROM [JsonEntitiesConverters] AS [j] +WHERE CAST(JSON_VALUE([j].[Reference], '$.StringTrueFalseConvertedToBool') AS bit) = CAST(0 AS bit) +"""); + } + + public override async Task Json_predicate_on_string_Y_N_converted_to_bool(bool async) + { + await base.Json_predicate_on_string_Y_N_converted_to_bool(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[Reference] +FROM [JsonEntitiesConverters] AS [j] +WHERE CAST(JSON_VALUE([j].[Reference], '$.StringYNConvertedToBool') AS bit) = CAST(0 AS bit) +"""); + } + + public override async Task FromSql_on_entity_with_json_basic(bool async) + { + await base.FromSql_on_entity_with_json_basic(async); + + AssertSql( + """ +SELECT [m].[Id], [m].[EntityBasicId], [m].[Name], [m].[OwnedCollectionRoot], [m].[OwnedReferenceRoot] +FROM ( + SELECT * FROM "JsonEntitiesBasic" AS j +) AS [m] +"""); + } + + public virtual async Task FromSqlInterpolated_on_entity_with_json_with_predicate(bool async) + { + var parameter = new SqlParameter { ParameterName = "prm", Value = 1 }; + await AssertQuery( + async, + ss => ((DbSet)ss.Set()).FromSql( + Fixture.TestStore.NormalizeDelimitersInInterpolatedString( + $"SELECT * FROM [JsonEntitiesBasic] AS j WHERE [j].[Id] = {parameter}")), + ss => ss.Set()); + + AssertSql( + """ +prm='1' + +SELECT [m].[Id], [m].[EntityBasicId], [m].[Name], [m].[OwnedCollectionRoot], [m].[OwnedReferenceRoot] +FROM ( + SELECT * FROM "JsonEntitiesBasic" AS j WHERE "j"."Id" = @prm +) AS [m] +"""); + } + + public override async Task FromSql_on_entity_with_json_project_json_reference(bool async) + { + await base.FromSql_on_entity_with_json_project_json_reference(async); + + AssertSql( + """ +SELECT JSON_QUERY([m].[OwnedReferenceRoot], '$.OwnedReferenceBranch'), [m].[Id] +FROM ( + SELECT * FROM "JsonEntitiesBasic" AS j +) AS [m] +"""); + } + + public override async Task FromSql_on_entity_with_json_project_json_collection(bool async) + { + await base.FromSql_on_entity_with_json_project_json_collection(async); + + AssertSql( + """ +SELECT JSON_QUERY([m].[OwnedReferenceRoot], '$.OwnedCollectionBranch'), [m].[Id] +FROM ( + SELECT * FROM "JsonEntitiesBasic" AS j +) AS [m] +"""); + } + + public override async Task FromSql_on_entity_with_json_inheritance_on_base(bool async) + { + // TODO:SQLJSON Returns empty (invalid) JSON (See BadJson.cs) + if (async) + { + Assert.Equal( + "Unable to cast object of type 'System.DBNull' to type 'System.String'.", + (await Assert.ThrowsAsync(() => base.FromSql_on_entity_with_json_inheritance_on_base(true))).Message); + } + else + { + Assert.Equal( + RelationalStrings.JsonEmptyString, + (await Assert.ThrowsAsync(() => base.FromSql_on_entity_with_json_inheritance_on_base(false))) + .Message); + } + + AssertSql( + """ +SELECT [m].[Id], [m].[Discriminator], [m].[Name], [m].[Fraction], [m].[CollectionOnBase], [m].[ReferenceOnBase], [m].[CollectionOnDerived], [m].[ReferenceOnDerived] +FROM ( + SELECT * FROM "JsonEntitiesInheritance" AS j +) AS [m] +"""); + } + + public override async Task FromSql_on_entity_with_json_inheritance_on_derived(bool async) + { + await base.FromSql_on_entity_with_json_inheritance_on_derived(async); + + AssertSql( + """ +SELECT [m].[Id], [m].[Discriminator], [m].[Name], [m].[Fraction], [m].[CollectionOnBase], [m].[ReferenceOnBase], [m].[CollectionOnDerived], [m].[ReferenceOnDerived] +FROM ( + SELECT * FROM "JsonEntitiesInheritance" AS j +) AS [m] +WHERE [m].[Discriminator] = N'JsonEntityInheritanceDerived' +"""); + } + + public override async Task FromSql_on_entity_with_json_inheritance_project_reference_on_base(bool async) + { + await base.FromSql_on_entity_with_json_inheritance_project_reference_on_base(async); + + AssertSql( + """ +SELECT [m].[ReferenceOnBase], [m].[Id] +FROM ( + SELECT * FROM "JsonEntitiesInheritance" AS j +) AS [m] +ORDER BY [m].[Id] +"""); + } + + public override async Task FromSql_on_entity_with_json_inheritance_project_reference_on_derived(bool async) + { + await base.FromSql_on_entity_with_json_inheritance_project_reference_on_derived(async); + + AssertSql( + """ +SELECT [m].[CollectionOnDerived], [m].[Id] +FROM ( + SELECT * FROM "JsonEntitiesInheritance" AS j +) AS [m] +WHERE [m].[Discriminator] = N'JsonEntityInheritanceDerived' +ORDER BY [m].[Id] +"""); + } + + public override async Task Json_projection_nothing_interesting_AsNoTrackingWithIdentityResolution(bool async) + { + await base.Json_projection_nothing_interesting_AsNoTrackingWithIdentityResolution(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[Name] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Json_projection_owner_entity_AsNoTrackingWithIdentityResolution(bool async) + { + await base.Json_projection_owner_entity_AsNoTrackingWithIdentityResolution(async); + + AssertSql( + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Json_nested_collection_anonymous_projection_of_primitives_in_projection_NoTrackingWithIdentityResolution( + bool async) + { + await base.Json_nested_collection_anonymous_projection_of_primitives_in_projection_NoTrackingWithIdentityResolution(async); + + AssertSql( + """ +SELECT [j].[Id], [s].[key], [s].[c], [s].[c0], [s].[c1], [s].[c2], [s].[key0] +FROM [JsonEntitiesBasic] AS [j] +OUTER APPLY ( + SELECT [o].[key], CAST(JSON_VALUE([o0].[value], '$.Date') AS datetime2) AS [c], CAST(JSON_VALUE([o0].[value], '$.Enum') AS int) AS [c0], JSON_QUERY([o0].[value], '$.Enums') AS [c1], CAST(JSON_VALUE([o0].[value], '$.Fraction') AS decimal(18,2)) AS [c2], [o0].[key] AS [key0], CAST([o].[key] AS int) AS [c3], CAST([o0].[key] AS int) AS [c4] + FROM OPENJSON(CAST([j].[OwnedCollectionRoot] AS nvarchar(max)), '$') AS [o] + OUTER APPLY OPENJSON(CAST(JSON_QUERY([o].[value], '$.OwnedCollectionBranch') AS nvarchar(max)), '$') AS [o0] +) AS [s] +ORDER BY [j].[Id], [s].[c3], [s].[key], [s].[c4] +"""); + } + + public override async Task + Json_projection_second_element_through_collection_element_constant_projected_after_owner_nested_AsNoTrackingWithIdentityResolution( + bool async) + { + await base + .Json_projection_second_element_through_collection_element_constant_projected_after_owner_nested_AsNoTrackingWithIdentityResolution( + async); + + AssertSql( + """ +SELECT [j].[Id], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch[0].OwnedCollectionLeaf'), JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch[0].OwnedCollectionLeaf[1]') +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Json_projection_reference_collection_and_collection_element_nested_AsNoTrackingWithIdentityResolution( + bool async) + { + await base.Json_projection_reference_collection_and_collection_element_nested_AsNoTrackingWithIdentityResolution(async); + + AssertSql( + """ +SELECT [j].[Id], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch[0].OwnedReferenceLeaf'), JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch[0].OwnedCollectionLeaf'), JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch[0].OwnedCollectionLeaf[1]') +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + [SqlServerCondition(SqlServerCondition.SupportsJsonPathExpressions)] + public override async Task + Json_projection_second_element_through_collection_element_parameter_correctly_projected_after_owner_nested_AsNoTrackingWithIdentityResolution( + bool async) + { + await base + .Json_projection_second_element_through_collection_element_parameter_correctly_projected_after_owner_nested_AsNoTrackingWithIdentityResolution( + async); + + AssertSql( + """ +@__prm_0='1' + +SELECT [j].[Id], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch[0].OwnedCollectionLeaf'), JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch[0].OwnedCollectionLeaf[' + CAST(@__prm_0 AS nvarchar(max)) + ']'), @__prm_0 +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task + Json_projection_only_second_element_through_collection_element_constant_projected_nested_AsNoTrackingWithIdentityResolution( + bool async) + { + await base + .Json_projection_only_second_element_through_collection_element_constant_projected_nested_AsNoTrackingWithIdentityResolution( + async); + + AssertSql( + """ +SELECT [j].[Id], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch[0].OwnedCollectionLeaf[1]') +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + [SqlServerCondition(SqlServerCondition.SupportsJsonPathExpressions)] + public override async Task + Json_projection_only_second_element_through_collection_element_parameter_projected_nested_AsNoTrackingWithIdentityResolution( + bool async) + { + await base + .Json_projection_only_second_element_through_collection_element_parameter_projected_nested_AsNoTrackingWithIdentityResolution( + async); + + AssertSql( + """ +@__prm1_0='0' +@__prm2_1='1' + +SELECT [j].[Id], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch[' + CAST(@__prm1_0 AS nvarchar(max)) + '].OwnedCollectionLeaf[' + CAST(@__prm2_1 AS nvarchar(max)) + ']'), @__prm1_0, @__prm2_1 +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task + Json_projection_second_element_through_collection_element_constant_different_values_projected_before_owner_nested_AsNoTrackingWithIdentityResolution( + bool async) + { + await base + .Json_projection_second_element_through_collection_element_constant_different_values_projected_before_owner_nested_AsNoTrackingWithIdentityResolution( + async); + + AssertSql( + """ +SELECT [j].[Id], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch[0].OwnedCollectionLeaf[1]'), JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch[1].OwnedCollectionLeaf') +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Json_projection_nested_collection_and_element_correct_order_AsNoTrackingWithIdentityResolution(bool async) + { + await base.Json_projection_nested_collection_and_element_correct_order_AsNoTrackingWithIdentityResolution(async); + + AssertSql( + """ +SELECT [j].[Id], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch[0].OwnedCollectionLeaf'), JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch[0].OwnedCollectionLeaf[1]') +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + [SqlServerCondition(SqlServerCondition.SupportsJsonPathExpressions)] + public override async Task + Json_projection_nested_collection_element_using_parameter_and_the_owner_in_correct_order_AsNoTrackingWithIdentityResolution( + bool async) + { + await base + .Json_projection_nested_collection_element_using_parameter_and_the_owner_in_correct_order_AsNoTrackingWithIdentityResolution( + async); + + AssertSql( + """ +@__prm_0='0' + +SELECT [j].[Id], [j].[OwnedReferenceRoot], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch[' + CAST(@__prm_0 AS nvarchar(max)) + '].OwnedCollectionLeaf[1]'), @__prm_0 +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Json_projection_second_element_projected_before_owner_as_well_as_root_AsNoTrackingWithIdentityResolution( + bool async) + { + await base.Json_projection_second_element_projected_before_owner_as_well_as_root_AsNoTrackingWithIdentityResolution(async); + + AssertSql( + """ +SELECT [j].[Id], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch[1]'), [j].[OwnedReferenceRoot], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task + Json_projection_second_element_projected_before_owner_nested_as_well_as_root_AsNoTrackingWithIdentityResolution(bool async) + { + await base.Json_projection_second_element_projected_before_owner_nested_as_well_as_root_AsNoTrackingWithIdentityResolution(async); + + AssertSql( + """ +SELECT [j].[Id], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedCollectionLeaf[1]'), JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedCollectionLeaf'), JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch'), [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + private void AssertSql(params string[] expected) + => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); +} diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/JsonQuerySqlServerFixture.cs b/test/EFCore.SqlServer.FunctionalTests/Query/JsonQuerySqlServerFixture.cs index 21d51690775..49e5c0660fc 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/JsonQuerySqlServerFixture.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/JsonQuerySqlServerFixture.cs @@ -12,6 +12,9 @@ public class JsonQuerySqlServerFixture : JsonQueryRelationalFixture protected override ITestStoreFactory TestStoreFactory => SqlServerTestStoreFactory.Instance; + public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) + => base.AddOptions(builder).ConfigureWarnings(e => e.Log(SqlServerEventId.JsonTypeExperimental)); + protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) { base.OnModelCreating(modelBuilder, context); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/JsonQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/JsonQuerySqlServerTest.cs index 391940ef030..dc0cf62266c 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/JsonQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/JsonQuerySqlServerTest.cs @@ -530,7 +530,7 @@ public override async Task Custom_naming_projection_owned_reference(bool async) await base.Custom_naming_projection_owned_reference(async); AssertSql( -""" + """ SELECT JSON_QUERY([j].[json_reference_custom_naming], '$."Custom#OwnedReferenceBranch\u0060-=[]\\;\u0027,./~!@#$%^\u0026*()_\u002B{}|:\u0022\u003C\u003E?\u72EC\u89D2\u517D\u03C0\u7368\u89D2\u7378"'), [j].[Id] FROM [JsonEntitiesCustomNaming] AS [j] """); @@ -553,7 +553,7 @@ public override async Task Custom_naming_projection_owned_scalar(bool async) await base.Custom_naming_projection_owned_scalar(async); AssertSql( -""" + """ SELECT CAST(JSON_VALUE([j].[json_reference_custom_naming], '$."Custom#OwnedReferenceBranch\u0060-=[]\\;\u0027,./~!@#$%^\u0026*()_\u002B{}|:\u0022\u003C\u003E?\u72EC\u89D2\u517D\u03C0\u7368\u89D2\u7378"."\u30E6\u30CB\u30B3\u30FC\u30F3Fraction\u4E00\u89D2\u7363"') AS float) FROM [JsonEntitiesCustomNaming] AS [j] """); @@ -564,7 +564,7 @@ public override async Task Custom_naming_projection_everything(bool async) await base.Custom_naming_projection_everything(async); AssertSql( -""" + """ SELECT [j].[Id], [j].[Title], [j].[json_collection_custom_naming], [j].[json_reference_custom_naming], [j].[json_reference_custom_naming], JSON_QUERY([j].[json_reference_custom_naming], '$."Custom#OwnedReferenceBranch\u0060-=[]\\;\u0027,./~!@#$%^\u0026*()_\u002B{}|:\u0022\u003C\u003E?\u72EC\u89D2\u517D\u03C0\u7368\u89D2\u7378"'), [j].[json_collection_custom_naming], JSON_QUERY([j].[json_reference_custom_naming], '$.CustomOwnedCollectionBranch'), JSON_VALUE([j].[json_reference_custom_naming], '$.CustomName'), CAST(JSON_VALUE([j].[json_reference_custom_naming], '$."Custom#OwnedReferenceBranch\u0060-=[]\\;\u0027,./~!@#$%^\u0026*()_\u002B{}|:\u0022\u003C\u003E?\u72EC\u89D2\u517D\u03C0\u7368\u89D2\u7378"."\u30E6\u30CB\u30B3\u30FC\u30F3Fraction\u4E00\u89D2\u7363"') AS float) FROM [JsonEntitiesCustomNaming] AS [j] """); @@ -1173,6 +1173,7 @@ FROM OPENJSON([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch') WITH ( [Date] datetime2 '$.Date', [Enum] int '$.Enum', [Fraction] decimal(18,2) '$.Fraction', + [Id] int '$.Id', [OwnedReferenceLeaf] nvarchar(max) '$.OwnedReferenceLeaf' AS JSON ) AS [o] ORDER BY [o].[Date] DESC @@ -1194,12 +1195,13 @@ FROM [JsonEntitiesBasic] AS [j] WHERE ( SELECT COUNT(*) FROM ( - SELECT DISTINCT [j].[Id], [o].[Date], [o].[Enum], [o].[Enums], [o].[Fraction], [o].[NullableEnum], [o].[NullableEnums], [o].[OwnedCollectionLeaf] AS [c], [o].[OwnedReferenceLeaf] AS [c0] + SELECT DISTINCT [j].[Id], [o].[Date], [o].[Enum], [o].[Enums], [o].[Fraction], [o].[Id] AS [Id0], [o].[NullableEnum], [o].[NullableEnums], [o].[OwnedCollectionLeaf] AS [c], [o].[OwnedReferenceLeaf] AS [c0] FROM OPENJSON([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch') WITH ( [Date] datetime2 '$.Date', [Enum] int '$.Enum', [Enums] nvarchar(max) '$.Enums' AS JSON, [Fraction] decimal(18,2) '$.Fraction', + [Id] int '$.Id', [NullableEnum] int '$.NullableEnum', [NullableEnums] nvarchar(max) '$.NullableEnums' AS JSON, [OwnedCollectionLeaf] nvarchar(max) '$.OwnedCollectionLeaf' AS JSON, @@ -1294,10 +1296,10 @@ public override async Task Json_collection_filter_in_projection(bool async) AssertSql( """ -SELECT [j].[Id], [o0].[Id], [o0].[Name], [o0].[Names], [o0].[Number], [o0].[Numbers], [o0].[c], [o0].[c0], [o0].[key] +SELECT [j].[Id], [o0].[Id], [o0].[Id0], [o0].[Name], [o0].[Names], [o0].[Number], [o0].[Numbers], [o0].[c], [o0].[c0], [o0].[key] FROM [JsonEntitiesBasic] AS [j] OUTER APPLY ( - SELECT [j].[Id], JSON_VALUE([o].[value], '$.Name') AS [Name], JSON_QUERY([o].[value], '$.Names') AS [Names], CAST(JSON_VALUE([o].[value], '$.Number') AS int) AS [Number], JSON_QUERY([o].[value], '$.Numbers') AS [Numbers], JSON_QUERY([o].[value], '$.OwnedCollectionBranch') AS [c], JSON_QUERY([o].[value], '$.OwnedReferenceBranch') AS [c0], [o].[key], CAST([o].[key] AS int) AS [c1] + SELECT [j].[Id], CAST(JSON_VALUE([o].[value], '$.Id') AS int) AS [Id0], JSON_VALUE([o].[value], '$.Name') AS [Name], JSON_QUERY([o].[value], '$.Names') AS [Names], CAST(JSON_VALUE([o].[value], '$.Number') AS int) AS [Number], JSON_QUERY([o].[value], '$.Numbers') AS [Numbers], JSON_QUERY([o].[value], '$.OwnedCollectionBranch') AS [c], JSON_QUERY([o].[value], '$.OwnedReferenceBranch') AS [c0], [o].[key], CAST([o].[key] AS int) AS [c1] FROM OPENJSON([j].[OwnedCollectionRoot], '$') AS [o] WHERE JSON_VALUE([o].[value], '$.Name') <> N'Foo' OR JSON_VALUE([o].[value], '$.Name') IS NULL ) AS [o0] @@ -1311,13 +1313,13 @@ public override async Task Json_nested_collection_filter_in_projection(bool asyn AssertSql( """ -SELECT [j].[Id], [s].[key], [s].[Id], [s].[Date], [s].[Enum], [s].[Enums], [s].[Fraction], [s].[NullableEnum], [s].[NullableEnums], [s].[c], [s].[c0], [s].[key0] +SELECT [j].[Id], [s].[key], [s].[Id], [s].[Date], [s].[Enum], [s].[Enums], [s].[Fraction], [s].[Id0], [s].[NullableEnum], [s].[NullableEnums], [s].[c], [s].[c0], [s].[key0] FROM [JsonEntitiesBasic] AS [j] OUTER APPLY ( - SELECT [o].[key], [o1].[Id], [o1].[Date], [o1].[Enum], [o1].[Enums], [o1].[Fraction], [o1].[NullableEnum], [o1].[NullableEnums], [o1].[c], [o1].[c0], [o1].[key] AS [key0], CAST([o].[key] AS int) AS [c1], [o1].[c1] AS [c10] + SELECT [o].[key], [o1].[Id], [o1].[Date], [o1].[Enum], [o1].[Enums], [o1].[Fraction], [o1].[Id0], [o1].[NullableEnum], [o1].[NullableEnums], [o1].[c], [o1].[c0], [o1].[key] AS [key0], CAST([o].[key] AS int) AS [c1], [o1].[c1] AS [c10] FROM OPENJSON([j].[OwnedCollectionRoot], '$') AS [o] OUTER APPLY ( - SELECT [j].[Id], CAST(JSON_VALUE([o0].[value], '$.Date') AS datetime2) AS [Date], CAST(JSON_VALUE([o0].[value], '$.Enum') AS int) AS [Enum], JSON_QUERY([o0].[value], '$.Enums') AS [Enums], CAST(JSON_VALUE([o0].[value], '$.Fraction') AS decimal(18,2)) AS [Fraction], CAST(JSON_VALUE([o0].[value], '$.NullableEnum') AS int) AS [NullableEnum], JSON_QUERY([o0].[value], '$.NullableEnums') AS [NullableEnums], JSON_QUERY([o0].[value], '$.OwnedCollectionLeaf') AS [c], JSON_QUERY([o0].[value], '$.OwnedReferenceLeaf') AS [c0], [o0].[key], CAST([o0].[key] AS int) AS [c1] + SELECT [j].[Id], CAST(JSON_VALUE([o0].[value], '$.Date') AS datetime2) AS [Date], CAST(JSON_VALUE([o0].[value], '$.Enum') AS int) AS [Enum], JSON_QUERY([o0].[value], '$.Enums') AS [Enums], CAST(JSON_VALUE([o0].[value], '$.Fraction') AS decimal(18,2)) AS [Fraction], CAST(JSON_VALUE([o0].[value], '$.Id') AS int) AS [Id0], CAST(JSON_VALUE([o0].[value], '$.NullableEnum') AS int) AS [NullableEnum], JSON_QUERY([o0].[value], '$.NullableEnums') AS [NullableEnums], JSON_QUERY([o0].[value], '$.OwnedCollectionLeaf') AS [c], JSON_QUERY([o0].[value], '$.OwnedReferenceLeaf') AS [c0], [o0].[key], CAST([o0].[key] AS int) AS [c1] FROM OPENJSON(JSON_QUERY([o].[value], '$.OwnedCollectionBranch'), '$') AS [o0] WHERE CAST(JSON_VALUE([o0].[value], '$.Date') AS datetime2) <> '2000-01-01T00:00:00.0000000' ) AS [o1] @@ -1349,10 +1351,10 @@ public override async Task Json_collection_skip_take_in_projection(bool async) AssertSql( """ -SELECT [j].[Id], [o0].[Id], [o0].[Name], [o0].[Names], [o0].[Number], [o0].[Numbers], [o0].[c], [o0].[c0], [o0].[key] +SELECT [j].[Id], [o0].[Id], [o0].[Id0], [o0].[Name], [o0].[Names], [o0].[Number], [o0].[Numbers], [o0].[c], [o0].[c0], [o0].[key] FROM [JsonEntitiesBasic] AS [j] OUTER APPLY ( - SELECT [j].[Id], JSON_VALUE([o].[value], '$.Name') AS [Name], JSON_QUERY([o].[value], '$.Names') AS [Names], CAST(JSON_VALUE([o].[value], '$.Number') AS int) AS [Number], JSON_QUERY([o].[value], '$.Numbers') AS [Numbers], JSON_QUERY([o].[value], '$.OwnedCollectionBranch') AS [c], JSON_QUERY([o].[value], '$.OwnedReferenceBranch') AS [c0], [o].[key], JSON_VALUE([o].[value], '$.Name') AS [c1] + SELECT [j].[Id], CAST(JSON_VALUE([o].[value], '$.Id') AS int) AS [Id0], JSON_VALUE([o].[value], '$.Name') AS [Name], JSON_QUERY([o].[value], '$.Names') AS [Names], CAST(JSON_VALUE([o].[value], '$.Number') AS int) AS [Number], JSON_QUERY([o].[value], '$.Numbers') AS [Numbers], JSON_QUERY([o].[value], '$.OwnedCollectionBranch') AS [c], JSON_QUERY([o].[value], '$.OwnedReferenceBranch') AS [c0], [o].[key], JSON_VALUE([o].[value], '$.Name') AS [c1] FROM OPENJSON([j].[OwnedCollectionRoot], '$') AS [o] ORDER BY JSON_VALUE([o].[value], '$.Name') OFFSET 1 ROWS FETCH NEXT 5 ROWS ONLY @@ -1403,11 +1405,12 @@ public override async Task Json_collection_distinct_in_projection(bool async) AssertSql( """ -SELECT [j].[Id], [o0].[Id], [o0].[Name], [o0].[Names], [o0].[Number], [o0].[Numbers], [o0].[c], [o0].[c0] +SELECT [j].[Id], [o0].[Id], [o0].[Id0], [o0].[Name], [o0].[Names], [o0].[Number], [o0].[Numbers], [o0].[c], [o0].[c0] FROM [JsonEntitiesBasic] AS [j] OUTER APPLY ( - SELECT DISTINCT [j].[Id], [o].[Name], [o].[Names], [o].[Number], [o].[Numbers], [o].[OwnedCollectionBranch] AS [c], [o].[OwnedReferenceBranch] AS [c0] + SELECT DISTINCT [j].[Id], [o].[Id] AS [Id0], [o].[Name], [o].[Names], [o].[Number], [o].[Numbers], [o].[OwnedCollectionBranch] AS [c], [o].[OwnedReferenceBranch] AS [c0] FROM OPENJSON([j].[OwnedCollectionRoot], '$') WITH ( + [Id] int '$.Id', [Name] nvarchar(max) '$.Name', [Names] nvarchar(max) '$.Names' AS JSON, [Number] int '$.Number', @@ -1416,7 +1419,7 @@ [OwnedCollectionBranch] nvarchar(max) '$.OwnedCollectionBranch' AS JSON, [OwnedReferenceBranch] nvarchar(max) '$.OwnedReferenceBranch' AS JSON ) AS [o] ) AS [o0] -ORDER BY [j].[Id], [o0].[Name], [o0].[Names], [o0].[Number] +ORDER BY [j].[Id], [o0].[Id0], [o0].[Name], [o0].[Names], [o0].[Number] """); } @@ -1450,7 +1453,7 @@ public override async Task Json_multiple_collection_projections(bool async) AssertSql( """ -SELECT [j].[Id], [o4].[Id], [o4].[SomethingSomething], [o4].[key], [o1].[Id], [o1].[Name], [o1].[Names], [o1].[Number], [o1].[Numbers], [o1].[c], [o1].[c0], [s].[key], [s].[Id], [s].[Date], [s].[Enum], [s].[Enums], [s].[Fraction], [s].[NullableEnum], [s].[NullableEnums], [s].[c], [s].[c0], [s].[key0], [j0].[Id], [j0].[Name], [j0].[ParentId] +SELECT [j].[Id], [o4].[Id], [o4].[SomethingSomething], [o4].[key], [o1].[Id], [o1].[Id0], [o1].[Name], [o1].[Names], [o1].[Number], [o1].[Numbers], [o1].[c], [o1].[c0], [s].[key], [s].[Id], [s].[Date], [s].[Enum], [s].[Enums], [s].[Fraction], [s].[Id0], [s].[NullableEnum], [s].[NullableEnums], [s].[c], [s].[c0], [s].[key0], [j0].[Id], [j0].[Name], [j0].[ParentId] FROM [JsonEntitiesBasic] AS [j] OUTER APPLY ( SELECT [j].[Id], JSON_VALUE([o].[value], '$.SomethingSomething') AS [SomethingSomething], [o].[key], CAST([o].[key] AS int) AS [c] @@ -1458,8 +1461,9 @@ FROM OPENJSON([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedCollectionL WHERE JSON_VALUE([o].[value], '$.SomethingSomething') <> N'Baz' OR JSON_VALUE([o].[value], '$.SomethingSomething') IS NULL ) AS [o4] OUTER APPLY ( - SELECT DISTINCT [j].[Id], [o0].[Name], [o0].[Names], [o0].[Number], [o0].[Numbers], [o0].[OwnedCollectionBranch] AS [c], [o0].[OwnedReferenceBranch] AS [c0] + SELECT DISTINCT [j].[Id], [o0].[Id] AS [Id0], [o0].[Name], [o0].[Names], [o0].[Number], [o0].[Numbers], [o0].[OwnedCollectionBranch] AS [c], [o0].[OwnedReferenceBranch] AS [c0] FROM OPENJSON([j].[OwnedCollectionRoot], '$') WITH ( + [Id] int '$.Id', [Name] nvarchar(max) '$.Name', [Names] nvarchar(max) '$.Names' AS JSON, [Number] int '$.Number', @@ -1469,16 +1473,16 @@ [OwnedReferenceBranch] nvarchar(max) '$.OwnedReferenceBranch' AS JSON ) AS [o0] ) AS [o1] OUTER APPLY ( - SELECT [o2].[key], [o5].[Id], [o5].[Date], [o5].[Enum], [o5].[Enums], [o5].[Fraction], [o5].[NullableEnum], [o5].[NullableEnums], [o5].[c], [o5].[c0], [o5].[key] AS [key0], CAST([o2].[key] AS int) AS [c1], [o5].[c1] AS [c10] + SELECT [o2].[key], [o5].[Id], [o5].[Date], [o5].[Enum], [o5].[Enums], [o5].[Fraction], [o5].[Id0], [o5].[NullableEnum], [o5].[NullableEnums], [o5].[c], [o5].[c0], [o5].[key] AS [key0], CAST([o2].[key] AS int) AS [c1], [o5].[c1] AS [c10] FROM OPENJSON([j].[OwnedCollectionRoot], '$') AS [o2] OUTER APPLY ( - SELECT [j].[Id], CAST(JSON_VALUE([o3].[value], '$.Date') AS datetime2) AS [Date], CAST(JSON_VALUE([o3].[value], '$.Enum') AS int) AS [Enum], JSON_QUERY([o3].[value], '$.Enums') AS [Enums], CAST(JSON_VALUE([o3].[value], '$.Fraction') AS decimal(18,2)) AS [Fraction], CAST(JSON_VALUE([o3].[value], '$.NullableEnum') AS int) AS [NullableEnum], JSON_QUERY([o3].[value], '$.NullableEnums') AS [NullableEnums], JSON_QUERY([o3].[value], '$.OwnedCollectionLeaf') AS [c], JSON_QUERY([o3].[value], '$.OwnedReferenceLeaf') AS [c0], [o3].[key], CAST([o3].[key] AS int) AS [c1] + SELECT [j].[Id], CAST(JSON_VALUE([o3].[value], '$.Date') AS datetime2) AS [Date], CAST(JSON_VALUE([o3].[value], '$.Enum') AS int) AS [Enum], JSON_QUERY([o3].[value], '$.Enums') AS [Enums], CAST(JSON_VALUE([o3].[value], '$.Fraction') AS decimal(18,2)) AS [Fraction], CAST(JSON_VALUE([o3].[value], '$.Id') AS int) AS [Id0], CAST(JSON_VALUE([o3].[value], '$.NullableEnum') AS int) AS [NullableEnum], JSON_QUERY([o3].[value], '$.NullableEnums') AS [NullableEnums], JSON_QUERY([o3].[value], '$.OwnedCollectionLeaf') AS [c], JSON_QUERY([o3].[value], '$.OwnedReferenceLeaf') AS [c0], [o3].[key], CAST([o3].[key] AS int) AS [c1] FROM OPENJSON(JSON_QUERY([o2].[value], '$.OwnedCollectionBranch'), '$') AS [o3] WHERE CAST(JSON_VALUE([o3].[value], '$.Date') AS datetime2) <> '2000-01-01T00:00:00.0000000' ) AS [o5] ) AS [s] LEFT JOIN [JsonEntitiesBasicForCollection] AS [j0] ON [j].[Id] = [j0].[ParentId] -ORDER BY [j].[Id], [o4].[c], [o4].[key], [o1].[Name], [o1].[Names], [o1].[Number], [o1].[Numbers], [s].[c1], [s].[key], [s].[c10], [s].[key0] +ORDER BY [j].[Id], [o4].[c], [o4].[key], [o1].[Id0], [o1].[Name], [o1].[Names], [o1].[Number], [o1].[Numbers], [s].[c1], [s].[key], [s].[c10], [s].[key0] """); } @@ -1488,15 +1492,16 @@ public override async Task Json_branch_collection_distinct_and_other_collection( AssertSql( """ -SELECT [j].[Id], [o0].[Id], [o0].[Date], [o0].[Enum], [o0].[Enums], [o0].[Fraction], [o0].[NullableEnum], [o0].[NullableEnums], [o0].[c], [o0].[c0], [j0].[Id], [j0].[Name], [j0].[ParentId] +SELECT [j].[Id], [o0].[Id], [o0].[Date], [o0].[Enum], [o0].[Enums], [o0].[Fraction], [o0].[Id0], [o0].[NullableEnum], [o0].[NullableEnums], [o0].[c], [o0].[c0], [j0].[Id], [j0].[Name], [j0].[ParentId] FROM [JsonEntitiesBasic] AS [j] OUTER APPLY ( - SELECT DISTINCT [j].[Id], [o].[Date], [o].[Enum], [o].[Enums], [o].[Fraction], [o].[NullableEnum], [o].[NullableEnums], [o].[OwnedCollectionLeaf] AS [c], [o].[OwnedReferenceLeaf] AS [c0] + SELECT DISTINCT [j].[Id], [o].[Date], [o].[Enum], [o].[Enums], [o].[Fraction], [o].[Id] AS [Id0], [o].[NullableEnum], [o].[NullableEnums], [o].[OwnedCollectionLeaf] AS [c], [o].[OwnedReferenceLeaf] AS [c0] FROM OPENJSON([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch') WITH ( [Date] datetime2 '$.Date', [Enum] int '$.Enum', [Enums] nvarchar(max) '$.Enums' AS JSON, [Fraction] decimal(18,2) '$.Fraction', + [Id] int '$.Id', [NullableEnum] int '$.NullableEnum', [NullableEnums] nvarchar(max) '$.NullableEnums' AS JSON, [OwnedCollectionLeaf] nvarchar(max) '$.OwnedCollectionLeaf' AS JSON, @@ -1504,7 +1509,7 @@ [OwnedReferenceLeaf] nvarchar(max) '$.OwnedReferenceLeaf' AS JSON ) AS [o] ) AS [o0] LEFT JOIN [JsonEntitiesBasicForCollection] AS [j0] ON [j].[Id] = [j0].[ParentId] -ORDER BY [j].[Id], [o0].[Date], [o0].[Enum], [o0].[Enums], [o0].[Fraction], [o0].[NullableEnum], [o0].[NullableEnums] +ORDER BY [j].[Id], [o0].[Date], [o0].[Enum], [o0].[Enums], [o0].[Fraction], [o0].[Id0], [o0].[NullableEnum], [o0].[NullableEnums] """); } @@ -1531,9 +1536,10 @@ public override async Task Json_collection_SelectMany(bool async) AssertSql( """ -SELECT [j].[Id], [o].[Name], [o].[Names], [o].[Number], [o].[Numbers], [o].[OwnedCollectionBranch], [o].[OwnedReferenceBranch] +SELECT [j].[Id], [o].[Id], [o].[Name], [o].[Names], [o].[Number], [o].[Numbers], [o].[OwnedCollectionBranch], [o].[OwnedReferenceBranch] FROM [JsonEntitiesBasic] AS [j] CROSS APPLY OPENJSON([j].[OwnedCollectionRoot], '$') WITH ( + [Id] int '$.Id', [Name] nvarchar(max) '$.Name', [Names] nvarchar(max) '$.Names' AS JSON, [Number] int '$.Number', @@ -1550,13 +1556,14 @@ public override async Task Json_nested_collection_SelectMany(bool async) AssertSql( """ -SELECT [j].[Id], [o].[Date], [o].[Enum], [o].[Enums], [o].[Fraction], [o].[NullableEnum], [o].[NullableEnums], [o].[OwnedCollectionLeaf], [o].[OwnedReferenceLeaf] +SELECT [j].[Id], [o].[Date], [o].[Enum], [o].[Enums], [o].[Fraction], [o].[Id], [o].[NullableEnum], [o].[NullableEnums], [o].[OwnedCollectionLeaf], [o].[OwnedReferenceLeaf] FROM [JsonEntitiesBasic] AS [j] CROSS APPLY OPENJSON([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch') WITH ( [Date] datetime2 '$.Date', [Enum] int '$.Enum', [Enums] nvarchar(max) '$.Enums' AS JSON, [Fraction] decimal(18,2) '$.Fraction', + [Id] int '$.Id', [NullableEnum] int '$.NullableEnum', [NullableEnums] nvarchar(max) '$.NullableEnums' AS JSON, [OwnedCollectionLeaf] nvarchar(max) '$.OwnedCollectionLeaf' AS JSON, @@ -2959,13 +2966,12 @@ ORDER BY [m].[Id] """); } - public override async Task Json_projection_nothing_interesting_AsNoTrackingWithIdentityResolution(bool async) { await base.Json_projection_nothing_interesting_AsNoTrackingWithIdentityResolution(async); AssertSql( -""" + """ SELECT [j].[Id], [j].[Name] FROM [JsonEntitiesBasic] AS [j] """); @@ -2976,18 +2982,19 @@ public override async Task Json_projection_owner_entity_AsNoTrackingWithIdentity await base.Json_projection_owner_entity_AsNoTrackingWithIdentityResolution(async); AssertSql( -""" + """ SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] FROM [JsonEntitiesBasic] AS [j] """); } - public override async Task Json_nested_collection_anonymous_projection_of_primitives_in_projection_NoTrackingWithIdentityResolution(bool async) + public override async Task Json_nested_collection_anonymous_projection_of_primitives_in_projection_NoTrackingWithIdentityResolution( + bool async) { await base.Json_nested_collection_anonymous_projection_of_primitives_in_projection_NoTrackingWithIdentityResolution(async); AssertSql( -""" + """ SELECT [j].[Id], [s].[key], [s].[c], [s].[c0], [s].[c1], [s].[c2], [s].[key0] FROM [JsonEntitiesBasic] AS [j] OUTER APPLY ( @@ -2999,35 +3006,44 @@ OUTER APPLY OPENJSON(JSON_QUERY([o].[value], '$.OwnedCollectionBranch'), '$') AS """); } - public override async Task Json_projection_second_element_through_collection_element_constant_projected_after_owner_nested_AsNoTrackingWithIdentityResolution(bool async) + public override async Task + Json_projection_second_element_through_collection_element_constant_projected_after_owner_nested_AsNoTrackingWithIdentityResolution( + bool async) { - await base.Json_projection_second_element_through_collection_element_constant_projected_after_owner_nested_AsNoTrackingWithIdentityResolution(async); + await base + .Json_projection_second_element_through_collection_element_constant_projected_after_owner_nested_AsNoTrackingWithIdentityResolution( + async); AssertSql( -""" + """ SELECT [j].[Id], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch[0].OwnedCollectionLeaf'), JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch[0].OwnedCollectionLeaf[1]') FROM [JsonEntitiesBasic] AS [j] """); } - public override async Task Json_projection_reference_collection_and_collection_element_nested_AsNoTrackingWithIdentityResolution(bool async) + public override async Task Json_projection_reference_collection_and_collection_element_nested_AsNoTrackingWithIdentityResolution( + bool async) { await base.Json_projection_reference_collection_and_collection_element_nested_AsNoTrackingWithIdentityResolution(async); AssertSql( -""" + """ SELECT [j].[Id], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch[0].OwnedReferenceLeaf'), JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch[0].OwnedCollectionLeaf'), JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch[0].OwnedCollectionLeaf[1]') FROM [JsonEntitiesBasic] AS [j] """); } [SqlServerCondition(SqlServerCondition.SupportsJsonPathExpressions)] - public override async Task Json_projection_second_element_through_collection_element_parameter_correctly_projected_after_owner_nested_AsNoTrackingWithIdentityResolution(bool async) + public override async Task + Json_projection_second_element_through_collection_element_parameter_correctly_projected_after_owner_nested_AsNoTrackingWithIdentityResolution( + bool async) { - await base.Json_projection_second_element_through_collection_element_parameter_correctly_projected_after_owner_nested_AsNoTrackingWithIdentityResolution(async); + await base + .Json_projection_second_element_through_collection_element_parameter_correctly_projected_after_owner_nested_AsNoTrackingWithIdentityResolution( + async); AssertSql( -""" + """ @__prm_0='1' SELECT [j].[Id], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch[0].OwnedCollectionLeaf'), JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch[0].OwnedCollectionLeaf[' + CAST(@__prm_0 AS nvarchar(max)) + ']'), @__prm_0 @@ -3035,24 +3051,32 @@ FROM [JsonEntitiesBasic] AS [j] """); } - public override async Task Json_projection_only_second_element_through_collection_element_constant_projected_nested_AsNoTrackingWithIdentityResolution(bool async) + public override async Task + Json_projection_only_second_element_through_collection_element_constant_projected_nested_AsNoTrackingWithIdentityResolution( + bool async) { - await base.Json_projection_only_second_element_through_collection_element_constant_projected_nested_AsNoTrackingWithIdentityResolution(async); + await base + .Json_projection_only_second_element_through_collection_element_constant_projected_nested_AsNoTrackingWithIdentityResolution( + async); AssertSql( -""" + """ SELECT [j].[Id], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch[0].OwnedCollectionLeaf[1]') FROM [JsonEntitiesBasic] AS [j] """); } [SqlServerCondition(SqlServerCondition.SupportsJsonPathExpressions)] - public override async Task Json_projection_only_second_element_through_collection_element_parameter_projected_nested_AsNoTrackingWithIdentityResolution(bool async) + public override async Task + Json_projection_only_second_element_through_collection_element_parameter_projected_nested_AsNoTrackingWithIdentityResolution( + bool async) { - await base.Json_projection_only_second_element_through_collection_element_parameter_projected_nested_AsNoTrackingWithIdentityResolution(async); + await base + .Json_projection_only_second_element_through_collection_element_parameter_projected_nested_AsNoTrackingWithIdentityResolution( + async); AssertSql( -""" + """ @__prm1_0='0' @__prm2_1='1' @@ -3061,12 +3085,16 @@ FROM [JsonEntitiesBasic] AS [j] """); } - public override async Task Json_projection_second_element_through_collection_element_constant_different_values_projected_before_owner_nested_AsNoTrackingWithIdentityResolution(bool async) + public override async Task + Json_projection_second_element_through_collection_element_constant_different_values_projected_before_owner_nested_AsNoTrackingWithIdentityResolution( + bool async) { - await base.Json_projection_second_element_through_collection_element_constant_different_values_projected_before_owner_nested_AsNoTrackingWithIdentityResolution(async); + await base + .Json_projection_second_element_through_collection_element_constant_different_values_projected_before_owner_nested_AsNoTrackingWithIdentityResolution( + async); AssertSql( -""" + """ SELECT [j].[Id], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch[0].OwnedCollectionLeaf[1]'), JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch[1].OwnedCollectionLeaf') FROM [JsonEntitiesBasic] AS [j] """); @@ -3077,19 +3105,23 @@ public override async Task Json_projection_nested_collection_and_element_correct await base.Json_projection_nested_collection_and_element_correct_order_AsNoTrackingWithIdentityResolution(async); AssertSql( -""" + """ SELECT [j].[Id], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch[0].OwnedCollectionLeaf'), JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch[0].OwnedCollectionLeaf[1]') FROM [JsonEntitiesBasic] AS [j] """); } [SqlServerCondition(SqlServerCondition.SupportsJsonPathExpressions)] - public override async Task Json_projection_nested_collection_element_using_parameter_and_the_owner_in_correct_order_AsNoTrackingWithIdentityResolution(bool async) + public override async Task + Json_projection_nested_collection_element_using_parameter_and_the_owner_in_correct_order_AsNoTrackingWithIdentityResolution( + bool async) { - await base.Json_projection_nested_collection_element_using_parameter_and_the_owner_in_correct_order_AsNoTrackingWithIdentityResolution(async); + await base + .Json_projection_nested_collection_element_using_parameter_and_the_owner_in_correct_order_AsNoTrackingWithIdentityResolution( + async); AssertSql( -""" + """ @__prm_0='0' SELECT [j].[Id], [j].[OwnedReferenceRoot], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch[' + CAST(@__prm_0 AS nvarchar(max)) + '].OwnedCollectionLeaf[1]'), @__prm_0 @@ -3097,23 +3129,25 @@ FROM [JsonEntitiesBasic] AS [j] """); } - public override async Task Json_projection_second_element_projected_before_owner_as_well_as_root_AsNoTrackingWithIdentityResolution(bool async) + public override async Task Json_projection_second_element_projected_before_owner_as_well_as_root_AsNoTrackingWithIdentityResolution( + bool async) { await base.Json_projection_second_element_projected_before_owner_as_well_as_root_AsNoTrackingWithIdentityResolution(async); AssertSql( -""" + """ SELECT [j].[Id], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedCollectionBranch[1]'), [j].[OwnedReferenceRoot], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] FROM [JsonEntitiesBasic] AS [j] """); } - public override async Task Json_projection_second_element_projected_before_owner_nested_as_well_as_root_AsNoTrackingWithIdentityResolution(bool async) + public override async Task + Json_projection_second_element_projected_before_owner_nested_as_well_as_root_AsNoTrackingWithIdentityResolution(bool async) { await base.Json_projection_second_element_projected_before_owner_nested_as_well_as_root_AsNoTrackingWithIdentityResolution(async); AssertSql( -""" + """ SELECT [j].[Id], JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedCollectionLeaf[1]'), JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch.OwnedCollectionLeaf'), JSON_QUERY([j].[OwnedReferenceRoot], '$.OwnedReferenceBranch'), [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] FROM [JsonEntitiesBasic] AS [j] """); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/MappingQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/MappingQuerySqlServerTest.cs index 019de4e990d..4b380debfb0 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/MappingQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/MappingQuerySqlServerTest.cs @@ -53,9 +53,7 @@ FROM [dbo].[Orders] AS [o] public MappingQuerySqlServerTest(MappingQuerySqlServerFixture fixture) : base(fixture) - { - Fixture.TestSqlLoggerFactory.Clear(); - } + => Fixture.TestSqlLoggerFactory.Clear(); private void AssertSql(params string[] expected) => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NonSharedPrimitiveCollectionsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NonSharedPrimitiveCollectionsQuerySqlServerTest.cs index b446632b715..3c7166fd2c1 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NonSharedPrimitiveCollectionsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NonSharedPrimitiveCollectionsQuerySqlServerTest.cs @@ -6,11 +6,24 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable - using static Expression; public class NonSharedPrimitiveCollectionsQuerySqlServerTest : NonSharedPrimitiveCollectionsQueryRelationalTestBase { + protected override DbContextOptionsBuilder SetTranslateParameterizedCollectionsToConstants(DbContextOptionsBuilder optionsBuilder) + { + new SqlServerDbContextOptionsBuilder(optionsBuilder).TranslateParameterizedCollectionsToConstants(); + + return optionsBuilder; + } + + protected override DbContextOptionsBuilder SetTranslateParameterizedCollectionsToParameters(DbContextOptionsBuilder optionsBuilder) + { + new SqlServerDbContextOptionsBuilder(optionsBuilder).TranslateParameterizedCollectionsToParameters(); + + return optionsBuilder; + } + #region Support for specific element types public override async Task Array_of_string() @@ -700,7 +713,7 @@ public override async Task Column_with_custom_converter() await base.Column_with_custom_converter(); AssertSql( -""" + """ @__ints_0='1,2,3' (Size = 4000) SELECT TOP(2) [t].[Id], [t].[Ints] @@ -779,6 +792,128 @@ FROM [TestEntityWithOwned] AS [t] """); } + public override async Task Parameter_collection_Count_with_column_predicate_with_default_constants() + { + await base.Parameter_collection_Count_with_column_predicate_with_default_constants(); + + AssertSql( + """ +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM (VALUES (2), (999)) AS [i]([Value]) + WHERE [i].[Value] > [t].[Id]) = 1 +"""); + } + + public override async Task Parameter_collection_of_ints_Contains_int_with_default_constants() + { + await base.Parameter_collection_of_ints_Contains_int_with_default_constants(); + + AssertSql( + """ +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE [t].[Id] IN (2, 999) +"""); + } + + public override async Task Parameter_collection_Count_with_column_predicate_with_default_constants_EF_Parameter() + { + await base.Parameter_collection_Count_with_column_predicate_with_default_constants_EF_Parameter(); + + AssertSql( + """ +@__ids_0='[2,999]' (Size = 4000) + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON(@__ids_0) WITH ([value] int '$') AS [i] + WHERE [i].[value] > [t].[Id]) = 1 +"""); + } + + public override async Task Parameter_collection_of_ints_Contains_int_with_default_constants_EF_Parameter() + { + await base.Parameter_collection_of_ints_Contains_int_with_default_constants_EF_Parameter(); + + AssertSql( + """ +@__ints_0='[2,999]' (Size = 4000) + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE [t].[Id] IN ( + SELECT [i].[value] + FROM OPENJSON(@__ints_0) WITH ([value] int '$') AS [i] +) +"""); + } + + public override async Task Parameter_collection_Count_with_column_predicate_with_default_parameters() + { + await base.Parameter_collection_Count_with_column_predicate_with_default_parameters(); + + AssertSql( + """ +@__ids_0='[2,999]' (Size = 4000) + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON(@__ids_0) WITH ([value] int '$') AS [i] + WHERE [i].[value] > [t].[Id]) = 1 +"""); + } + + public override async Task Parameter_collection_of_ints_Contains_int_with_default_parameters() + { + await base.Parameter_collection_of_ints_Contains_int_with_default_parameters(); + + AssertSql( + """ +@__ints_0='[2,999]' (Size = 4000) + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE [t].[Id] IN ( + SELECT [i].[value] + FROM OPENJSON(@__ints_0) WITH ([value] int '$') AS [i] +) +"""); + } + + public override async Task Parameter_collection_Count_with_column_predicate_with_default_parameters_EF_Constant() + { + await base.Parameter_collection_Count_with_column_predicate_with_default_parameters_EF_Constant(); + + AssertSql( + """ +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM (VALUES (2), (999)) AS [i]([Value]) + WHERE [i].[Value] > [t].[Id]) = 1 +"""); + } + + public override async Task Parameter_collection_of_ints_Contains_int_with_default_parameters_EF_Constant() + { + await base.Parameter_collection_of_ints_Contains_int_with_default_parameters_EF_Constant(); + + AssertSql( + """ +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE [t].[Id] IN (2, 999) +"""); + } + [ConditionalFact] public virtual async Task Same_parameter_with_different_type_mappings() { diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindAggregateOperatorsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindAggregateOperatorsQuerySqlServerTest.cs index 033b0de4407..a34a4630461 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindAggregateOperatorsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindAggregateOperatorsQuerySqlServerTest.cs @@ -1888,7 +1888,7 @@ FROM OPENJSON(@__ids_0) WITH ([value] nchar(5) '$') AS [i] ) """, // -""" + """ @__ids_0='["ABCDE"]' (Size = 4000) SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] @@ -1970,7 +1970,7 @@ FROM OPENJSON(@__ids_0) WITH ([value] nchar(5) '$') AS [i] ) """, // -""" + """ @__ids_0='["ABCDE"]' (Size = 4000) SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] @@ -2044,7 +2044,7 @@ FROM OPENJSON(@__Order_0) WITH ([value] nchar(5) '$') AS [o] ) """, // -""" + """ @__Order_0='["ABCDE","ANATR"]' (Size = 4000) SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] @@ -2071,8 +2071,8 @@ SELECT [i].[value] FROM OPENJSON(@__ids_0) WITH ([value] nchar(5) '$') AS [i] ) """, - // - """ + // + """ @__ids_0='["ABCDE"]' (Size = 4000) SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] @@ -2145,8 +2145,8 @@ SELECT [a].[value] FROM OPENJSON(@__AsReadOnly_0) WITH ([value] nchar(5) '$') AS [a] ) """, - // - """ + // + """ @__AsReadOnly_0='["ABCDE","ANATR"]' (Size = 4000) SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] @@ -3169,38 +3169,38 @@ public override async Task Return_type_of_singular_operator_is_preserved(bool as await base.Return_type_of_singular_operator_is_preserved(async); AssertSql( -""" + """ SELECT TOP(1) [c].[CustomerID], [c].[City] FROM [Customers] AS [c] WHERE [c].[CustomerID] = N'ALFKI' """, - // - """ + // + """ SELECT TOP(1) [c].[CustomerID], [c].[City] FROM [Customers] AS [c] WHERE [c].[CustomerID] = N'ALFKI' """, - // - """ + // + """ SELECT TOP(2) [c].[CustomerID], [c].[City] FROM [Customers] AS [c] WHERE [c].[CustomerID] = N'ALFKI' """, - // - """ + // + """ SELECT TOP(2) [c].[CustomerID], [c].[City] FROM [Customers] AS [c] WHERE [c].[CustomerID] = N'ALFKI' """, - // - """ + // + """ SELECT TOP(1) [c].[CustomerID], [c].[City] FROM [Customers] AS [c] WHERE [c].[CustomerID] LIKE N'A%' ORDER BY [c].[CustomerID] DESC """, - // - """ + // + """ SELECT TOP(1) [c].[CustomerID], [c].[City] FROM [Customers] AS [c] WHERE [c].[CustomerID] LIKE N'A%' @@ -3213,7 +3213,7 @@ public override async Task Type_casting_inside_sum(bool async) await base.Type_casting_inside_sum(async); AssertSql( -""" + """ SELECT COALESCE(SUM(CAST([o].[Discount] AS decimal(18,2))), 0.0) FROM [Order Details] AS [o] """); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindAsTrackingQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindAsTrackingQuerySqlServerTest.cs index 5bcce95ac8a..46d8f9a3731 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindAsTrackingQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindAsTrackingQuerySqlServerTest.cs @@ -10,9 +10,7 @@ public class NorthwindAsTrackingQuerySqlServerTest : NorthwindAsTrackingQueryTes { public NorthwindAsTrackingQuerySqlServerTest(NorthwindQuerySqlServerFixture fixture) : base(fixture) - { - Fixture.TestSqlLoggerFactory.Clear(); - } + => Fixture.TestSqlLoggerFactory.Clear(); [ConditionalFact] public virtual void Check_all_tests_overridden() diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindChangeTrackingQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindChangeTrackingQuerySqlServerTest.cs index 0401997f13d..1751f95bd89 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindChangeTrackingQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindChangeTrackingQuerySqlServerTest.cs @@ -12,9 +12,7 @@ public class NorthwindChangeTrackingQuerySqlServerTest : NorthwindChangeTracking { public NorthwindChangeTrackingQuerySqlServerTest(NorthwindQuerySqlServerFixture fixture) : base(fixture) - { - Fixture.TestSqlLoggerFactory.Clear(); - } + => Fixture.TestSqlLoggerFactory.Clear(); [ConditionalFact] public virtual void Check_all_tests_overridden() diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindEFPropertyIncludeQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindEFPropertyIncludeQuerySqlServerTest.cs index da37c8b4f3c..3cfb0e6340a 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindEFPropertyIncludeQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindEFPropertyIncludeQuerySqlServerTest.cs @@ -10,9 +10,7 @@ public class NorthwindEFPropertyIncludeQuerySqlServerTest : NorthwindEFPropertyI { public NorthwindEFPropertyIncludeQuerySqlServerTest(NorthwindQuerySqlServerFixture fixture) : base(fixture) - { - Fixture.TestSqlLoggerFactory.Clear(); - } + => Fixture.TestSqlLoggerFactory.Clear(); [ConditionalFact] public virtual void Check_all_tests_overridden() diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindFunctionsQuerySqlServer160Test.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindFunctionsQuerySqlServer160Test.cs index 555f1733719..84fc4b39966 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindFunctionsQuerySqlServer160Test.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindFunctionsQuerySqlServer160Test.cs @@ -2686,7 +2686,7 @@ WHERE RTRIM([c].[ContactTitle]) = N'Owner' public override async Task TrimEnd_with_char_argument_in_predicate(bool async) { - await base.TrimEnd_with_char_argument_in_predicate(async); + await base.TrimEnd_with_char_argument_in_predicate(async); AssertSql( """ diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindFunctionsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindFunctionsQuerySqlServerTest.cs index 12e35480552..ee401529e9f 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindFunctionsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindFunctionsQuerySqlServerTest.cs @@ -447,32 +447,32 @@ public override async Task String_Compare_simple_zero(bool async) FROM [Customers] AS [c] WHERE [c].[CustomerID] = N'AROUT' """, - // - """ + // + """ SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[CustomerID] <> N'AROUT' """, - // - """ + // + """ SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[CustomerID] > N'AROUT' """, - // - """ + // + """ SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[CustomerID] <= N'AROUT' """, - // - """ + // + """ SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[CustomerID] > N'AROUT' """, - // - """ + // + """ SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[CustomerID] <= N'AROUT' @@ -489,32 +489,32 @@ public override async Task String_Compare_simple_one(bool async) FROM [Customers] AS [c] WHERE [c].[CustomerID] > N'AROUT' """, - // - """ + // + """ SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[CustomerID] < N'AROUT' """, - // - """ + // + """ SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[CustomerID] <= N'AROUT' """, - // - """ + // + """ SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[CustomerID] <= N'AROUT' """, - // - """ + // + """ SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[CustomerID] >= N'AROUT' """, - // - """ + // + """ SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[CustomerID] >= N'AROUT' @@ -533,40 +533,40 @@ public override async Task String_compare_with_parameter(bool async) FROM [Customers] AS [c] WHERE [c].[CustomerID] > @__customer_CustomerID_0 """, - // - """ + // + """ @__customer_CustomerID_0='AROUT' (Size = 5) (DbType = StringFixedLength) SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[CustomerID] < @__customer_CustomerID_0 """, - // - """ + // + """ @__customer_CustomerID_0='AROUT' (Size = 5) (DbType = StringFixedLength) SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[CustomerID] <= @__customer_CustomerID_0 """, - // - """ + // + """ @__customer_CustomerID_0='AROUT' (Size = 5) (DbType = StringFixedLength) SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[CustomerID] <= @__customer_CustomerID_0 """, - // - """ + // + """ @__customer_CustomerID_0='AROUT' (Size = 5) (DbType = StringFixedLength) SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[CustomerID] >= @__customer_CustomerID_0 """, - // - """ + // + """ @__customer_CustomerID_0='AROUT' (Size = 5) (DbType = StringFixedLength) SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] @@ -681,32 +681,32 @@ public override async Task String_Compare_to_simple_zero(bool async) FROM [Customers] AS [c] WHERE [c].[CustomerID] = N'AROUT' """, - // - """ + // + """ SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[CustomerID] <> N'AROUT' """, - // - """ + // + """ SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[CustomerID] > N'AROUT' """, - // - """ + // + """ SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[CustomerID] <= N'AROUT' """, - // - """ + // + """ SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[CustomerID] > N'AROUT' """, - // - """ + // + """ SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[CustomerID] <= N'AROUT' @@ -723,32 +723,32 @@ public override async Task String_Compare_to_simple_one(bool async) FROM [Customers] AS [c] WHERE [c].[CustomerID] > N'AROUT' """, - // - """ + // + """ SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[CustomerID] < N'AROUT' """, - // - """ + // + """ SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[CustomerID] <= N'AROUT' """, - // - """ + // + """ SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[CustomerID] <= N'AROUT' """, - // - """ + // + """ SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[CustomerID] >= N'AROUT' """, - // - """ + // + """ SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[CustomerID] >= N'AROUT' @@ -767,40 +767,40 @@ public override async Task String_compare_to_with_parameter(bool async) FROM [Customers] AS [c] WHERE [c].[CustomerID] > @__customer_CustomerID_0 """, - // - """ + // + """ @__customer_CustomerID_0='AROUT' (Size = 5) (DbType = StringFixedLength) SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[CustomerID] < @__customer_CustomerID_0 """, - // - """ + // + """ @__customer_CustomerID_0='AROUT' (Size = 5) (DbType = StringFixedLength) SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[CustomerID] <= @__customer_CustomerID_0 """, - // - """ + // + """ @__customer_CustomerID_0='AROUT' (Size = 5) (DbType = StringFixedLength) SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[CustomerID] <= @__customer_CustomerID_0 """, - // - """ + // + """ @__customer_CustomerID_0='AROUT' (Size = 5) (DbType = StringFixedLength) SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[CustomerID] >= @__customer_CustomerID_0 """, - // - """ + // + """ @__customer_CustomerID_0='AROUT' (Size = 5) (DbType = StringFixedLength) SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] @@ -855,32 +855,32 @@ public override async Task String_Compare_to_nested(bool async) FROM [Customers] AS [c] WHERE [c].[CustomerID] <> N'M' + [c].[CustomerID] """, - // - """ + // + """ SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[CustomerID] = UPPER([c].[CustomerID]) """, - // - """ + // + """ SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[CustomerID] > REPLACE(N'AROUT', N'OUT', [c].[CustomerID]) """, - // - """ + // + """ SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[CustomerID] <= N'M' + [c].[CustomerID] """, - // - """ + // + """ SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[CustomerID] > UPPER([c].[CustomerID]) """, - // - """ + // + """ SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[CustomerID] < REPLACE(N'AROUT', N'OUT', [c].[CustomerID]) @@ -2791,7 +2791,7 @@ public override async Task String_Contains_in_projection(bool async) await base.String_Contains_in_projection(async); AssertSql( -""" + """ SELECT [c].[CustomerID] AS [Id], CASE WHEN [c].[ContactName] IS NOT NULL AND (CHARINDEX([c].[ContactName], [c].[CompanyName]) > 0 OR [c].[ContactName] LIKE N'') THEN CAST(1 AS bit) ELSE CAST(0 AS bit) @@ -2805,7 +2805,7 @@ public override async Task String_Contains_negated_in_predicate(bool async) await base.String_Contains_negated_in_predicate(async); AssertSql( -""" + """ SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] WHERE [c].[ContactName] IS NULL OR (CHARINDEX([c].[ContactName], [c].[CompanyName]) <= 0 AND [c].[ContactName] NOT LIKE N'') @@ -2817,7 +2817,7 @@ public override async Task String_Contains_negated_in_projection(bool async) await base.String_Contains_negated_in_projection(async); AssertSql( -""" + """ SELECT [c].[CustomerID] AS [Id], CASE WHEN [c].[ContactName] IS NULL OR (CHARINDEX([c].[ContactName], [c].[CompanyName]) <= 0 AND [c].[ContactName] NOT LIKE N'') THEN CAST(1 AS bit) ELSE CAST(0 AS bit) diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindGroupByQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindGroupByQuerySqlServerTest.cs index b0bd1c81497..3ade710428e 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindGroupByQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindGroupByQuerySqlServerTest.cs @@ -2475,7 +2475,7 @@ public override async Task GroupBy_Select_Distinct_aggregate(bool async) AssertSql( """ -SELECT [o].[CustomerID] AS [Key], AVG(DISTINCT (CAST([o].[OrderID] AS float))) AS [Average], COUNT(DISTINCT ([o].[EmployeeID])) AS [Count], COUNT_BIG(DISTINCT ([o].[EmployeeID])) AS [LongCount], MAX(DISTINCT ([o].[OrderDate])) AS [Max], MIN(DISTINCT ([o].[OrderDate])) AS [Min], COALESCE(SUM(DISTINCT ([o].[OrderID])), 0) AS [Sum] +SELECT [o].[CustomerID] AS [Key], AVG(DISTINCT (CAST([o].[OrderID] AS float))) AS [Average], COUNT(DISTINCT ([o].[EmployeeID])) AS [Count], COUNT_BIG(DISTINCT ([o].[EmployeeID])) AS [LongCount], MAX([o].[OrderDate]) AS [Max], MIN([o].[OrderDate]) AS [Min], COALESCE(SUM(DISTINCT ([o].[OrderID])), 0) AS [Sum] FROM [Orders] AS [o] GROUP BY [o].[CustomerID] """); @@ -2487,7 +2487,7 @@ public override async Task GroupBy_group_Distinct_Select_Distinct_aggregate(bool AssertSql( """ -SELECT [o].[CustomerID] AS [Key], MAX(DISTINCT ([o].[OrderDate])) AS [Max] +SELECT [o].[CustomerID] AS [Key], MAX([o].[OrderDate]) AS [Max] FROM [Orders] AS [o] GROUP BY [o].[CustomerID] """); @@ -2499,9 +2499,9 @@ public override async Task GroupBy_group_Where_Select_Distinct_aggregate(bool as AssertSql( """ -SELECT [o].[CustomerID] AS [Key], MAX(DISTINCT (CASE +SELECT [o].[CustomerID] AS [Key], MAX(CASE WHEN [o].[OrderDate] IS NOT NULL THEN [o].[OrderDate] -END)) AS [Max] +END) AS [Max] FROM [Orders] AS [o] GROUP BY [o].[CustomerID] """); @@ -3595,6 +3595,8 @@ public override async Task GroupBy_aggregate_SelectMany(bool async) AssertSql(); } + #region FinalGroupBy + public override async Task Final_GroupBy_property_entity(bool async) { await base.Final_GroupBy_property_entity(async); @@ -3772,6 +3774,22 @@ FROM [Orders] AS [o0] """); } + public override async Task Final_GroupBy_TagWith(bool async) + { + await base.Final_GroupBy_TagWith(async); + + AssertSql( + """ +-- foo + +SELECT [c].[City], [c].[CustomerID], [c].[Address], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] +FROM [Customers] AS [c] +ORDER BY [c].[City] +"""); + } + + #endregion FinalGroupBy + public override async Task GroupBy_Where_with_grouping_result(bool async) { await base.GroupBy_Where_with_grouping_result(async); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindIncludeNoTrackingQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindIncludeNoTrackingQuerySqlServerTest.cs index 2481d8e6f9d..911848c713f 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindIncludeNoTrackingQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindIncludeNoTrackingQuerySqlServerTest.cs @@ -10,9 +10,7 @@ public class NorthwindIncludeNoTrackingQuerySqlServerTest : NorthwindIncludeNoTr { public NorthwindIncludeNoTrackingQuerySqlServerTest(NorthwindQuerySqlServerFixture fixture) : base(fixture) - { - Fixture.TestSqlLoggerFactory.Clear(); - } + => Fixture.TestSqlLoggerFactory.Clear(); [ConditionalFact] public virtual void Check_all_tests_overridden() diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindMiscellaneousQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindMiscellaneousQuerySqlServerTest.cs index 8743cb7099c..9cec3c4e613 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindMiscellaneousQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindMiscellaneousQuerySqlServerTest.cs @@ -4744,11 +4744,8 @@ public override async Task Select_distinct_max(bool async) AssertSql( """ -SELECT MAX([o0].[OrderID]) -FROM ( - SELECT DISTINCT [o].[OrderID] - FROM [Orders] AS [o] -) AS [o0] +SELECT MAX([o].[OrderID]) +FROM [Orders] AS [o] """); } @@ -4758,11 +4755,8 @@ public override async Task Select_distinct_min(bool async) AssertSql( """ -SELECT MIN([o0].[OrderID]) -FROM ( - SELECT DISTINCT [o].[OrderID] - FROM [Orders] AS [o] -) AS [o0] +SELECT MIN([o].[OrderID]) +FROM [Orders] AS [o] """); } @@ -7392,13 +7386,10 @@ FROM [Customers] AS [c] } public override async Task Compiler_generated_local_closure_produces_valid_parameter_name(bool async) - { - await base.Compiler_generated_local_closure_produces_valid_parameter_name(async); - - // No AssertSQL since compiler generated variable names are different between local and CI - //AssertSql(""); - } + => await base.Compiler_generated_local_closure_produces_valid_parameter_name(async); + // No AssertSQL since compiler generated variable names are different between local and CI + //AssertSql(""); public override async Task Static_member_access_gets_parameterized_within_larger_evaluatable(bool async) { await base.Static_member_access_gets_parameterized_within_larger_evaluatable(async); @@ -7413,6 +7404,46 @@ FROM [Customers] AS [c] """); } + public override async Task Select_Order(bool async) + { + await base.Select_Order(async); + + AssertSql( + """ +SELECT [c].[CustomerID] +FROM [Customers] AS [c] +ORDER BY [c].[CustomerID] +"""); + } + + public override async Task Select_OrderDescending(bool async) + { + await base.Select_OrderDescending(async); + + AssertSql( + """ +SELECT [c].[CustomerID] +FROM [Customers] AS [c] +ORDER BY [c].[CustomerID] DESC +"""); + } + + public override async Task Where_Order_First(bool async) + { + await base.Where_Order_First(async); + + AssertSql( + """ +SELECT [c].[CustomerID] +FROM [Customers] AS [c] +WHERE ( + SELECT TOP(1) [o].[OrderID] + FROM [Orders] AS [o] + WHERE [c].[CustomerID] = [o].[CustomerID] + ORDER BY [o].[OrderID]) = 10248 +"""); + } + private void AssertSql(params string[] expected) => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindSelectQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindSelectQuerySqlServerTest.cs index 30732589058..f8c1d6e8041 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindSelectQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindSelectQuerySqlServerTest.cs @@ -795,7 +795,7 @@ public override async Task Project_single_element_from_collection_with_OrderBy_D AssertSql( """ SELECT ( - SELECT DISTINCT TOP(1) [o].[CustomerID] + SELECT TOP(1) [o].[CustomerID] FROM [Orders] AS [o] WHERE [c].[CustomerID] = [o].[CustomerID]) FROM [Customers] AS [c] @@ -2791,7 +2791,7 @@ public override async Task Entity_passed_to_DTO_constructor_works(bool async) await base.Entity_passed_to_DTO_constructor_works(async); AssertSql( -""" + """ SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] """); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindSqlQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindSqlQuerySqlServerTest.cs index 959908d7c53..a54443c7781 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindSqlQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindSqlQuerySqlServerTest.cs @@ -11,9 +11,7 @@ public class NorthwindSqlQuerySqlServerTest : NorthwindSqlQueryTestBase fixture, ITestOutputHelper testOutputHelper) : base(fixture) - { - Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); - } + => Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); [ConditionalFact] public virtual void Check_all_tests_overridden() diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindStringIncludeQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindStringIncludeQuerySqlServerTest.cs index 81178b22899..dec936ceca5 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindStringIncludeQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindStringIncludeQuerySqlServerTest.cs @@ -10,9 +10,7 @@ public class NorthwindStringIncludeQuerySqlServerTest : NorthwindStringIncludeQu { public NorthwindStringIncludeQuerySqlServerTest(NorthwindQuerySqlServerFixture fixture) : base(fixture) - { - Fixture.TestSqlLoggerFactory.Clear(); - } + => Fixture.TestSqlLoggerFactory.Clear(); [ConditionalFact] public virtual void Check_all_tests_overridden() diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindWhereQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindWhereQuerySqlServerTest.cs index c40a5fc7c4a..132b41e85bb 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindWhereQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindWhereQuerySqlServerTest.cs @@ -2033,8 +2033,8 @@ public override async Task Enclosing_class_settable_member_generates_parameter(b FROM [Orders] AS [o] WHERE [o].[OrderID] = @__SettableProperty_0 """, - // - """ + // + """ @__SettableProperty_0='10275' SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] @@ -3356,37 +3356,37 @@ public override async Task Implicit_cast_in_predicate(bool async) await base.Implicit_cast_in_predicate(async); AssertSql( -""" + """ SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] FROM [Orders] AS [o] WHERE [o].[CustomerID] = N'1337' """, - // - """ + // + """ @__prm_Value_0='1337' (Size = 5) SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] FROM [Orders] AS [o] WHERE [o].[CustomerID] = @__prm_Value_0 """, - // - """ + // + """ @__ToString_0='1337' (Size = 5) SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] FROM [Orders] AS [o] WHERE [o].[CustomerID] = @__ToString_0 """, - // - """ + // + """ @__p_0='1337' (Size = 5) SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] FROM [Orders] AS [o] WHERE [o].[CustomerID] = @__p_0 """, - // - """ + // + """ SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] FROM [Orders] AS [o] WHERE [o].[CustomerID] = N'1337' @@ -3398,27 +3398,27 @@ public override async Task Interface_casting_though_generic_method(bool async) await base.Interface_casting_though_generic_method(async); AssertSql( -""" + """ @__id_0='10252' SELECT [o].[OrderID] AS [Id] FROM [Orders] AS [o] WHERE [o].[OrderID] = @__id_0 """, - // - """ + // + """ SELECT [o].[OrderID] AS [Id] FROM [Orders] AS [o] WHERE [o].[OrderID] = 10252 """, - // - """ + // + """ SELECT [o].[OrderID] AS [Id] FROM [Orders] AS [o] WHERE [o].[OrderID] = 10252 """, - // - """ + // + """ SELECT [o].[OrderID] AS [Id] FROM [Orders] AS [o] WHERE [o].[OrderID] = 10252 diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NullKeysSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NullKeysSqlServerTest.cs index 5108682f98a..dee8fcdfca5 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NullKeysSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NullKeysSqlServerTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class NullKeysSqlServerTest(NullKeysSqlServerTest.NullKeysSqlServerFixture fixture) : NullKeysTestBase(fixture) +public class NullKeysSqlServerTest(NullKeysSqlServerTest.NullKeysSqlServerFixture fixture) + : NullKeysTestBase(fixture) { public class NullKeysSqlServerFixture : NullKeysFixtureBase { diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NullSemanticsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NullSemanticsQuerySqlServerTest.cs index 70a2c9ced58..2581e0a3baa 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NullSemanticsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NullSemanticsQuerySqlServerTest.cs @@ -3099,8 +3099,8 @@ SELECT 1 FROM [Entities2] AS [e0] WHERE [e0].[NullableStringA] = [e].[NullableStringB] OR ([e0].[NullableStringA] IS NULL AND [e].[NullableStringB] IS NULL)) """, - // - """ + // + """ SELECT [e].[Id] FROM [Entities1] AS [e] WHERE NOT EXISTS ( diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/OptionalDependentQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/OptionalDependentQuerySqlServerTest.cs index 59d7289d21d..3249890f7cb 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/OptionalDependentQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/OptionalDependentQuerySqlServerTest.cs @@ -13,6 +13,7 @@ public OptionalDependentQuerySqlServerTest(OptionalDependentQuerySqlServerFixtur Fixture.TestSqlLoggerFactory.Clear(); Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); } + public override async Task Basic_projection_entity_with_all_optional(bool async) { await base.Basic_projection_entity_with_all_optional(async); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/OwnedEntityQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/OwnedEntityQuerySqlServerTest.cs index c70570a8c7d..5eb74c50918 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/OwnedEntityQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/OwnedEntityQuerySqlServerTest.cs @@ -319,13 +319,16 @@ public Task SeedAsync() Add( new Owner23211 { - Dependents = [new(), new()], + Dependents = [new Dependent23211(), new Dependent23211()], Owned1 = new OwnedType23211 { Value = "A" }, Owned2 = new OwnedType23211 { Value = "B" } }); Add( - new SecondOwner23211 { Dependents = [new(), new()], Owned = new OwnedType23211 { Value = "A" } }); + new SecondOwner23211 + { + Dependents = [new SecondDependent23211(), new SecondDependent23211()], Owned = new OwnedType23211 { Value = "A" } + }); return SaveChangesAsync(); } @@ -415,7 +418,6 @@ ORDER BY [p].[Id] """); } - public override async Task Owned_entity_multiple_level_in_aggregate() { await base.Owned_entity_multiple_level_in_aggregate(); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/OwnedQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/OwnedQuerySqlServerTest.cs index df65d197ba4..1e7744a2e35 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/OwnedQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/OwnedQuerySqlServerTest.cs @@ -9,9 +9,7 @@ public class OwnedQuerySqlServerTest : OwnedQueryRelationalTestBase Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); public override async Task Query_with_owned_entity_equality_operator(bool async) { diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrecompiledQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrecompiledQuerySqlServerTest.cs index 760bf5794f4..b209e80f11e 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/PrecompiledQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrecompiledQuerySqlServerTest.cs @@ -67,27 +67,27 @@ public override async Task Invoke_no_evaluatability_is_not_supported() AssertSql(); } - public override async Task ListInit_no_evaluatability() - { - await base.ListInit_no_evaluatability(); + public override async Task ListInit_no_evaluatability() + { + await base.ListInit_no_evaluatability(); - AssertSql( - """ + AssertSql( + """ SELECT [b].[Id], [b].[Id] + 1 FROM [Blogs] AS [b] """); - } + } - public override async Task ListInit_with_evaluatable_with_captured_variable() - { - await base.ListInit_with_evaluatable_with_captured_variable(); + public override async Task ListInit_with_evaluatable_with_captured_variable() + { + await base.ListInit_with_evaluatable_with_captured_variable(); - AssertSql( - """ + AssertSql( + """ SELECT [b].[Id] FROM [Blogs] AS [b] """); - } + } public override async Task ListInit_with_evaluatable_without_captured_variable() { @@ -112,17 +112,17 @@ WHERE [b].[Id] IN (7, 8) """); } - public override async Task MethodCallExpression_no_evaluatability() - { - await base.MethodCallExpression_no_evaluatability(); + public override async Task MethodCallExpression_no_evaluatability() + { + await base.MethodCallExpression_no_evaluatability(); - AssertSql( - """ + AssertSql( + """ SELECT [b].[Id], [b].[Name], [b].[Json] FROM [Blogs] AS [b] WHERE [b].[Name] IS NOT NULL AND LEFT([b].[Name], LEN([b].[Name])) = [b].[Name] """); - } + } public override async Task MethodCallExpression_with_evaluatable_with_captured_variable() { @@ -1952,7 +1952,7 @@ public override async Task Two_captured_variables_in_different_lambdas() AssertSql( """ -@__starts_0_startswith='blog%' (Size = 4000) +@__starts_0_startswith='Blog%' (Size = 4000) @__ends_1_endswith='%2' (Size = 4000) SELECT TOP(2) [b].[Id], [b].[Name], [b].[Json] @@ -2094,6 +2094,7 @@ public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder build return builder; } - public override PrecompiledQueryTestHelpers PrecompiledQueryTestHelpers => SqlServerPrecompiledQueryTestHelpers.Instance; + public override PrecompiledQueryTestHelpers PrecompiledQueryTestHelpers + => SqlServerPrecompiledQueryTestHelpers.Instance; } } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrecompiledSqlPregenerationQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrecompiledSqlPregenerationQuerySqlServerTest.cs index b187615aee8..2dee871227b 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/PrecompiledSqlPregenerationQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrecompiledSqlPregenerationQuerySqlServerTest.cs @@ -6,7 +6,6 @@ namespace Microsoft.EntityFrameworkCore.Query; // ReSharper disable InconsistentNaming - public class PrecompiledSqlPregenerationQuerySqlServerTest( PrecompiledSqlPregenerationQuerySqlServerTest.PrecompiledSqlPregenerationQuerySqlServerFixture fixture, ITestOutputHelper testOutputHelper) @@ -263,6 +262,7 @@ public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder build return builder; } - public override PrecompiledQueryTestHelpers PrecompiledQueryTestHelpers => SqlServerPrecompiledQueryTestHelpers.Instance; + public override PrecompiledQueryTestHelpers PrecompiledQueryTestHelpers + => SqlServerPrecompiledQueryTestHelpers.Instance; } } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQueryOldSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQueryOldSqlServerTest.cs index 077c136ab9a..d23ea73a1ce 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQueryOldSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQueryOldSqlServerTest.cs @@ -453,6 +453,12 @@ SELECT COUNT(*) """); } + public override Task Inline_collection_Contains_with_EF_Parameter(bool async) + => AssertCompatibilityLevelTooLow(() => base.Inline_collection_Contains_with_EF_Parameter(async)); + + public override Task Inline_collection_Count_with_column_predicate_with_EF_Parameter(bool async) + => AssertCompatibilityLevelTooLow(() => base.Inline_collection_Count_with_column_predicate_with_EF_Parameter(async)); + public override Task Parameter_collection_Count(bool async) => AssertCompatibilityLevelTooLow(() => base.Parameter_collection_Count(async)); @@ -899,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 b1159553a81..c47c00cf862 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs @@ -418,6 +418,40 @@ SELECT COUNT(*) """); } + public override async Task Inline_collection_Contains_with_EF_Parameter(bool async) + { + await base.Inline_collection_Contains_with_EF_Parameter(async); + + AssertSql( + """ +@__p_0='[2,999,1000]' (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] +WHERE [p].[Id] IN ( + SELECT [p0].[value] + FROM OPENJSON(@__p_0) WITH ([value] int '$') AS [p0] +) +"""); + } + + public override async Task Inline_collection_Count_with_column_predicate_with_EF_Parameter(bool async) + { + await base.Inline_collection_Count_with_column_predicate_with_EF_Parameter(async); + + AssertSql( + """ +@__p_0='[2,999,1000]' (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] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON(@__p_0) WITH ([value] int '$') AS [p0] + WHERE [p0].[value] > [p].[Id]) = 2 +"""); + } + public override async Task Parameter_collection_Count(bool async) { await base.Parameter_collection_Count(async); @@ -748,7 +782,7 @@ public override async Task Parameter_collection_null_Contains(bool async) FROM [PrimitiveCollectionsEntity] AS [p] WHERE [p].[Int] IN ( SELECT [i].[value] - FROM OPENJSON(NULL) AS [i] + FROM OPENJSON(NULL) WITH ([value] int '$') AS [i] ) """); } @@ -1473,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 new file mode 100644 index 00000000000..d382ca0642d --- /dev/null +++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerJsonTypeTest.cs @@ -0,0 +1,2105 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.Data.SqlClient; + +namespace Microsoft.EntityFrameworkCore.Query; + +[SqlServerCondition(SqlServerCondition.SupportsFunctions2022 | SqlServerCondition.SupportsJsonType)] +public class PrimitiveCollectionsQuerySqlServerJsonTypeTest : PrimitiveCollectionsQueryRelationalTestBase< + PrimitiveCollectionsQuerySqlServerJsonTypeTest.PrimitiveCollectionsQuerySqlServerFixture> +{ + public PrimitiveCollectionsQuerySqlServerJsonTypeTest( + PrimitiveCollectionsQuerySqlServerFixture fixture, + ITestOutputHelper testOutputHelper) + : base(fixture) + { + Fixture.TestSqlLoggerFactory.Clear(); + Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); + } + + [ConditionalFact] + public virtual void Check_all_tests_overridden() + => TestHelpers.AssertAllMethodsOverridden(GetType()); + + public override async Task Inline_collection_with_single_parameter_element_Contains(bool async) + { + await base.Inline_collection_with_single_parameter_element_Contains(async); + + AssertSql( + """ +@__i_0='2' + +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] +WHERE [p].[Id] = @__i_0 +"""); + } + + public override async Task Inline_collection_with_single_parameter_element_Count(bool async) + { + await base.Inline_collection_with_single_parameter_element_Count(async); + + AssertSql( + """ +@__i_0='2' + +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] +WHERE ( + SELECT COUNT(*) + FROM (VALUES (CAST(@__i_0 AS int))) AS [v]([Value]) + WHERE [v].[Value] > [p].[Id]) = 1 +"""); + } + + public override async Task Parameter_collection_Contains_with_EF_Constant(bool async) + { + await base.Parameter_collection_Contains_with_EF_Constant(async); + + AssertSql( + """ +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] +WHERE [p].[Id] IN (2, 999, 1000) +"""); + } + + public override async Task Parameter_collection_Where_with_EF_Constant_Where_Any(bool async) + { + await base.Parameter_collection_Where_with_EF_Constant_Where_Any(async); + + AssertSql( + """ +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] +WHERE EXISTS ( + SELECT 1 + FROM (VALUES (2), (999), (1000)) AS [i]([Value]) + WHERE [i].[Value] > 0) +"""); + } + + public override async Task Parameter_collection_Count_with_column_predicate_with_EF_Constant(bool async) + { + await base.Parameter_collection_Count_with_column_predicate_with_EF_Constant(async); + + AssertSql( + """ +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] +WHERE ( + SELECT COUNT(*) + FROM (VALUES (2), (999), (1000)) AS [i]([Value]) + WHERE [i].[Value] > [p].[Id]) = 2 +"""); + } + + public override async Task Inline_collection_of_ints_Contains(bool async) + { + await base.Inline_collection_of_ints_Contains(async); + + AssertSql( + """ +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] +WHERE [p].[Int] IN (10, 999) +"""); + } + + public override async Task Inline_collection_of_nullable_ints_Contains(bool async) + { + await base.Inline_collection_of_nullable_ints_Contains(async); + + AssertSql( + """ +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] +WHERE [p].[NullableInt] IN (10, 999) +"""); + } + + public override async Task Inline_collection_of_nullable_ints_Contains_null(bool async) + { + await base.Inline_collection_of_nullable_ints_Contains_null(async); + + AssertSql( + """ +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] +WHERE [p].[NullableInt] IS NULL OR [p].[NullableInt] = 999 +"""); + } + + public override async Task Inline_collection_Count_with_zero_values(bool async) + { + await base.Inline_collection_Count_with_zero_values(async); + + AssertSql(); + } + + public override async Task Inline_collection_Count_with_one_value(bool async) + { + await base.Inline_collection_Count_with_one_value(async); + + AssertSql( + """ +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] +WHERE ( + SELECT COUNT(*) + FROM (VALUES (CAST(2 AS int))) AS [v]([Value]) + WHERE [v].[Value] > [p].[Id]) = 1 +"""); + } + + public override async Task Inline_collection_Count_with_two_values(bool async) + { + await base.Inline_collection_Count_with_two_values(async); + + AssertSql( + """ +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] +WHERE ( + SELECT COUNT(*) + FROM (VALUES (CAST(2 AS int)), (999)) AS [v]([Value]) + WHERE [v].[Value] > [p].[Id]) = 1 +"""); + } + + public override async Task Inline_collection_Count_with_three_values(bool async) + { + await base.Inline_collection_Count_with_three_values(async); + + AssertSql( + """ +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] +WHERE ( + SELECT COUNT(*) + FROM (VALUES (CAST(2 AS int)), (999), (1000)) AS [v]([Value]) + WHERE [v].[Value] > [p].[Id]) = 2 +"""); + } + + public override async Task Inline_collection_Contains_with_zero_values(bool async) + { + await base.Inline_collection_Contains_with_zero_values(async); + + AssertSql( + """ +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] +WHERE 0 = 1 +"""); + } + + public override async Task Inline_collection_Contains_with_one_value(bool async) + { + await base.Inline_collection_Contains_with_one_value(async); + + AssertSql( + """ +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] +WHERE [p].[Id] = 2 +"""); + } + + public override async Task Inline_collection_Contains_with_two_values(bool async) + { + await base.Inline_collection_Contains_with_two_values(async); + + AssertSql( + """ +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] +WHERE [p].[Id] IN (2, 999) +"""); + } + + public override async Task Inline_collection_Contains_with_three_values(bool async) + { + await base.Inline_collection_Contains_with_three_values(async); + + AssertSql( + """ +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] +WHERE [p].[Id] IN (2, 999, 1000) +"""); + } + + public override async Task Inline_collection_Contains_with_all_parameters(bool async) + { + await base.Inline_collection_Contains_with_all_parameters(async); + + AssertSql( + """ +@__i_0='2' +@__j_1='999' + +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] +WHERE [p].[Id] IN (@__i_0, @__j_1) +"""); + } + + public override async Task Inline_collection_Contains_with_constant_and_parameter(bool async) + { + await base.Inline_collection_Contains_with_constant_and_parameter(async); + + AssertSql( + """ +@__j_0='999' + +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] +WHERE [p].[Id] IN (2, @__j_0) +"""); + } + + public override async Task Inline_collection_Contains_with_mixed_value_types(bool async) + { + await base.Inline_collection_Contains_with_mixed_value_types(async); + + AssertSql( + """ +@__i_0='11' + +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] +WHERE [p].[Int] IN (999, @__i_0, [p].[Id], [p].[Id] + [p].[Int]) +"""); + } + + public override async Task Inline_collection_List_Contains_with_mixed_value_types(bool async) + { + await base.Inline_collection_List_Contains_with_mixed_value_types(async); + + AssertSql( + """ +@__i_0='11' + +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] +WHERE [p].[Int] IN (999, @__i_0, [p].[Id], [p].[Id] + [p].[Int]) +"""); + } + + public override async Task Inline_collection_Contains_as_Any_with_predicate(bool async) + { + await base.Inline_collection_Contains_as_Any_with_predicate(async); + + AssertSql( + """ +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] +WHERE [p].[Id] IN (2, 999) +"""); + } + + public override async Task Inline_collection_negated_Contains_as_All(bool async) + { + await base.Inline_collection_negated_Contains_as_All(async); + + AssertSql( + """ +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] +WHERE [p].[Id] NOT IN (2, 999) +"""); + } + + public override async Task Inline_collection_Min_with_two_values(bool async) + { + await base.Inline_collection_Min_with_two_values(async); + + AssertSql( + """ +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] +WHERE LEAST(30, [p].[Int]) = 30 +"""); + } + + public override async Task Inline_collection_List_Min_with_two_values(bool async) + { + await base.Inline_collection_List_Min_with_two_values(async); + + AssertSql( + """ +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] +WHERE LEAST(30, [p].[Int]) = 30 +"""); + } + + public override async Task Inline_collection_Max_with_two_values(bool async) + { + await base.Inline_collection_Max_with_two_values(async); + + AssertSql( + """ +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] +WHERE GREATEST(30, [p].[Int]) = 30 +"""); + } + + public override async Task Inline_collection_List_Max_with_two_values(bool async) + { + await base.Inline_collection_List_Max_with_two_values(async); + + AssertSql( + """ +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] +WHERE GREATEST(30, [p].[Int]) = 30 +"""); + } + + public override async Task Inline_collection_Min_with_three_values(bool async) + { + await base.Inline_collection_Min_with_three_values(async); + + AssertSql( + """ +@__i_0='25' + +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] +WHERE LEAST(30, [p].[Int], @__i_0) = 25 +"""); + } + + public override async Task Inline_collection_List_Min_with_three_values(bool async) + { + await base.Inline_collection_List_Min_with_three_values(async); + + AssertSql( + """ +@__i_0='25' + +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] +WHERE LEAST(30, [p].[Int], @__i_0) = 25 +"""); + } + + public override async Task Inline_collection_Max_with_three_values(bool async) + { + await base.Inline_collection_Max_with_three_values(async); + + AssertSql( + """ +@__i_0='35' + +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] +WHERE GREATEST(30, [p].[Int], @__i_0) = 35 +"""); + } + + public override async Task Inline_collection_List_Max_with_three_values(bool async) + { + await base.Inline_collection_List_Max_with_three_values(async); + + AssertSql( + """ +@__i_0='35' + +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] +WHERE GREATEST(30, [p].[Int], @__i_0) = 35 +"""); + } + + public override async Task Inline_collection_of_nullable_value_type_Min(bool async) + { + await base.Inline_collection_of_nullable_value_type_Min(async); + + AssertSql( + """ +@__i_0='25' (Nullable = true) + +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] +WHERE LEAST(30, [p].[Int], @__i_0) = 25 +"""); + } + + public override async Task Inline_collection_of_nullable_value_type_Max(bool async) + { + await base.Inline_collection_of_nullable_value_type_Max(async); + + AssertSql( + """ +@__i_0='35' (Nullable = true) + +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] +WHERE GREATEST(30, [p].[Int], @__i_0) = 35 +"""); + } + + public override async Task Inline_collection_of_nullable_value_type_with_null_Min(bool async) + { + await base.Inline_collection_of_nullable_value_type_with_null_Min(async); + + AssertSql( + """ +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] +WHERE LEAST(30, [p].[NullableInt], NULL) = 30 +"""); + } + + public override async Task Inline_collection_of_nullable_value_type_with_null_Max(bool async) + { + await base.Inline_collection_of_nullable_value_type_with_null_Max(async); + + AssertSql( + """ +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] +WHERE GREATEST(30, [p].[NullableInt], NULL) = 30 +"""); + } + + public override async Task Parameter_collection_Count(bool async) + { + await base.Parameter_collection_Count(async); + + AssertSql( + """ +@__ids_0='[2,999]' (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] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON(@__ids_0) WITH ([value] int '$') AS [i] + WHERE [i].[value] > [p].[Id]) = 1 +"""); + } + + public override async Task Parameter_collection_of_ints_Contains_int(bool async) + { + await base.Parameter_collection_of_ints_Contains_int(async); + + AssertSql( + """ +@__ints_0='[10,999]' (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] +WHERE [p].[Int] IN ( + SELECT [i].[value] + FROM OPENJSON(@__ints_0) WITH ([value] int '$') AS [i] +) +""", + // + """ +@__ints_0='[10,999]' (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] +WHERE [p].[Int] NOT IN ( + SELECT [i].[value] + FROM OPENJSON(@__ints_0) WITH ([value] int '$') AS [i] +) +"""); + } + + public override async Task Parameter_collection_HashSet_of_ints_Contains_int(bool async) + { + await base.Parameter_collection_HashSet_of_ints_Contains_int(async); + + AssertSql( + """ +@__ints_0='[10,999]' (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] +WHERE [p].[Int] IN ( + SELECT [i].[value] + FROM OPENJSON(@__ints_0) WITH ([value] int '$') AS [i] +) +""", + // + """ +@__ints_0='[10,999]' (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] +WHERE [p].[Int] NOT IN ( + SELECT [i].[value] + FROM OPENJSON(@__ints_0) WITH ([value] int '$') AS [i] +) +"""); + } + + public override async Task Parameter_collection_of_ints_Contains_nullable_int(bool async) + { + await base.Parameter_collection_of_ints_Contains_nullable_int(async); + + AssertSql( + """ +@__ints_0='[10,999]' (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] +WHERE [p].[NullableInt] IN ( + SELECT [i].[value] + FROM OPENJSON(@__ints_0) WITH ([value] int '$') AS [i] +) +""", + // + """ +@__ints_0='[10,999]' (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] +WHERE [p].[NullableInt] NOT IN ( + SELECT [i].[value] + FROM OPENJSON(@__ints_0) WITH ([value] int '$') AS [i] +) OR [p].[NullableInt] IS NULL +"""); + } + + public override async Task Parameter_collection_of_nullable_ints_Contains_int(bool async) + { + await base.Parameter_collection_of_nullable_ints_Contains_int(async); + + AssertSql( + """ +@__nullableInts_0='[10,999]' (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] +WHERE [p].[Int] IN ( + SELECT [n].[value] + FROM OPENJSON(@__nullableInts_0) WITH ([value] int '$') AS [n] +) +""", + // + """ +@__nullableInts_0='[10,999]' (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] +WHERE [p].[Int] NOT IN ( + SELECT [n].[value] + FROM OPENJSON(@__nullableInts_0) WITH ([value] int '$') AS [n] +) +"""); + } + + public override async Task Parameter_collection_of_nullable_ints_Contains_nullable_int(bool async) + { + await base.Parameter_collection_of_nullable_ints_Contains_nullable_int(async); + + AssertSql( + """ +@__nullableInts_0_without_nulls='[999]' (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] +WHERE [p].[NullableInt] IN ( + SELECT [n].[value] + FROM OPENJSON(@__nullableInts_0_without_nulls) AS [n] +) OR [p].[NullableInt] IS NULL +""", + // + """ +@__nullableInts_0_without_nulls='[999]' (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] +WHERE [p].[NullableInt] NOT IN ( + SELECT [n].[value] + FROM OPENJSON(@__nullableInts_0_without_nulls) AS [n] +) AND [p].[NullableInt] IS NOT NULL +"""); + } + + public override async Task Parameter_collection_of_strings_Contains_string(bool async) + { + await base.Parameter_collection_of_strings_Contains_string(async); + + AssertSql( + """ +@__strings_0='["10","999"]' (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] +WHERE [p].[String] IN ( + SELECT [s].[value] + FROM OPENJSON(@__strings_0) WITH ([value] nvarchar(max) '$') AS [s] +) +""", + // + """ +@__strings_0='["10","999"]' (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] +WHERE [p].[String] NOT IN ( + SELECT [s].[value] + FROM OPENJSON(@__strings_0) WITH ([value] nvarchar(max) '$') AS [s] +) +"""); + } + + public override async Task Parameter_collection_of_strings_Contains_nullable_string(bool async) + { + await base.Parameter_collection_of_strings_Contains_nullable_string(async); + + AssertSql( + """ +@__strings_0='["10","999"]' (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] +WHERE [p].[NullableString] IN ( + SELECT [s].[value] + FROM OPENJSON(@__strings_0) WITH ([value] nvarchar(max) '$') AS [s] +) +""", + // + """ +@__strings_0='["10","999"]' (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] +WHERE [p].[NullableString] NOT IN ( + SELECT [s].[value] + FROM OPENJSON(@__strings_0) WITH ([value] nvarchar(max) '$') AS [s] +) OR [p].[NullableString] IS NULL +"""); + } + + public override async Task Parameter_collection_of_nullable_strings_Contains_string(bool async) + { + await base.Parameter_collection_of_nullable_strings_Contains_string(async); + + AssertSql( + """ +@__strings_0='["10",null]' (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] +WHERE [p].[String] IN ( + SELECT [s].[value] + FROM OPENJSON(@__strings_0) WITH ([value] nvarchar(max) '$') AS [s] +) +""", + // + """ +@__strings_0_without_nulls='["10"]' (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] +WHERE [p].[String] NOT IN ( + SELECT [s].[value] + FROM OPENJSON(@__strings_0_without_nulls) AS [s] +) +"""); + } + + public override async Task Parameter_collection_of_nullable_strings_Contains_nullable_string(bool async) + { + await base.Parameter_collection_of_nullable_strings_Contains_nullable_string(async); + + AssertSql( + """ +@__strings_0_without_nulls='["999"]' (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] +WHERE [p].[NullableString] IN ( + SELECT [s].[value] + FROM OPENJSON(@__strings_0_without_nulls) AS [s] +) OR [p].[NullableString] IS NULL +""", + // + """ +@__strings_0_without_nulls='["999"]' (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] +WHERE [p].[NullableString] NOT IN ( + SELECT [s].[value] + FROM OPENJSON(@__strings_0_without_nulls) AS [s] +) AND [p].[NullableString] IS NOT NULL +"""); + } + + public override async Task Parameter_collection_of_DateTimes_Contains(bool async) + { + await base.Parameter_collection_of_DateTimes_Contains(async); + + AssertSql( + """ +@__dateTimes_0='["2020-01-10T12:30:00Z","9999-01-01T00:00:00Z"]' (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] +WHERE [p].[DateTime] IN ( + SELECT [d].[value] + FROM OPENJSON(@__dateTimes_0) WITH ([value] datetime '$') AS [d] +) +"""); + } + + public override async Task Parameter_collection_of_bools_Contains(bool async) + { + await base.Parameter_collection_of_bools_Contains(async); + + AssertSql( + """ +@__bools_0='[true]' (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] +WHERE [p].[Bool] IN ( + SELECT [b].[value] + FROM OPENJSON(@__bools_0) WITH ([value] bit '$') AS [b] +) +"""); + } + + public override async Task Parameter_collection_of_enums_Contains(bool async) + { + await base.Parameter_collection_of_enums_Contains(async); + + AssertSql( + """ +@__enums_0='[0,3]' (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] +WHERE [p].[Enum] IN ( + SELECT [e].[value] + FROM OPENJSON(@__enums_0) WITH ([value] int '$') AS [e] +) +"""); + } + + public override async Task Parameter_collection_null_Contains(bool async) + { + await base.Parameter_collection_null_Contains(async); + + AssertSql( + """ +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] +WHERE [p].[Int] IN ( + SELECT [i].[value] + FROM OPENJSON(NULL) AS [i] +) +"""); + } + + public override async Task Column_collection_of_ints_Contains(bool async) + { + await base.Column_collection_of_ints_Contains(async); + + AssertSql( + """ +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] +WHERE 10 IN ( + SELECT [i].[value] + FROM OPENJSON(CAST([p].[Ints] AS nvarchar(max))) WITH ([value] int '$') AS [i] +) +"""); + } + + public override async Task Column_collection_of_nullable_ints_Contains(bool async) + { + await base.Column_collection_of_nullable_ints_Contains(async); + + AssertSql( + """ +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] +WHERE 10 IN ( + SELECT [n].[value] + FROM OPENJSON(CAST([p].[NullableInts] AS nvarchar(max))) WITH ([value] int '$') AS [n] +) +"""); + } + + public override async Task Column_collection_of_nullable_ints_Contains_null(bool async) + { + await base.Column_collection_of_nullable_ints_Contains_null(async); + + AssertSql( + """ +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] +WHERE EXISTS ( + SELECT 1 + FROM OPENJSON(CAST([p].[NullableInts] AS nvarchar(max))) WITH ([value] int '$') AS [n] + WHERE [n].[value] IS NULL) +"""); + } + + public override async Task Column_collection_of_strings_contains_null(bool async) + { + await base.Column_collection_of_strings_contains_null(async); + + AssertSql( + """ +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] +WHERE 0 = 1 +"""); + } + + public override async Task Column_collection_of_nullable_strings_contains_null(bool async) + { + await base.Column_collection_of_nullable_strings_contains_null(async); + + AssertSql( + """ +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] +WHERE EXISTS ( + SELECT 1 + FROM OPENJSON(CAST([p].[NullableStrings] AS nvarchar(max))) WITH ([value] nvarchar(max) '$') AS [n] + WHERE [n].[value] IS NULL) +"""); + } + + public override async Task Column_collection_of_bools_Contains(bool async) + { + await base.Column_collection_of_bools_Contains(async); + + AssertSql( + """ +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] +WHERE CAST(1 AS bit) IN ( + SELECT [b].[value] + FROM OPENJSON(CAST([p].[Bools] AS nvarchar(max))) WITH ([value] bit '$') AS [b] +) +"""); + } + + [ConditionalFact] + public virtual async Task Json_representation_of_bool_array() + { + await using var context = CreateContext(); + + Assert.Equal( + "[true,false]", + await context.Database.SqlQuery($"SELECT [Bools] AS [Value] FROM [PrimitiveCollectionsEntity] WHERE [Id] = 1") + .SingleAsync()); + } + + public override async Task Column_collection_Count_method(bool async) + { + await base.Column_collection_Count_method(async); + + AssertSql( + """ +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] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON(CAST([p].[Ints] AS nvarchar(max))) AS [i]) = 2 +"""); + } + + public override async Task Column_collection_Length(bool async) + { + await base.Column_collection_Length(async); + + AssertSql( + """ +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] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON(CAST([p].[Ints] AS nvarchar(max))) AS [i]) = 2 +"""); + } + + public override async Task Column_collection_Count_with_predicate(bool async) + { + await base.Column_collection_Count_with_predicate(async); + + AssertSql( + """ +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] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON(CAST([p].[Ints] AS nvarchar(max))) WITH ([value] int '$') AS [i] + WHERE [i].[value] > 1) = 2 +"""); + } + + public override async Task Column_collection_Where_Count(bool async) + { + await base.Column_collection_Where_Count(async); + + AssertSql( + """ +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] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON(CAST([p].[Ints] AS nvarchar(max))) WITH ([value] int '$') AS [i] + WHERE [i].[value] > 1) = 2 +"""); + } + + public override async Task Column_collection_index_int(bool async) + { + await base.Column_collection_index_int(async); + + AssertSql( + """ +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] +WHERE CAST(JSON_VALUE([p].[Ints], '$[1]') AS int) = 10 +"""); + } + + public override async Task Column_collection_index_string(bool async) + { + await base.Column_collection_index_string(async); + + AssertSql( + """ +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] +WHERE JSON_VALUE([p].[Strings], '$[1]') = N'10' +"""); + } + + public override async Task Column_collection_index_datetime(bool async) + { + await base.Column_collection_index_datetime(async); + + AssertSql( + """ +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] +WHERE CAST(JSON_VALUE([p].[DateTimes], '$[1]') AS datetime2) = '2020-01-10T12:30:00.0000000Z' +"""); + } + + public override async Task Column_collection_index_beyond_end(bool async) + { + await base.Column_collection_index_beyond_end(async); + + AssertSql( + """ +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] +WHERE CAST(JSON_VALUE([p].[Ints], '$[999]') AS int) = 10 +"""); + } + + public override async Task Nullable_reference_column_collection_index_equals_nullable_column(bool async) + { + // TODO: This test is incorrect, see #33784 + await base.Nullable_reference_column_collection_index_equals_nullable_column(async); + + AssertSql( + """ +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] +WHERE JSON_VALUE([p].[NullableStrings], '$[2]') = [p].[NullableString] OR (JSON_VALUE([p].[NullableStrings], '$[2]') IS NULL AND [p].[NullableString] IS NULL) +"""); + } + + public override async Task Non_nullable_reference_column_collection_index_equals_nullable_column(bool async) + { + await base.Non_nullable_reference_column_collection_index_equals_nullable_column(async); + + AssertSql( + """ +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] +WHERE EXISTS ( + SELECT 1 + FROM OPENJSON(CAST([p].[Strings] AS nvarchar(max))) AS [s]) AND JSON_VALUE([p].[Strings], '$[1]') = [p].[NullableString] +"""); + } + + public override async Task Inline_collection_index_Column(bool async) + { + await base.Inline_collection_index_Column(async); + + AssertSql( + """ +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] +WHERE ( + SELECT [v].[Value] + FROM (VALUES (0, CAST(1 AS int)), (1, 2), (2, 3)) AS [v]([_ord], [Value]) + ORDER BY [v].[_ord] + OFFSET [p].[Int] ROWS FETCH NEXT 1 ROWS ONLY) = 1 +"""); + } + + public override async Task Inline_collection_value_index_Column(bool async) + { + await base.Inline_collection_value_index_Column(async); + + AssertSql( + """ +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] +WHERE ( + SELECT [v].[Value] + FROM (VALUES (0, CAST(1 AS int)), (1, [p].[Int]), (2, 3)) AS [v]([_ord], [Value]) + ORDER BY [v].[_ord] + OFFSET [p].[Int] ROWS FETCH NEXT 1 ROWS ONLY) = 1 +"""); + } + + public override async Task Inline_collection_List_value_index_Column(bool async) + { + await base.Inline_collection_List_value_index_Column(async); + + AssertSql( + """ +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] +WHERE ( + SELECT [v].[Value] + FROM (VALUES (0, CAST(1 AS int)), (1, [p].[Int]), (2, 3)) AS [v]([_ord], [Value]) + ORDER BY [v].[_ord] + OFFSET [p].[Int] ROWS FETCH NEXT 1 ROWS ONLY) = 1 +"""); + } + + [SqlServerCondition(SqlServerCondition.SupportsJsonPathExpressions)] + public override async Task Parameter_collection_index_Column_equal_Column(bool async) + { + await base.Parameter_collection_index_Column_equal_Column(async); + + AssertSql( + """ +@__ints_0='[0,2,3]' (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] +WHERE CAST(JSON_VALUE(@__ints_0, '$[' + CAST([p].[Int] AS nvarchar(max)) + ']') AS int) = [p].[Int] +"""); + } + + [SqlServerCondition(SqlServerCondition.SupportsJsonPathExpressions)] + public override async Task Parameter_collection_index_Column_equal_constant(bool async) + { + await base.Parameter_collection_index_Column_equal_constant(async); + + AssertSql( + """ +@__ints_0='[1,2,3]' (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] +WHERE CAST(JSON_VALUE(@__ints_0, '$[' + CAST([p].[Int] AS nvarchar(max)) + ']') AS int) = 1 +"""); + } + + public override async Task Column_collection_ElementAt(bool async) + { + await base.Column_collection_ElementAt(async); + + AssertSql( + """ +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] +WHERE CAST(JSON_VALUE([p].[Ints], '$[1]') AS int) = 10 +"""); + } + + public override async Task Column_collection_First(bool async) + { + await base.Column_collection_First(async); + + AssertSql( + """ +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] +WHERE ( + SELECT TOP(1) CAST([i].[value] AS int) AS [value] + FROM OPENJSON(CAST([p].[Ints] AS nvarchar(max))) AS [i] + ORDER BY CAST([i].[key] AS int)) = 1 +"""); + } + + public override async Task Column_collection_FirstOrDefault(bool async) + { + await base.Column_collection_FirstOrDefault(async); + + AssertSql( + """ +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] +WHERE COALESCE(( + SELECT TOP(1) CAST([i].[value] AS int) AS [value] + FROM OPENJSON(CAST([p].[Ints] AS nvarchar(max))) AS [i] + ORDER BY CAST([i].[key] AS int)), 0) = 1 +"""); + } + + public override async Task Column_collection_Single(bool async) + { + await base.Column_collection_Single(async); + + AssertSql( + """ +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] +WHERE ( + SELECT TOP(1) CAST([i].[value] AS int) AS [value] + FROM OPENJSON(CAST([p].[Ints] AS nvarchar(max))) AS [i] + ORDER BY CAST([i].[key] AS int)) = 1 +"""); + } + + public override async Task Column_collection_SingleOrDefault(bool async) + { + await base.Column_collection_SingleOrDefault(async); + + AssertSql( + """ +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] +WHERE COALESCE(( + SELECT TOP(1) CAST([i].[value] AS int) AS [value] + FROM OPENJSON(CAST([p].[Ints] AS nvarchar(max))) AS [i] + ORDER BY CAST([i].[key] AS int)), 0) = 1 +"""); + } + + public override async Task Column_collection_Skip(bool async) + { + await base.Column_collection_Skip(async); + + AssertSql( + """ +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] +WHERE ( + SELECT COUNT(*) + FROM ( + SELECT 1 AS empty + FROM OPENJSON(CAST([p].[Ints] AS nvarchar(max))) AS [i] + ORDER BY CAST([i].[key] AS int) + OFFSET 1 ROWS + ) AS [i0]) = 2 +"""); + } + + public override async Task Column_collection_Take(bool async) + { + await base.Column_collection_Take(async); + + AssertSql( + """ +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] +WHERE 11 IN ( + SELECT TOP(2) CAST([i].[value] AS int) AS [value] + FROM OPENJSON(CAST([p].[Ints] AS nvarchar(max))) AS [i] + ORDER BY CAST([i].[key] AS int) +) +"""); + } + + public override async Task Column_collection_Skip_Take(bool async) + { + await base.Column_collection_Skip_Take(async); + + AssertSql( + """ +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] +WHERE 11 IN ( + SELECT CAST([i].[value] AS int) AS [value] + FROM OPENJSON(CAST([p].[Ints] AS nvarchar(max))) AS [i] + ORDER BY CAST([i].[key] AS int) + OFFSET 1 ROWS FETCH NEXT 2 ROWS ONLY +) +"""); + } + + public override async Task Column_collection_Where_Skip(bool async) + { + await base.Column_collection_Where_Skip(async); + + AssertSql( + """ +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] +WHERE ( + SELECT COUNT(*) + FROM ( + SELECT 1 AS empty + FROM OPENJSON(CAST([p].[Ints] AS nvarchar(max))) AS [i] + WHERE CAST([i].[value] AS int) > 1 + ORDER BY CAST([i].[key] AS int) + OFFSET 1 ROWS + ) AS [i0]) = 3 +"""); + } + + public override async Task Column_collection_Where_Take(bool async) + { + await base.Column_collection_Where_Take(async); + + AssertSql( + """ +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] +WHERE ( + SELECT COUNT(*) + FROM ( + SELECT TOP(2) 1 AS empty + FROM OPENJSON(CAST([p].[Ints] AS nvarchar(max))) AS [i] + WHERE CAST([i].[value] AS int) > 1 + ORDER BY CAST([i].[key] AS int) + ) AS [i0]) = 2 +"""); + } + + public override async Task Column_collection_Where_Skip_Take(bool async) + { + await base.Column_collection_Where_Skip_Take(async); + + AssertSql( + """ +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] +WHERE ( + SELECT COUNT(*) + FROM ( + SELECT 1 AS empty + FROM OPENJSON(CAST([p].[Ints] AS nvarchar(max))) AS [i] + WHERE CAST([i].[value] AS int) > 1 + ORDER BY CAST([i].[key] AS int) + OFFSET 1 ROWS FETCH NEXT 2 ROWS ONLY + ) AS [i0]) = 1 +"""); + } + + public override async Task Column_collection_Contains_over_subquery(bool async) + { + await base.Column_collection_Contains_over_subquery(async); + + AssertSql( + """ +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] +WHERE 11 IN ( + SELECT [i].[value] + FROM OPENJSON(CAST([p].[Ints] AS nvarchar(max))) WITH ([value] int '$') AS [i] + WHERE [i].[value] > 1 +) +"""); + } + + public override async Task Column_collection_OrderByDescending_ElementAt(bool async) + { + await base.Column_collection_OrderByDescending_ElementAt(async); + + AssertSql( + """ +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] +WHERE ( + SELECT [i].[value] + FROM OPENJSON(CAST([p].[Ints] AS nvarchar(max))) WITH ([value] int '$') AS [i] + ORDER BY [i].[value] DESC + OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY) = 111 +"""); + } + + public override async Task Column_collection_Where_ElementAt(bool async) + { + await base.Column_collection_Where_ElementAt(async); + + AssertSql( + """ +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] +WHERE ( + SELECT CAST([i].[value] AS int) AS [value] + FROM OPENJSON(CAST([p].[Ints] AS nvarchar(max))) AS [i] + WHERE CAST([i].[value] AS int) > 1 + ORDER BY CAST([i].[key] AS int) + OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY) = 11 +"""); + } + + public override async Task Column_collection_Any(bool async) + { + await base.Column_collection_Any(async); + + AssertSql( + """ +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] +WHERE EXISTS ( + SELECT 1 + FROM OPENJSON(CAST([p].[Ints] AS nvarchar(max))) AS [i]) +"""); + } + + public override async Task Column_collection_Distinct(bool async) + { + await base.Column_collection_Distinct(async); + + AssertSql( + """ +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] +WHERE ( + SELECT COUNT(*) + FROM ( + SELECT DISTINCT [i].[value] + FROM OPENJSON(CAST([p].[Ints] AS nvarchar(max))) WITH ([value] int '$') AS [i] + ) AS [i0]) = 3 +"""); + } + + public override async Task Column_collection_SelectMany(bool async) + { + await base.Column_collection_SelectMany(async); + + AssertSql( + """ +SELECT [i].[value] +FROM [PrimitiveCollectionsEntity] AS [p] +CROSS APPLY OPENJSON(CAST([p].[Ints] AS nvarchar(max))) WITH ([value] int '$') AS [i] +"""); + } + + public override async Task Column_collection_SelectMany_with_filter(bool async) + { + await base.Column_collection_SelectMany_with_filter(async); + + AssertSql( + """ +SELECT [i0].[value] +FROM [PrimitiveCollectionsEntity] AS [p] +CROSS APPLY ( + SELECT [i].[value] + FROM OPENJSON(CAST([p].[Ints] AS nvarchar(max))) WITH ([value] int '$') AS [i] + WHERE [i].[value] > 1 +) AS [i0] +"""); + } + + public override async Task Column_collection_SelectMany_with_Select_to_anonymous_type(bool async) + { + await base.Column_collection_SelectMany_with_Select_to_anonymous_type(async); + + AssertSql( + """ +SELECT [i].[value] AS [Original], [i].[value] + 1 AS [Incremented] +FROM [PrimitiveCollectionsEntity] AS [p] +CROSS APPLY OPENJSON(CAST([p].[Ints] AS nvarchar(max))) WITH ([value] int '$') AS [i] +"""); + } + + public override async Task Column_collection_projection_from_top_level(bool async) + { + await base.Column_collection_projection_from_top_level(async); + + AssertSql( + """ +SELECT [p].[Ints] +FROM [PrimitiveCollectionsEntity] AS [p] +ORDER BY [p].[Id] +"""); + } + + public override async Task Column_collection_Join_parameter_collection(bool async) + { + await base.Column_collection_Join_parameter_collection(async); + + AssertSql( + """ +@__ints_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] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON(CAST([p].[Ints] AS nvarchar(max))) WITH ([value] int '$') AS [i] + INNER JOIN OPENJSON(@__ints_0) WITH ([value] int '$') AS [i0] ON [i].[value] = [i0].[value]) = 2 +"""); + } + + public override async Task Inline_collection_Join_ordered_column_collection(bool async) + { + await base.Inline_collection_Join_ordered_column_collection(async); + + AssertSql( + """ +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] +WHERE ( + SELECT COUNT(*) + FROM (VALUES (CAST(11 AS int)), (111)) AS [v]([Value]) + INNER JOIN OPENJSON(CAST([p].[Ints] AS nvarchar(max))) WITH ([value] int '$') AS [i] ON [v].[Value] = [i].[value]) = 2 +"""); + } + + public override async Task Parameter_collection_Concat_column_collection(bool async) + { + await base.Parameter_collection_Concat_column_collection(async); + + AssertSql( + """ +@__ints_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] +WHERE ( + SELECT COUNT(*) + FROM ( + SELECT 1 AS empty + FROM OPENJSON(@__ints_0) AS [i] + UNION ALL + SELECT 1 AS empty + FROM OPENJSON(CAST([p].[Ints] AS nvarchar(max))) AS [i0] + ) AS [u]) = 2 +"""); + } + + 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); + + AssertSql( + """ +@__ints_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] +WHERE ( + SELECT COUNT(*) + FROM ( + SELECT [i].[value] + FROM OPENJSON(CAST([p].[Ints] AS nvarchar(max))) WITH ([value] int '$') AS [i] + UNION + SELECT [i0].[value] + FROM OPENJSON(@__ints_0) WITH ([value] int '$') AS [i0] + ) AS [u]) = 2 +"""); + } + + public override async Task Column_collection_Intersect_inline_collection(bool async) + { + await base.Column_collection_Intersect_inline_collection(async); + + AssertSql( + """ +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] +WHERE ( + SELECT COUNT(*) + FROM ( + SELECT [i].[value] + FROM OPENJSON(CAST([p].[Ints] AS nvarchar(max))) WITH ([value] int '$') AS [i] + INTERSECT + SELECT [v].[Value] AS [value] + FROM (VALUES (CAST(11 AS int)), (111)) AS [v]([Value]) + ) AS [i0]) = 2 +"""); + } + + public override async Task Inline_collection_Except_column_collection(bool async) + { + await base.Inline_collection_Except_column_collection(async); + + AssertSql( + """ +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] +WHERE ( + SELECT COUNT(*) + FROM ( + SELECT [v].[Value] + FROM (VALUES (CAST(11 AS int)), (111)) AS [v]([Value]) + EXCEPT + SELECT [i].[value] AS [Value] + FROM OPENJSON(CAST([p].[Ints] AS nvarchar(max))) WITH ([value] int '$') AS [i] + ) AS [e] + WHERE [e].[Value] % 2 = 1) = 2 +"""); + } + + public override async Task Column_collection_Where_Union(bool async) + { + await base.Column_collection_Where_Union(async); + + AssertSql( + """ +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] +WHERE ( + SELECT COUNT(*) + FROM ( + SELECT [i].[value] + FROM OPENJSON(CAST([p].[Ints] AS nvarchar(max))) WITH ([value] int '$') AS [i] + WHERE [i].[value] > 100 + UNION + SELECT [v].[Value] AS [value] + FROM (VALUES (CAST(50 AS int))) AS [v]([Value]) + ) AS [u]) = 2 +"""); + } + + public override async Task Column_collection_equality_parameter_collection(bool async) + { + // TODO:SQLJSON Json type is not comparable + Assert.Equal( + "The JSON data type cannot be compared or sorted, except when using the IS NULL operator.", + (await Assert.ThrowsAsync(() => base.Column_collection_equality_parameter_collection(async))).Message); + + AssertSql( + """ +@__ints_0='[1,10]' (Size = 8000) + +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] +WHERE [p].[Ints] = @__ints_0 +"""); + } + + public override async Task Column_collection_Concat_parameter_collection_equality_inline_collection(bool async) + { + await base.Column_collection_Concat_parameter_collection_equality_inline_collection(async); + + AssertSql(); + } + + public override async Task Column_collection_equality_inline_collection(bool async) + { + // TODO:SQLJSON Json type is not comparable + Assert.Equal( + "The data types json and varchar are incompatible in the equal to operator.", + (await Assert.ThrowsAsync(() => base.Column_collection_equality_inline_collection(async))).Message); + + AssertSql( + """ +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] +WHERE [p].[Ints] = '[1,10]' +"""); + } + + public override async Task Column_collection_equality_inline_collection_with_parameters(bool async) + { + await base.Column_collection_equality_inline_collection_with_parameters(async); + + AssertSql(); + } + + public override async Task Column_collection_Where_equality_inline_collection(bool async) + { + await base.Column_collection_Where_equality_inline_collection(async); + + AssertSql(); + } + + public override async Task Parameter_collection_in_subquery_Union_column_collection_as_compiled_query(bool async) + { + await base.Parameter_collection_in_subquery_Union_column_collection_as_compiled_query(async); + + AssertSql( + """ +@__ints='[10,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] +WHERE ( + SELECT COUNT(*) + FROM ( + SELECT [i1].[value] + FROM ( + SELECT CAST([i].[value] AS int) AS [value] + FROM OPENJSON(@__ints) AS [i] + ORDER BY CAST([i].[key] AS int) + OFFSET 1 ROWS + ) AS [i1] + UNION + SELECT [i0].[value] + FROM OPENJSON(CAST([p].[Ints] AS nvarchar(max))) WITH ([value] int '$') AS [i0] + ) AS [u]) = 3 +"""); + } + + public override async Task Parameter_collection_in_subquery_Union_column_collection(bool async) + { + await base.Parameter_collection_in_subquery_Union_column_collection(async); + + AssertSql( + """ +@__Skip_0='[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] +WHERE ( + SELECT COUNT(*) + FROM ( + SELECT [s].[value] + FROM OPENJSON(@__Skip_0) WITH ([value] int '$') AS [s] + UNION + SELECT [i].[value] + FROM OPENJSON(CAST([p].[Ints] AS nvarchar(max))) WITH ([value] int '$') AS [i] + ) AS [u]) = 3 +"""); + } + + public override async Task Parameter_collection_in_subquery_Union_column_collection_nested(bool async) + { + await base.Parameter_collection_in_subquery_Union_column_collection_nested(async); + + AssertSql( + """ +@__Skip_0='[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] +WHERE ( + SELECT COUNT(*) + FROM ( + SELECT [s].[value] + FROM OPENJSON(@__Skip_0) WITH ([value] int '$') AS [s] + UNION + SELECT [i2].[value] + FROM ( + SELECT TOP(20) [i1].[value] + FROM ( + SELECT DISTINCT [i0].[value] + FROM ( + SELECT [i].[value] + FROM OPENJSON(CAST([p].[Ints] AS nvarchar(max))) WITH ([value] int '$') AS [i] + ORDER BY [i].[value] + OFFSET 1 ROWS + ) AS [i0] + ) AS [i1] + ORDER BY [i1].[value] DESC + ) AS [i2] + ) AS [u]) = 3 +"""); + } + + public override void Parameter_collection_in_subquery_and_Convert_as_compiled_query() + { + base.Parameter_collection_in_subquery_and_Convert_as_compiled_query(); + + AssertSql(); + } + + public override async Task Parameter_collection_in_subquery_Count_as_compiled_query(bool async) + { + await base.Parameter_collection_in_subquery_Count_as_compiled_query(async); + + // TODO: the subquery projection contains extra columns which we should remove + AssertSql( + """ +@__ints='[10,111]' (Size = 4000) + +SELECT COUNT(*) +FROM [PrimitiveCollectionsEntity] AS [p] +WHERE ( + SELECT COUNT(*) + FROM ( + SELECT CAST([i].[value] AS int) AS [value0] + FROM OPENJSON(@__ints) AS [i] + ORDER BY CAST([i].[key] AS int) + OFFSET 1 ROWS + ) AS [i0] + WHERE [i0].[value0] > [p].[Id]) = 1 +"""); + } + + public override async Task Parameter_collection_in_subquery_Union_another_parameter_collection_as_compiled_query(bool async) + { + await base.Parameter_collection_in_subquery_Union_another_parameter_collection_as_compiled_query(async); + + AssertSql(); + } + + public override async Task Column_collection_in_subquery_Union_parameter_collection(bool async) + { + await base.Column_collection_in_subquery_Union_parameter_collection(async); + + AssertSql( + """ +@__ints_0='[10,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] +WHERE ( + SELECT COUNT(*) + FROM ( + SELECT [i1].[value] + FROM ( + SELECT CAST([i].[value] AS int) AS [value] + FROM OPENJSON(CAST([p].[Ints] AS nvarchar(max))) AS [i] + ORDER BY CAST([i].[key] AS int) + OFFSET 1 ROWS + ) AS [i1] + UNION + SELECT [i0].[value] + FROM OPENJSON(@__ints_0) WITH ([value] int '$') AS [i0] + ) AS [u]) = 3 +"""); + } + + public override async Task Project_collection_of_ints_simple(bool async) + { + await base.Project_collection_of_ints_simple(async); + + AssertSql( + """ +SELECT [p].[Ints] +FROM [PrimitiveCollectionsEntity] AS [p] +ORDER BY [p].[Id] +"""); + } + + public override async Task Project_collection_of_ints_ordered(bool async) + { + await base.Project_collection_of_ints_ordered(async); + + AssertSql( + """ +SELECT [p].[Id], CAST([i].[value] AS int) AS [value], [i].[key] +FROM [PrimitiveCollectionsEntity] AS [p] +OUTER APPLY OPENJSON(CAST([p].[Ints] AS nvarchar(max))) AS [i] +ORDER BY [p].[Id], CAST([i].[value] AS int) DESC +"""); + } + + public override async Task Project_collection_of_datetimes_filtered(bool async) + { + await base.Project_collection_of_datetimes_filtered(async); + + AssertSql( + """ +SELECT [p].[Id], [d0].[value], [d0].[key] +FROM [PrimitiveCollectionsEntity] AS [p] +OUTER APPLY ( + SELECT CAST([d].[value] AS datetime2) AS [value], [d].[key], CAST([d].[key] AS int) AS [c] + FROM OPENJSON(CAST([p].[DateTimes] AS nvarchar(max))) AS [d] + WHERE DATEPART(day, CAST([d].[value] AS datetime2)) <> 1 +) AS [d0] +ORDER BY [p].[Id], [d0].[c] +"""); + } + + public override async Task Project_collection_of_nullable_ints_with_paging(bool async) + { + await base.Project_collection_of_nullable_ints_with_paging(async); + + AssertSql( + """ +SELECT [p].[Id], [n0].[value], [n0].[key] +FROM [PrimitiveCollectionsEntity] AS [p] +OUTER APPLY ( + SELECT TOP(20) CAST([n].[value] AS int) AS [value], [n].[key], CAST([n].[key] AS int) AS [c] + FROM OPENJSON(CAST([p].[NullableInts] AS nvarchar(max))) AS [n] + ORDER BY CAST([n].[key] AS int) +) AS [n0] +ORDER BY [p].[Id], [n0].[c] +"""); + } + + public override async Task Project_collection_of_nullable_ints_with_paging2(bool async) + { + await base.Project_collection_of_nullable_ints_with_paging2(async); + + AssertSql( + """ +SELECT [p].[Id], [n0].[value], [n0].[key] +FROM [PrimitiveCollectionsEntity] AS [p] +OUTER APPLY ( + SELECT CAST([n].[value] AS int) AS [value], [n].[key] + FROM OPENJSON(CAST([p].[NullableInts] AS nvarchar(max))) AS [n] + ORDER BY CAST([n].[value] AS int) + OFFSET 1 ROWS +) AS [n0] +ORDER BY [p].[Id], [n0].[value] +"""); + } + + public override async Task Project_collection_of_nullable_ints_with_paging3(bool async) + { + await base.Project_collection_of_nullable_ints_with_paging3(async); + + AssertSql( + """ +SELECT [p].[Id], [n0].[value], [n0].[key] +FROM [PrimitiveCollectionsEntity] AS [p] +OUTER APPLY ( + SELECT CAST([n].[value] AS int) AS [value], [n].[key], CAST([n].[key] AS int) AS [c] + FROM OPENJSON(CAST([p].[NullableInts] AS nvarchar(max))) AS [n] + ORDER BY CAST([n].[key] AS int) + OFFSET 2 ROWS +) AS [n0] +ORDER BY [p].[Id], [n0].[c] +"""); + } + + public override async Task Project_collection_of_ints_with_distinct(bool async) + { + await base.Project_collection_of_ints_with_distinct(async); + + AssertSql( + """ +SELECT [p].[Id], [i0].[value] +FROM [PrimitiveCollectionsEntity] AS [p] +OUTER APPLY ( + SELECT DISTINCT [i].[value] + FROM OPENJSON(CAST([p].[Ints] AS nvarchar(max))) WITH ([value] int '$') AS [i] +) AS [i0] +ORDER BY [p].[Id] +"""); + } + + public override async Task Project_collection_of_nullable_ints_with_distinct(bool async) + { + await base.Project_collection_of_nullable_ints_with_distinct(async); + + AssertSql(""); + } + + public override async Task Project_collection_of_ints_with_ToList_and_FirstOrDefault(bool async) + { + await base.Project_collection_of_ints_with_ToList_and_FirstOrDefault(async); + + AssertSql( + """ +SELECT [p0].[Id], CAST([i].[value] AS int) AS [value], [i].[key] +FROM ( + SELECT TOP(1) [p].[Id], [p].[Ints] + FROM [PrimitiveCollectionsEntity] AS [p] + ORDER BY [p].[Id] +) AS [p0] +OUTER APPLY OPENJSON(CAST([p0].[Ints] AS nvarchar(max))) AS [i] +ORDER BY [p0].[Id], CAST([i].[key] AS int) +"""); + } + + public override async Task Project_empty_collection_of_nullables_and_collection_only_containing_nulls(bool async) + { + await base.Project_empty_collection_of_nullables_and_collection_only_containing_nulls(async); + + AssertSql( + """ +SELECT [p].[Id], [n1].[value], [n1].[key], [n2].[value], [n2].[key] +FROM [PrimitiveCollectionsEntity] AS [p] +OUTER APPLY ( + SELECT CAST([n].[value] AS int) AS [value], [n].[key], CAST([n].[key] AS int) AS [c] + FROM OPENJSON(CAST([p].[NullableInts] AS nvarchar(max))) AS [n] + WHERE 0 = 1 +) AS [n1] +OUTER APPLY ( + SELECT CAST([n0].[value] AS int) AS [value], [n0].[key], CAST([n0].[key] AS int) AS [c] + FROM OPENJSON(CAST([p].[NullableInts] AS nvarchar(max))) AS [n0] + WHERE [n0].[value] IS NULL +) AS [n2] +ORDER BY [p].[Id], [n1].[c], [n1].[key], [n2].[c] +"""); + } + + public override async Task Project_multiple_collections(bool async) + { + await base.Project_multiple_collections(async); + + AssertSql( + """ +SELECT [p].[Id], CAST([i].[value] AS int) AS [value], [i].[key], CAST([i0].[value] AS int) AS [value], [i0].[key], [d1].[value], [d1].[key], [d2].[value], [d2].[key] +FROM [PrimitiveCollectionsEntity] AS [p] +OUTER APPLY OPENJSON(CAST([p].[Ints] AS nvarchar(max))) AS [i] +OUTER APPLY OPENJSON(CAST([p].[Ints] AS nvarchar(max))) AS [i0] +OUTER APPLY ( + SELECT CAST([d].[value] AS datetime2) AS [value], [d].[key], CAST([d].[key] AS int) AS [c] + FROM OPENJSON(CAST([p].[DateTimes] AS nvarchar(max))) AS [d] + WHERE DATEPART(day, CAST([d].[value] AS datetime2)) <> 1 +) AS [d1] +OUTER APPLY ( + SELECT CAST([d0].[value] AS datetime2) AS [value], [d0].[key], CAST([d0].[key] AS int) AS [c] + FROM OPENJSON(CAST([p].[DateTimes] AS nvarchar(max))) AS [d0] + WHERE CAST([d0].[value] AS datetime2) > '2000-01-01T00:00:00.0000000' +) AS [d2] +ORDER BY [p].[Id], CAST([i].[key] AS int), [i].[key], CAST([i0].[value] AS int) DESC, [i0].[key], [d1].[c], [d1].[key], [d2].[c] +"""); + } + + public override async Task Project_primitive_collections_element(bool async) + { + await base.Project_primitive_collections_element(async); + + AssertSql( + """ +SELECT CAST(JSON_VALUE([p].[Ints], '$[0]') AS int) AS [Indexer], CAST(JSON_VALUE([p].[DateTimes], '$[0]') AS datetime2) AS [EnumerableElementAt], JSON_VALUE([p].[Strings], '$[1]') AS [QueryableElementAt] +FROM [PrimitiveCollectionsEntity] AS [p] +WHERE [p].[Id] < 4 +ORDER BY [p].[Id] +"""); + } + + public override async Task Project_inline_collection(bool async) + { + await base.Project_inline_collection(async); + + AssertSql( + """ +SELECT [p].[String] +FROM [PrimitiveCollectionsEntity] AS [p] +"""); + } + + public override async Task Project_inline_collection_with_Union(bool async) + { + await base.Project_inline_collection_with_Union(async); + + AssertSql( + """ +SELECT [p].[Id], [u].[Value] +FROM [PrimitiveCollectionsEntity] AS [p] +OUTER APPLY ( + SELECT [v].[Value] + FROM (VALUES ([p].[String])) AS [v]([Value]) + UNION + SELECT [p0].[String] AS [Value] + FROM [PrimitiveCollectionsEntity] AS [p0] +) AS [u] +ORDER BY [p].[Id] +"""); + } + + public override async Task Project_inline_collection_with_Concat(bool async) + { + await base.Project_inline_collection_with_Concat(async); + + AssertSql(); + } + + public override async Task Nested_contains_with_Lists_and_no_inferred_type_mapping(bool async) + { + await base.Nested_contains_with_Lists_and_no_inferred_type_mapping(async); + + AssertSql( + """ +@__ints_0='[1,2,3]' (Size = 4000) +@__strings_1='["one","two","three"]' (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] +WHERE CASE + WHEN [p].[Int] IN ( + SELECT [i].[value] + FROM OPENJSON(@__ints_0) WITH ([value] int '$') AS [i] + ) THEN N'one' + ELSE N'two' +END IN ( + SELECT [s].[value] + FROM OPENJSON(@__strings_1) WITH ([value] nvarchar(max) '$') AS [s] +) +"""); + } + + public override async Task Nested_contains_with_arrays_and_no_inferred_type_mapping(bool async) + { + await base.Nested_contains_with_arrays_and_no_inferred_type_mapping(async); + + AssertSql( + """ +@__ints_0='[1,2,3]' (Size = 4000) +@__strings_1='["one","two","three"]' (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] +WHERE CASE + WHEN [p].[Int] IN ( + SELECT [i].[value] + FROM OPENJSON(@__ints_0) WITH ([value] int '$') AS [i] + ) THEN N'one' + ELSE N'two' +END IN ( + SELECT [s].[value] + FROM OPENJSON(@__strings_1) WITH ([value] nvarchar(max) '$') AS [s] +) +"""); + } + + private void AssertSql(params string[] expected) + => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); + + private PrimitiveCollectionsContext CreateContext() + => Fixture.CreateContext(); + + public class PrimitiveCollectionsQuerySqlServerFixture : PrimitiveCollectionsQueryFixtureBase, ITestSqlLoggerFactory + { + protected override string StoreName + => "PrimitiveCollectionsJsonTypeTest"; + + public TestSqlLoggerFactory TestSqlLoggerFactory + => (TestSqlLoggerFactory)ListLoggerFactory; + + protected override ITestStoreFactory TestStoreFactory + => SqlServerTestStoreFactory.Instance; + + public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) + => base.AddOptions(builder) + .UseSqlServer(b => b.UseCompatibilityLevel(160)) + .ConfigureWarnings(e => e.Log(SqlServerEventId.JsonTypeExperimental)); + + protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) + { + base.OnModelCreating(modelBuilder, context); + + modelBuilder.Entity( + b => + { + // Map DateTime to non-default datetime instead of the default datetime2 to exercise type mapping inference + b.Property(p => p.DateTime).HasColumnType("datetime"); + b.PrimitiveCollection(e => e.Strings).HasColumnType("json"); + b.PrimitiveCollection(e => e.Ints).HasColumnType("json"); + b.PrimitiveCollection(e => e.DateTimes).HasColumnType("json"); + b.PrimitiveCollection(e => e.Bools).HasColumnType("json"); + b.PrimitiveCollection(e => e.Ints).HasColumnType("json"); + b.PrimitiveCollection(e => e.Enums).HasColumnType("json"); + b.PrimitiveCollection(e => e.NullableStrings).HasColumnType("json"); + b.PrimitiveCollection(e => e.NullableInts).HasColumnType("json"); + }); + } + } +} diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs index d99fb9ea774..3575a954aa7 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs @@ -441,6 +441,40 @@ SELECT COUNT(*) """); } + public override async Task Inline_collection_Contains_with_EF_Parameter(bool async) + { + await base.Inline_collection_Contains_with_EF_Parameter(async); + + AssertSql( + """ +@__p_0='[2,999,1000]' (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] +WHERE [p].[Id] IN ( + SELECT [p0].[value] + FROM OPENJSON(@__p_0) WITH ([value] int '$') AS [p0] +) +"""); + } + + public override async Task Inline_collection_Count_with_column_predicate_with_EF_Parameter(bool async) + { + await base.Inline_collection_Count_with_column_predicate_with_EF_Parameter(async); + + AssertSql( + """ +@__p_0='[2,999,1000]' (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] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON(@__p_0) WITH ([value] int '$') AS [p0] + WHERE [p0].[value] > [p].[Id]) = 2 +"""); + } + public override async Task Parameter_collection_Count(bool async) { await base.Parameter_collection_Count(async); @@ -771,7 +805,7 @@ public override async Task Parameter_collection_null_Contains(bool async) FROM [PrimitiveCollectionsEntity] AS [p] WHERE [p].[Int] IN ( SELECT [i].[value] - FROM OPENJSON(NULL) AS [i] + FROM OPENJSON(NULL) WITH ([value] int '$') AS [i] ) """); } @@ -1496,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/Query/QueryFilterFuncletizationSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/QueryFilterFuncletizationSqlServerTest.cs index fed02c68159..6f5be4c633e 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/QueryFilterFuncletizationSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/QueryFilterFuncletizationSqlServerTest.cs @@ -100,7 +100,7 @@ public override void DbContext_list_is_parameterized() FROM [ListFilter] AS [l] WHERE [l].[Tenant] IN ( SELECT [e].[value] - FROM OPENJSON(NULL) AS [e] + FROM OPENJSON(NULL) WITH ([value] int '$') AS [e] ) """, // diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/QueryNoClientEvalSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/QueryNoClientEvalSqlServerTest.cs index 47c6dc2580c..7a2c7756c13 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/QueryNoClientEvalSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/QueryNoClientEvalSqlServerTest.cs @@ -5,4 +5,5 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class QueryNoClientEvalSqlServerTest(NorthwindQuerySqlServerFixture fixture) : QueryNoClientEvalTestBase>(fixture); +public class QueryNoClientEvalSqlServerTest(NorthwindQuerySqlServerFixture fixture) + : QueryNoClientEvalTestBase>(fixture); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/SqlQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/SqlQuerySqlServerTest.cs index 5d03c225058..6162a35617d 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/SqlQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/SqlQuerySqlServerTest.cs @@ -11,9 +11,7 @@ public class SqlQuerySqlServerTest : SqlQueryTestBase fixture, ITestOutputHelper testOutputHelper) : base(fixture) - { - Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); - } + => Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); public override async Task SqlQueryRaw_queryable_simple(bool async) { @@ -456,7 +454,7 @@ public override async Task SqlQueryRaw_composed_with_predicate(bool async) await base.SqlQueryRaw_composed_with_predicate(async); AssertSql( -""" + """ SELECT [m].[Address], [m].[City], [m].[CompanyName], [m].[ContactName], [m].[ContactTitle], [m].[Country], [m].[CustomerID], [m].[Fax], [m].[Phone], [m].[Region], [m].[PostalCode] FROM ( SELECT * FROM "Customers" diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs index 5f691f3504a..160949226d5 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs @@ -896,7 +896,7 @@ public override async Task Where_enum_has_flag_subquery_with_pushdown(bool async await base.Where_enum_has_flag_subquery_with_pushdown(async); AssertSql( -""" + """ SELECT [u].[Nickname], [u].[SquadId], [u].[AssignedCityName], [u].[CityOfBirthName], [u].[FullName], [u].[HasSoulPatch], [u].[LeaderNickname], [u].[LeaderSquadId], [u].[Rank], [u].[Discriminator] FROM ( SELECT [g].[Nickname], [g].[SquadId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[Rank], N'Gear' AS [Discriminator] @@ -934,8 +934,8 @@ FROM [Officers] AS [o0] ) AS [u0] ORDER BY [u0].[Nickname], [u0].[SquadId]) IS NULL """, - // - """ + // + """ SELECT [u].[Nickname], [u].[SquadId], [u].[AssignedCityName], [u].[CityOfBirthName], [u].[FullName], [u].[HasSoulPatch], [u].[LeaderNickname], [u].[LeaderSquadId], [u].[Rank], [u].[Discriminator] FROM ( SELECT [g].[Nickname], [g].[SquadId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[Rank], N'Gear' AS [Discriminator] @@ -2230,7 +2230,7 @@ UNION ALL FROM [Officers] AS [o] ) AS [u] WHERE [u].[HasSoulPatch] = CAST(1 AS bit) AND COALESCE(( - SELECT DISTINCT TOP(1) [w].[IsAutomatic] + SELECT TOP(1) [w].[IsAutomatic] FROM [Weapons] AS [w] WHERE [u].[FullName] = [w].[OwnerFullName] AND [w].[Name] LIKE N'%Lancer%'), CAST(0 AS bit)) = CAST(1 AS bit) ORDER BY [u].[Nickname] @@ -5408,7 +5408,7 @@ public override async Task ToString_nullable_enum_property_projection(bool async await base.ToString_nullable_enum_property_projection(async); AssertSql( -""" + """ SELECT CASE [w].[AmmunitionType] WHEN 1 THEN N'Cartridge' WHEN 2 THEN N'Shell' @@ -5423,7 +5423,7 @@ public override async Task ToString_enum_contains(bool async) await base.ToString_enum_contains(async); AssertSql( -""" + """ SELECT [m].[CodeName] FROM [Missions] AS [m] WHERE CAST([m].[Difficulty] AS nvarchar(max)) LIKE N'%Med%' @@ -5435,7 +5435,7 @@ public override async Task ToString_nullable_enum_contains(bool async) await base.ToString_nullable_enum_contains(async); AssertSql( -""" + """ SELECT [w].[Name] FROM [Weapons] AS [w] WHERE CASE [w].[AmmunitionType] @@ -7957,7 +7957,7 @@ public override async Task Select_subquery_distinct_singleordefault_boolean2(boo AssertSql( """ SELECT COALESCE(( - SELECT DISTINCT TOP(1) [w].[IsAutomatic] + SELECT TOP(1) [w].[IsAutomatic] FROM [Weapons] AS [w] WHERE [u].[FullName] = [w].[OwnerFullName] AND [w].[Name] LIKE N'%Lancer%'), CAST(0 AS bit)) FROM ( @@ -8026,7 +8026,7 @@ public override async Task Select_subquery_distinct_singleordefault_boolean_empt AssertSql( """ SELECT COALESCE(( - SELECT DISTINCT TOP(1) [w].[IsAutomatic] + SELECT TOP(1) [w].[IsAutomatic] FROM [Weapons] AS [w] WHERE [u].[FullName] = [w].[OwnerFullName] AND [w].[Name] = N'BFG'), CAST(0 AS bit)) FROM ( @@ -11854,7 +11854,7 @@ public override async Task Where_TimeOnly_FromDateTime_compared_to_property(bool await base.Where_TimeOnly_FromDateTime_compared_to_property(async); AssertSql( -""" + """ SELECT [t].[Id] AS [TagId], [m].[Id] AS [MissionId] FROM [Tags] AS [t] CROSS JOIN [Missions] AS [m] @@ -11867,7 +11867,7 @@ public override async Task Where_TimeOnly_FromDateTime_compared_to_parameter(boo await base.Where_TimeOnly_FromDateTime_compared_to_parameter(async); AssertSql( -""" + """ @__time_0='02:00' (DbType = Time) SELECT [t].[Id], [t].[GearNickName], [t].[GearSquadId], [t].[IssueDate], [t].[Note] @@ -11888,7 +11888,7 @@ public override async Task Where_TimeOnly_FromDateTime_compared_to_constant(bool await base.Where_TimeOnly_FromDateTime_compared_to_constant(async); AssertSql( -""" + """ SELECT [t].[Id], [t].[GearNickName], [t].[GearSquadId], [t].[IssueDate], [t].[Note] FROM [Tags] AS [t] WHERE CAST(DATEADD(hour, CAST(CAST(CAST(LEN([t].[Note]) AS int) AS float) AS int), [t].[IssueDate]) AS time) > '09:00:00' @@ -11900,7 +11900,7 @@ public override async Task Where_TimeOnly_FromTimeSpan_compared_to_property(bool await base.Where_TimeOnly_FromTimeSpan_compared_to_property(async); AssertSql( -""" + """ SELECT [m].[Id], [m].[CodeName], [m].[Date], [m].[Difficulty], [m].[Duration], [m].[Rating], [m].[Time], [m].[Timeline] FROM [Missions] AS [m] WHERE CAST([m].[Duration] AS time) < [m].[Time] @@ -11912,7 +11912,7 @@ public override async Task Where_TimeOnly_FromTimeSpan_compared_to_parameter(boo await base.Where_TimeOnly_FromTimeSpan_compared_to_parameter(async); AssertSql( -""" + """ @__time_0='01:02' (DbType = Time) SELECT [m].[Id], [m].[CodeName], [m].[Date], [m].[Difficulty], [m].[Duration], [m].[Rating], [m].[Time], [m].[Timeline] @@ -11926,7 +11926,7 @@ public override async Task Order_by_TimeOnly_FromTimeSpan(bool async) await base.Order_by_TimeOnly_FromTimeSpan(async); AssertSql( -""" + """ SELECT [m].[Id], [m].[CodeName], [m].[Date], [m].[Difficulty], [m].[Duration], [m].[Rating], [m].[Time], [m].[Timeline] FROM [Missions] AS [m] ORDER BY CAST([m].[Duration] AS time) @@ -11938,7 +11938,7 @@ public override async Task Where_DateOnly_FromDateTime_compared_to_property(bool await base.Where_DateOnly_FromDateTime_compared_to_property(async); AssertSql( -""" + """ SELECT [t].[Id] AS [TagId], [m].[Id] AS [MissionId] FROM [Tags] AS [t] CROSS JOIN [Missions] AS [m] @@ -11951,7 +11951,7 @@ public override async Task Where_DateOnly_FromDateTime_compared_to_constant_and_ await base.Where_DateOnly_FromDateTime_compared_to_constant_and_parameter(async); AssertSql( -""" + """ @__prm_0='10/11/0002' (DbType = Date) SELECT [t].[Id], [t].[GearNickName], [t].[GearSquadId], [t].[IssueDate], [t].[Note] diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPCInheritanceQueryHiLoSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPCInheritanceQueryHiLoSqlServerTest.cs index 6f53963afed..a7eb9d6b4eb 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TPCInheritanceQueryHiLoSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPCInheritanceQueryHiLoSqlServerTest.cs @@ -5,4 +5,5 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class TPCInheritanceQueryHiLoSqlServerTest(TPCInheritanceQueryHiLoSqlServerFixture fixture, ITestOutputHelper testOutputHelper) : TPCInheritanceQuerySqlServerTestBase(fixture, testOutputHelper); +public class TPCInheritanceQueryHiLoSqlServerTest(TPCInheritanceQueryHiLoSqlServerFixture fixture, ITestOutputHelper testOutputHelper) + : TPCInheritanceQuerySqlServerTestBase(fixture, testOutputHelper); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPCInheritanceQuerySqlServerFixture.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPCInheritanceQuerySqlServerFixture.cs index 3e1b6e9421f..c2a392dfe07 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TPCInheritanceQuerySqlServerFixture.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPCInheritanceQuerySqlServerFixture.cs @@ -3,6 +3,4 @@ namespace Microsoft.EntityFrameworkCore.Query; -#nullable disable - public class TPCInheritanceQuerySqlServerFixture : TPCInheritanceQuerySqlServerFixtureBase; diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPCInheritanceQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPCInheritanceQuerySqlServerTest.cs index a9dcec25621..e123f45edae 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TPCInheritanceQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPCInheritanceQuerySqlServerTest.cs @@ -7,4 +7,5 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class TPCInheritanceQuerySqlServerTest(TPCInheritanceQuerySqlServerFixture fixture, ITestOutputHelper testOutputHelper) : TPCInheritanceQuerySqlServerTestBase(fixture, testOutputHelper); +public class TPCInheritanceQuerySqlServerTest(TPCInheritanceQuerySqlServerFixture fixture, ITestOutputHelper testOutputHelper) + : TPCInheritanceQuerySqlServerTestBase(fixture, testOutputHelper); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPTGearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPTGearsOfWarQuerySqlServerTest.cs index 060ffae67ed..9420310aecc 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TPTGearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPTGearsOfWarQuerySqlServerTest.cs @@ -1859,7 +1859,7 @@ END AS [Discriminator] FROM [Gears] AS [g] LEFT JOIN [Officers] AS [o] ON [g].[Nickname] = [o].[Nickname] AND [g].[SquadId] = [o].[SquadId] WHERE [g].[HasSoulPatch] = CAST(1 AS bit) AND COALESCE(( - SELECT DISTINCT TOP(1) [w].[IsAutomatic] + SELECT TOP(1) [w].[IsAutomatic] FROM [Weapons] AS [w] WHERE [g].[FullName] = [w].[OwnerFullName] AND [w].[Name] LIKE N'%Lancer%'), CAST(0 AS bit)) = CAST(1 AS bit) ORDER BY [g].[Nickname] @@ -4680,7 +4680,7 @@ public override async Task ToString_nullable_enum_property_projection(bool async await base.ToString_nullable_enum_property_projection(async); AssertSql( -""" + """ SELECT CASE [w].[AmmunitionType] WHEN 1 THEN N'Cartridge' WHEN 2 THEN N'Shell' @@ -4707,7 +4707,7 @@ public override async Task ToString_nullable_enum_contains(bool async) await base.ToString_nullable_enum_contains(async); AssertSql( -""" + """ SELECT [w].[Name] FROM [Weapons] AS [w] WHERE CASE [w].[AmmunitionType] @@ -6678,7 +6678,7 @@ public override async Task Select_subquery_distinct_singleordefault_boolean2(boo AssertSql( """ SELECT COALESCE(( - SELECT DISTINCT TOP(1) [w].[IsAutomatic] + SELECT TOP(1) [w].[IsAutomatic] FROM [Weapons] AS [w] WHERE [g].[FullName] = [w].[OwnerFullName] AND [w].[Name] LIKE N'%Lancer%'), CAST(0 AS bit)) FROM [Gears] AS [g] @@ -6729,7 +6729,7 @@ public override async Task Select_subquery_distinct_singleordefault_boolean_empt AssertSql( """ SELECT COALESCE(( - SELECT DISTINCT TOP(1) [w].[IsAutomatic] + SELECT TOP(1) [w].[IsAutomatic] FROM [Weapons] AS [w] WHERE [g].[FullName] = [w].[OwnerFullName] AND [w].[Name] = N'BFG'), CAST(0 AS bit)) FROM [Gears] AS [g] @@ -10070,7 +10070,7 @@ public override async Task Where_TimeOnly_FromDateTime_compared_to_property(bool await base.Where_TimeOnly_FromDateTime_compared_to_property(async); AssertSql( -""" + """ SELECT [t].[Id] AS [TagId], [m].[Id] AS [MissionId] FROM [Tags] AS [t] CROSS JOIN [Missions] AS [m] @@ -10083,7 +10083,7 @@ public override async Task Where_TimeOnly_FromDateTime_compared_to_parameter(boo await base.Where_TimeOnly_FromDateTime_compared_to_parameter(async); AssertSql( -""" + """ @__time_0='02:00' (DbType = Time) SELECT [t].[Id], [t].[GearNickName], [t].[GearSquadId], [t].[IssueDate], [t].[Note] @@ -10101,7 +10101,7 @@ public override async Task Where_TimeOnly_FromDateTime_compared_to_constant(bool await base.Where_TimeOnly_FromDateTime_compared_to_constant(async); AssertSql( -""" + """ SELECT [t].[Id], [t].[GearNickName], [t].[GearSquadId], [t].[IssueDate], [t].[Note] FROM [Tags] AS [t] WHERE CAST(DATEADD(hour, CAST(CAST(CAST(LEN([t].[Note]) AS int) AS float) AS int), [t].[IssueDate]) AS time) > '09:00:00' @@ -10113,7 +10113,7 @@ public override async Task Where_TimeOnly_FromTimeSpan_compared_to_property(bool await base.Where_TimeOnly_FromTimeSpan_compared_to_property(async); AssertSql( -""" + """ SELECT [m].[Id], [m].[CodeName], [m].[Date], [m].[Difficulty], [m].[Duration], [m].[Rating], [m].[Time], [m].[Timeline] FROM [Missions] AS [m] WHERE CAST([m].[Duration] AS time) < [m].[Time] @@ -10125,7 +10125,7 @@ public override async Task Where_TimeOnly_FromTimeSpan_compared_to_parameter(boo await base.Where_TimeOnly_FromTimeSpan_compared_to_parameter(async); AssertSql( -""" + """ @__time_0='01:02' (DbType = Time) SELECT [m].[Id], [m].[CodeName], [m].[Date], [m].[Difficulty], [m].[Duration], [m].[Rating], [m].[Time], [m].[Timeline] @@ -10139,7 +10139,7 @@ public override async Task Order_by_TimeOnly_FromTimeSpan(bool async) await base.Order_by_TimeOnly_FromTimeSpan(async); AssertSql( -""" + """ SELECT [m].[Id], [m].[CodeName], [m].[Date], [m].[Difficulty], [m].[Duration], [m].[Rating], [m].[Time], [m].[Timeline] FROM [Missions] AS [m] ORDER BY CAST([m].[Duration] AS time) @@ -10151,7 +10151,7 @@ public override async Task Where_DateOnly_FromDateTime_compared_to_property(bool await base.Where_DateOnly_FromDateTime_compared_to_property(async); AssertSql( -""" + """ SELECT [t].[Id] AS [TagId], [m].[Id] AS [MissionId] FROM [Tags] AS [t] CROSS JOIN [Missions] AS [m] @@ -10164,7 +10164,7 @@ public override async Task Where_DateOnly_FromDateTime_compared_to_constant_and_ await base.Where_DateOnly_FromDateTime_compared_to_constant_and_parameter(async); AssertSql( -""" + """ @__prm_0='10/11/0002' (DbType = Date) SELECT [t].[Id], [t].[GearNickName], [t].[GearSquadId], [t].[IssueDate], [t].[Note] @@ -11627,7 +11627,7 @@ public override async Task Include_one_to_many_on_composite_key_then_orderby_key await base.Include_one_to_many_on_composite_key_then_orderby_key_properties(async); AssertSql( -""" + """ SELECT [g].[Nickname], [g].[SquadId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[Rank], CASE WHEN [o].[Nickname] IS NOT NULL THEN N'Officer' END AS [Discriminator], [w].[Id], [w].[AmmunitionType], [w].[IsAutomatic], [w].[Name], [w].[OwnerFullName], [w].[SynergyWithId] @@ -11795,7 +11795,7 @@ public override async Task Derived_reference_is_skipped_when_base_type(bool asyn await base.Derived_reference_is_skipped_when_base_type(async); AssertSql( -""" + """ SELECT [l].[Name], [l].[LocustHordeId], [l].[ThreatLevel], [l].[ThreatLevelByte], [l].[ThreatLevelNullableByte], [l0].[DefeatedByNickname], [l0].[DefeatedBySquadId], [l0].[HighCommandId], CASE WHEN [l0].[Name] IS NOT NULL THEN N'LocustCommander' END AS [Discriminator], [l1].[Id], [l1].[IsOperational], [l1].[Name] diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPTRelationshipsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPTRelationshipsQuerySqlServerTest.cs index 6e8c7d8e184..382759c61a3 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TPTRelationshipsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPTRelationshipsQuerySqlServerTest.cs @@ -12,9 +12,7 @@ public TPTRelationshipsQuerySqlServerTest( TPTRelationshipsQuerySqlServerFixture fixture, ITestOutputHelper testOutputHelper) : base(fixture) - { - fixture.TestSqlLoggerFactory.Clear(); - } + => fixture.TestSqlLoggerFactory.Clear(); [ConditionalFact] public virtual void Check_all_tests_overridden() diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs index e9372707817..73d5554d42f 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs @@ -137,7 +137,7 @@ public override async Task Query_reusing_parameter_with_inner_query_doesnt_decla { // Test infra issue await Assert.ThrowsAsync( - () => base.Query_reusing_parameter_with_inner_query_doesnt_declare_duplicate_parameter(async)); + () => base.Query_reusing_parameter_with_inner_query_doesnt_declare_duplicate_parameter(async)); AssertSql( """ @@ -436,7 +436,7 @@ public override async Task Where_TimeOnly_FromDateTime_compared_to_property(bool await base.Where_TimeOnly_FromDateTime_compared_to_property(async); AssertSql( -""" + """ SELECT [t].[Id] AS [TagId], [m].[Id] AS [MissionId] FROM [Tags] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [t] CROSS JOIN [Missions] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [m] @@ -449,7 +449,7 @@ public override async Task Where_TimeOnly_FromDateTime_compared_to_parameter(boo await base.Where_TimeOnly_FromDateTime_compared_to_parameter(async); AssertSql( -""" + """ @__time_0='02:00' (DbType = Time) SELECT [t].[Id], [t].[GearNickName], [t].[GearSquadId], [t].[IssueDate], [t].[Note], [t].[PeriodEnd], [t].[PeriodStart] @@ -464,7 +464,7 @@ public override async Task Where_TimeOnly_FromDateTime_compared_to_constant(bool await base.Where_TimeOnly_FromDateTime_compared_to_constant(async); AssertSql( -""" + """ SELECT [t].[Id], [t].[GearNickName], [t].[GearSquadId], [t].[IssueDate], [t].[Note], [t].[PeriodEnd], [t].[PeriodStart] FROM [Tags] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [t] WHERE CAST(DATEADD(hour, CAST(CAST(CAST(LEN([t].[Note]) AS int) AS float) AS int), [t].[IssueDate]) AS time) > '09:00:00' @@ -476,7 +476,7 @@ public override async Task Where_TimeOnly_FromTimeSpan_compared_to_property(bool await base.Where_TimeOnly_FromTimeSpan_compared_to_property(async); AssertSql( -""" + """ SELECT [m].[Id], [m].[BriefingDocument], [m].[BriefingDocumentFileExtension], [m].[CodeName], [m].[Date], [m].[Difficulty], [m].[Duration], [m].[PeriodEnd], [m].[PeriodStart], [m].[Rating], [m].[Time], [m].[Timeline] FROM [Missions] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [m] WHERE CAST([m].[Duration] AS time) < [m].[Time] @@ -488,7 +488,7 @@ public override async Task Where_TimeOnly_FromTimeSpan_compared_to_parameter(boo await base.Where_TimeOnly_FromTimeSpan_compared_to_parameter(async); AssertSql( -""" + """ @__time_0='01:02' (DbType = Time) SELECT [m].[Id], [m].[BriefingDocument], [m].[BriefingDocumentFileExtension], [m].[CodeName], [m].[Date], [m].[Difficulty], [m].[Duration], [m].[PeriodEnd], [m].[PeriodStart], [m].[Rating], [m].[Time], [m].[Timeline] @@ -502,7 +502,7 @@ public override async Task Order_by_TimeOnly_FromTimeSpan(bool async) await base.Order_by_TimeOnly_FromTimeSpan(async); AssertSql( -""" + """ SELECT [m].[Id], [m].[BriefingDocument], [m].[BriefingDocumentFileExtension], [m].[CodeName], [m].[Date], [m].[Difficulty], [m].[Duration], [m].[PeriodEnd], [m].[PeriodStart], [m].[Rating], [m].[Time], [m].[Timeline] FROM [Missions] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [m] ORDER BY CAST([m].[Duration] AS time) @@ -514,7 +514,7 @@ public override async Task Where_DateOnly_FromDateTime_compared_to_property(bool await base.Where_DateOnly_FromDateTime_compared_to_property(async); AssertSql( -""" + """ SELECT [t].[Id] AS [TagId], [m].[Id] AS [MissionId] FROM [Tags] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [t] CROSS JOIN [Missions] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [m] @@ -527,7 +527,7 @@ public override async Task Where_DateOnly_FromDateTime_compared_to_constant_and_ await base.Where_DateOnly_FromDateTime_compared_to_constant_and_parameter(async); AssertSql( -""" + """ @__prm_0='10/11/0002' (DbType = Date) SELECT [t].[Id], [t].[GearNickName], [t].[GearSquadId], [t].[IssueDate], [t].[Note], [t].[PeriodEnd], [t].[PeriodStart] @@ -1536,7 +1536,7 @@ public override async Task Select_subquery_distinct_singleordefault_boolean2(boo AssertSql( """ SELECT COALESCE(( - SELECT DISTINCT TOP(1) [w].[IsAutomatic] + SELECT TOP(1) [w].[IsAutomatic] FROM [Weapons] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [w] WHERE [g].[FullName] = [w].[OwnerFullName] AND [w].[Name] LIKE N'%Lancer%'), CAST(0 AS bit)) FROM [Gears] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [g] @@ -2395,7 +2395,7 @@ public override async Task Select_subquery_distinct_singleordefault_boolean_empt AssertSql( """ SELECT COALESCE(( - SELECT DISTINCT TOP(1) [w].[IsAutomatic] + SELECT TOP(1) [w].[IsAutomatic] FROM [Weapons] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [w] WHERE [g].[FullName] = [w].[OwnerFullName] AND [w].[Name] = N'BFG'), CAST(0 AS bit)) FROM [Gears] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [g] @@ -4783,7 +4783,7 @@ public override async Task ToString_nullable_enum_property_projection(bool async await base.ToString_nullable_enum_property_projection(async); AssertSql( -""" + """ SELECT CASE [w].[AmmunitionType] WHEN 1 THEN N'Cartridge' WHEN 2 THEN N'Shell' @@ -4798,7 +4798,7 @@ public override async Task ToString_enum_contains(bool async) await base.ToString_enum_contains(async); AssertSql( -""" + """ SELECT [m].[CodeName] FROM [Missions] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [m] WHERE CAST([m].[Difficulty] AS nvarchar(max)) LIKE N'%Med%' @@ -4810,7 +4810,7 @@ public override async Task ToString_nullable_enum_contains(bool async) await base.ToString_nullable_enum_contains(async); AssertSql( -""" + """ SELECT [w].[Name] FROM [Weapons] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [w] WHERE CASE [w].[AmmunitionType] @@ -6607,7 +6607,7 @@ public override async Task Where_subquery_distinct_singleordefault_boolean2(bool SELECT [g].[Nickname], [g].[SquadId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[Discriminator], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[PeriodEnd], [g].[PeriodStart], [g].[Rank] FROM [Gears] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [g] WHERE [g].[HasSoulPatch] = CAST(1 AS bit) AND COALESCE(( - SELECT DISTINCT TOP(1) [w].[IsAutomatic] + SELECT TOP(1) [w].[IsAutomatic] FROM [Weapons] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [w] WHERE [g].[FullName] = [w].[OwnerFullName] AND [w].[Name] LIKE N'%Lancer%'), CAST(0 AS bit)) = CAST(1 AS bit) ORDER BY [g].[Nickname] @@ -10249,7 +10249,7 @@ public override async Task Include_one_to_many_on_composite_key_then_orderby_key await base.Include_one_to_many_on_composite_key_then_orderby_key_properties(async); AssertSql( -""" + """ SELECT [g].[Nickname], [g].[SquadId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[Discriminator], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[PeriodEnd], [g].[PeriodStart], [g].[Rank], [w].[Id], [w].[AmmunitionType], [w].[IsAutomatic], [w].[Name], [w].[OwnerFullName], [w].[PeriodEnd], [w].[PeriodStart], [w].[SynergyWithId] FROM [Gears] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [g] LEFT JOIN [Weapons] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [w] ON [g].[FullName] = [w].[OwnerFullName] @@ -10278,7 +10278,7 @@ public override async Task Join_include_coalesce_simple(bool async) await base.Join_include_coalesce_simple(async); AssertSql( -""" + """ SELECT [g0].[Nickname], [g0].[SquadId], [g0].[AssignedCityName], [g0].[CityOfBirthName], [g0].[Discriminator], [g0].[FullName], [g0].[HasSoulPatch], [g0].[LeaderNickname], [g0].[LeaderSquadId], [g0].[PeriodEnd], [g0].[PeriodStart], [g0].[Rank], [g].[Nickname], [g].[SquadId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[Discriminator], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[PeriodEnd], [g].[PeriodStart], [g].[Rank], [w].[Id], [w].[AmmunitionType], [w].[IsAutomatic], [w].[Name], [w].[OwnerFullName], [w].[PeriodEnd], [w].[PeriodStart], [w].[SynergyWithId], CASE WHEN [g].[Nickname] = N'Marcus' THEN CAST(1 AS bit) ELSE CAST(0 AS bit) @@ -10288,16 +10288,16 @@ ELSE CAST(0 AS bit) LEFT JOIN [Weapons] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [w] ON [g].[FullName] = [w].[OwnerFullName] ORDER BY [g].[Nickname], [g].[SquadId], [g0].[Nickname], [g0].[SquadId] """, - // - """ + // + """ SELECT [g0].[Nickname], [g0].[SquadId], [g0].[AssignedCityName], [g0].[CityOfBirthName], [g0].[Discriminator], [g0].[FullName], [g0].[HasSoulPatch], [g0].[LeaderNickname], [g0].[LeaderSquadId], [g0].[PeriodEnd], [g0].[PeriodStart], [g0].[Rank], [g].[Nickname], [g].[SquadId], [w].[Id], [w].[AmmunitionType], [w].[IsAutomatic], [w].[Name], [w].[OwnerFullName], [w].[PeriodEnd], [w].[PeriodStart], [w].[SynergyWithId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[Discriminator], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[PeriodEnd], [g].[PeriodStart], [g].[Rank] FROM [Gears] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [g] LEFT JOIN [Gears] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [g0] ON [g].[LeaderNickname] = [g0].[Nickname] LEFT JOIN [Weapons] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [w] ON [g0].[FullName] = [w].[OwnerFullName] ORDER BY [g].[Nickname], [g].[SquadId], [g0].[Nickname], [g0].[SquadId] """, - // - """ + // + """ SELECT [g0].[Nickname], [g0].[SquadId], [g0].[AssignedCityName], [g0].[CityOfBirthName], [g0].[Discriminator], [g0].[FullName], [g0].[HasSoulPatch], [g0].[LeaderNickname], [g0].[LeaderSquadId], [g0].[PeriodEnd], [g0].[PeriodStart], [g0].[Rank], [g].[Nickname], [g].[SquadId], [w].[Id], [w].[AmmunitionType], [w].[IsAutomatic], [w].[Name], [w].[OwnerFullName], [w].[PeriodEnd], [w].[PeriodStart], [w].[SynergyWithId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[Discriminator], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[PeriodEnd], [g].[PeriodStart], [g].[Rank], [w0].[Id], [w0].[AmmunitionType], [w0].[IsAutomatic], [w0].[Name], [w0].[OwnerFullName], [w0].[PeriodEnd], [w0].[PeriodStart], [w0].[SynergyWithId] FROM [Gears] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [g] LEFT JOIN [Gears] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [g0] ON [g].[LeaderNickname] = [g0].[Nickname] @@ -10312,7 +10312,7 @@ public override async Task Join_include_coalesce_nested(bool async) await base.Join_include_coalesce_nested(async); AssertSql( -""" + """ SELECT [g0].[Nickname], [g0].[SquadId], [g0].[AssignedCityName], [g0].[CityOfBirthName], [g0].[Discriminator], [g0].[FullName], [g0].[HasSoulPatch], [g0].[LeaderNickname], [g0].[LeaderSquadId], [g0].[PeriodEnd], [g0].[PeriodStart], [g0].[Rank], [g].[Nickname], [g].[SquadId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[Discriminator], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[PeriodEnd], [g].[PeriodStart], [g].[Rank], [w].[Id], [w].[AmmunitionType], [w].[IsAutomatic], [w].[Name], [w].[OwnerFullName], [w].[PeriodEnd], [w].[PeriodStart], [w].[SynergyWithId], CASE WHEN [g].[Nickname] = N'Marcus' THEN CAST(1 AS bit) ELSE CAST(0 AS bit) @@ -10322,8 +10322,8 @@ ELSE CAST(0 AS bit) LEFT JOIN [Weapons] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [w] ON [g].[FullName] = [w].[OwnerFullName] ORDER BY [g].[Nickname], [g].[SquadId], [g0].[Nickname], [g0].[SquadId] """, - // - """ + // + """ SELECT [g0].[Nickname], [g0].[SquadId], [g0].[AssignedCityName], [g0].[CityOfBirthName], [g0].[Discriminator], [g0].[FullName], [g0].[HasSoulPatch], [g0].[LeaderNickname], [g0].[LeaderSquadId], [g0].[PeriodEnd], [g0].[PeriodStart], [g0].[Rank], [g].[Nickname], [g].[SquadId], [w].[Id], [w].[AmmunitionType], [w].[IsAutomatic], [w].[Name], [w].[OwnerFullName], [w].[PeriodEnd], [w].[PeriodStart], [w].[SynergyWithId], [w0].[Id], [w0].[AmmunitionType], [w0].[IsAutomatic], [w0].[Name], [w0].[OwnerFullName], [w0].[PeriodEnd], [w0].[PeriodStart], [w0].[SynergyWithId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[Discriminator], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[PeriodEnd], [g].[PeriodStart], [g].[Rank], [w1].[Id], [w1].[AmmunitionType], [w1].[IsAutomatic], [w1].[Name], [w1].[OwnerFullName], [w1].[PeriodEnd], [w1].[PeriodStart], [w1].[SynergyWithId] FROM [Gears] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [g] LEFT JOIN [Gears] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [g0] ON [g].[LeaderNickname] = [g0].[Nickname] @@ -10339,7 +10339,7 @@ public override async Task Join_include_conditional(bool async) await base.Join_include_conditional(async); AssertSql( -""" + """ SELECT CASE WHEN [g0].[Nickname] IS NOT NULL AND [g0].[SquadId] IS NOT NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) @@ -10359,7 +10359,7 @@ public override async Task Derived_reference_is_skipped_when_base_type(bool asyn await base.Derived_reference_is_skipped_when_base_type(async); AssertSql( -""" + """ SELECT [l].[Name], [l].[Discriminator], [l].[LocustHordeId], [l].[PeriodEnd], [l].[PeriodStart], [l].[ThreatLevel], [l].[ThreatLevelByte], [l].[ThreatLevelNullableByte], [l].[DefeatedByNickname], [l].[DefeatedBySquadId], [l].[HighCommandId], [l0].[Id], [l0].[IsOperational], [l0].[Name], [l0].[PeriodEnd], [l0].[PeriodStart] FROM [LocustLeaders] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [l] LEFT JOIN [LocustHighCommands] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [l0] ON [l].[HighCommandId] = [l0].[Id] diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TemporalOwnedQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TemporalOwnedQuerySqlServerTest.cs index 67aedc24e72..cecd329a737 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TemporalOwnedQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TemporalOwnedQuerySqlServerTest.cs @@ -13,9 +13,7 @@ public class TemporalOwnedQuerySqlServerTest : OwnedQueryRelationalTestBase< { public TemporalOwnedQuerySqlServerTest(TemporalOwnedQuerySqlServerFixture fixture, ITestOutputHelper testOutputHelper) : base(fixture) - { - Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); - } + => Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); protected override Expression RewriteServerQueryExpression(Expression serverQueryExpression) { diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/WarningsSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/WarningsSqlServerTest.cs index a4ec9a294f4..a70b877dd49 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/WarningsSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/WarningsSqlServerTest.cs @@ -5,4 +5,5 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class WarningsSqlServerTest(NorthwindQuerySqlServerFixture fixture) : WarningsTestBase>(fixture); +public class WarningsSqlServerTest(NorthwindQuerySqlServerFixture fixture) + : WarningsTestBase>(fixture); diff --git a/test/EFCore.SqlServer.FunctionalTests/QueryExpressionInterceptionSqlServerTestBase.cs b/test/EFCore.SqlServer.FunctionalTests/QueryExpressionInterceptionSqlServerTestBase.cs index d3c8407e20f..99b20b338c0 100644 --- a/test/EFCore.SqlServer.FunctionalTests/QueryExpressionInterceptionSqlServerTestBase.cs +++ b/test/EFCore.SqlServer.FunctionalTests/QueryExpressionInterceptionSqlServerTestBase.cs @@ -30,7 +30,8 @@ public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder build } public class QueryExpressionInterceptionSqlServerTest(QueryExpressionInterceptionSqlServerTest.InterceptionSqlServerFixture fixture) - : QueryExpressionInterceptionSqlServerTestBase(fixture), IClassFixture + : QueryExpressionInterceptionSqlServerTestBase(fixture), + IClassFixture { public class InterceptionSqlServerFixture : InterceptionSqlServerFixtureBase { @@ -42,7 +43,8 @@ protected override bool ShouldSubscribeToDiagnosticListener } } - public class QueryExpressionInterceptionWithDiagnosticsSqlServerTest(QueryExpressionInterceptionWithDiagnosticsSqlServerTest.InterceptionSqlServerFixture fixture) + public class QueryExpressionInterceptionWithDiagnosticsSqlServerTest( + QueryExpressionInterceptionWithDiagnosticsSqlServerTest.InterceptionSqlServerFixture fixture) : QueryExpressionInterceptionSqlServerTestBase(fixture), IClassFixture { diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/DependentBaseEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/DependentBaseEntityType.cs index 92f584448c3..29c9d8da74e 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/DependentBaseEntityType.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/DependentBaseEntityType.cs @@ -187,8 +187,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (byte v1, byte v2) => v1 == v2, int (byte v) => ((int)(v)), byte (byte v) => v)); - id.SetValueComparer(new NullableValueComparer(id.TypeMapping.Comparer)); - id.SetKeyValueComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); + id.SetComparer(new NullableValueComparer(id.TypeMapping.Comparer)); + id.SetKeyComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); id.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var key = runtimeEntityType.AddKey( @@ -286,14 +286,14 @@ public static RuntimeForeignKey CreateForeignKey2(RuntimeEntityType declaringEnt public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var principalId = runtimeEntityType.FindProperty("PrincipalId")!; - var principalAlternateId = runtimeEntityType.FindProperty("PrincipalAlternateId")!; - var enumDiscriminator = runtimeEntityType.FindProperty("EnumDiscriminator")!; - var id = runtimeEntityType.FindProperty("Id")!; + var principalId = runtimeEntityType.FindProperty("PrincipalId"); + var principalAlternateId = runtimeEntityType.FindProperty("PrincipalAlternateId"); + var enumDiscriminator = runtimeEntityType.FindProperty("EnumDiscriminator"); + var id = runtimeEntityType.FindProperty("Id"); var key = runtimeEntityType.FindKey(new[] { principalId, principalAlternateId }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateCompositeFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory>(key)); - var principal = runtimeEntityType.FindNavigation("Principal")!; + var principal = runtimeEntityType.FindNavigation("Principal"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/DependentDerivedEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/DependentDerivedEntityType.cs index ffaeb589c27..ebd7aee13f6 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/DependentDerivedEntityType.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/DependentDerivedEntityType.cs @@ -121,13 +121,13 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var principalId = runtimeEntityType.FindProperty("PrincipalId")!; - var principalAlternateId = runtimeEntityType.FindProperty("PrincipalAlternateId")!; - var enumDiscriminator = runtimeEntityType.FindProperty("EnumDiscriminator")!; - var id = runtimeEntityType.FindProperty("Id")!; - var data = runtimeEntityType.FindProperty("Data")!; - var money = runtimeEntityType.FindProperty("Money")!; - var principal = runtimeEntityType.FindNavigation("Principal")!; + var principalId = runtimeEntityType.FindProperty("PrincipalId"); + var principalAlternateId = runtimeEntityType.FindProperty("PrincipalAlternateId"); + var enumDiscriminator = runtimeEntityType.FindProperty("EnumDiscriminator"); + var id = runtimeEntityType.FindProperty("Id"); + var data = runtimeEntityType.FindProperty("Data"); + var money = runtimeEntityType.FindProperty("Money"); + var principal = runtimeEntityType.FindNavigation("Principal"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/ManyTypesEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/ManyTypesEntityType.cs index acf2fc670f0..7363b3af85d 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/ManyTypesEntityType.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/ManyTypesEntityType.cs @@ -6569,8 +6569,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (bool v1, bool v2) => v1 == v2, int (bool v) => ((object)v).GetHashCode(), bool (bool v) => v)); - nullableBool.SetValueComparer(new NullableValueComparer(nullableBool.TypeMapping.Comparer)); - nullableBool.SetKeyValueComparer(new NullableValueComparer(nullableBool.TypeMapping.KeyComparer)); + nullableBool.SetComparer(new NullableValueComparer(nullableBool.TypeMapping.Comparer)); + nullableBool.SetKeyComparer(new NullableValueComparer(nullableBool.TypeMapping.KeyComparer)); nullableBool.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableBoolArray = runtimeEntityType.AddProperty( @@ -6800,8 +6800,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( string (char v) => string.Format(CultureInfo.InvariantCulture, "{0}", ((object)(v))), char (string v) => (v.Length < 1 ? '\0' : v[0])))); - nullableChar.SetValueComparer(new NullableValueComparer(nullableChar.TypeMapping.Comparer)); - nullableChar.SetKeyValueComparer(new NullableValueComparer(nullableChar.TypeMapping.KeyComparer)); + nullableChar.SetComparer(new NullableValueComparer(nullableChar.TypeMapping.Comparer)); + nullableChar.SetKeyComparer(new NullableValueComparer(nullableChar.TypeMapping.KeyComparer)); nullableChar.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableCharArray = runtimeEntityType.AddProperty( @@ -6928,8 +6928,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (DateOnly v1, DateOnly v2) => v1.Equals(v2), int (DateOnly v) => ((object)v).GetHashCode(), DateOnly (DateOnly v) => v)); - nullableDateOnly.SetValueComparer(new NullableValueComparer(nullableDateOnly.TypeMapping.Comparer)); - nullableDateOnly.SetKeyValueComparer(new NullableValueComparer(nullableDateOnly.TypeMapping.KeyComparer)); + nullableDateOnly.SetComparer(new NullableValueComparer(nullableDateOnly.TypeMapping.Comparer)); + nullableDateOnly.SetKeyComparer(new NullableValueComparer(nullableDateOnly.TypeMapping.KeyComparer)); nullableDateOnly.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableDateOnlyArray = runtimeEntityType.AddProperty( @@ -7035,8 +7035,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (DateTime v1, DateTime v2) => v1.Equals(v2), int (DateTime v) => ((object)v).GetHashCode(), DateTime (DateTime v) => v)); - nullableDateTime.SetValueComparer(new NullableValueComparer(nullableDateTime.TypeMapping.Comparer)); - nullableDateTime.SetKeyValueComparer(new NullableValueComparer(nullableDateTime.TypeMapping.KeyComparer)); + nullableDateTime.SetComparer(new NullableValueComparer(nullableDateTime.TypeMapping.Comparer)); + nullableDateTime.SetKeyComparer(new NullableValueComparer(nullableDateTime.TypeMapping.KeyComparer)); nullableDateTime.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableDateTimeArray = runtimeEntityType.AddProperty( @@ -7142,8 +7142,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (decimal v1, decimal v2) => v1 == v2, int (decimal v) => ((object)v).GetHashCode(), decimal (decimal v) => v)); - nullableDecimal.SetValueComparer(new NullableValueComparer(nullableDecimal.TypeMapping.Comparer)); - nullableDecimal.SetKeyValueComparer(new NullableValueComparer(nullableDecimal.TypeMapping.KeyComparer)); + nullableDecimal.SetComparer(new NullableValueComparer(nullableDecimal.TypeMapping.Comparer)); + nullableDecimal.SetKeyComparer(new NullableValueComparer(nullableDecimal.TypeMapping.KeyComparer)); nullableDecimal.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableDecimalArray = runtimeEntityType.AddProperty( @@ -7249,8 +7249,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (double v1, double v2) => v1.Equals(v2), int (double v) => ((object)v).GetHashCode(), double (double v) => v)); - nullableDouble.SetValueComparer(new NullableValueComparer(nullableDouble.TypeMapping.Comparer)); - nullableDouble.SetKeyValueComparer(new NullableValueComparer(nullableDouble.TypeMapping.KeyComparer)); + nullableDouble.SetComparer(new NullableValueComparer(nullableDouble.TypeMapping.Comparer)); + nullableDouble.SetKeyComparer(new NullableValueComparer(nullableDouble.TypeMapping.KeyComparer)); nullableDouble.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableDoubleArray = runtimeEntityType.AddProperty( @@ -7364,8 +7364,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( short (CompiledModelTestBase.Enum16 value) => ((short)(value)), CompiledModelTestBase.Enum16 (short value) => ((CompiledModelTestBase.Enum16)(value))))); - nullableEnum16.SetValueComparer(new NullableValueComparer(nullableEnum16.TypeMapping.Comparer)); - nullableEnum16.SetKeyValueComparer(new NullableValueComparer(nullableEnum16.TypeMapping.KeyComparer)); + nullableEnum16.SetComparer(new NullableValueComparer(nullableEnum16.TypeMapping.Comparer)); + nullableEnum16.SetKeyComparer(new NullableValueComparer(nullableEnum16.TypeMapping.KeyComparer)); nullableEnum16.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableEnum16Array = runtimeEntityType.AddProperty( @@ -7495,8 +7495,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( short (CompiledModelTestBase.Enum16 value) => ((short)(value)), CompiledModelTestBase.Enum16 (short value) => ((CompiledModelTestBase.Enum16)(value))))); - nullableEnum16AsString.SetValueComparer(new NullableValueComparer(nullableEnum16AsString.TypeMapping.Comparer)); - nullableEnum16AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnum16AsString.TypeMapping.KeyComparer)); + nullableEnum16AsString.SetComparer(new NullableValueComparer(nullableEnum16AsString.TypeMapping.Comparer)); + nullableEnum16AsString.SetKeyComparer(new NullableValueComparer(nullableEnum16AsString.TypeMapping.KeyComparer)); nullableEnum16AsString.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableEnum16AsStringArray = runtimeEntityType.AddProperty( @@ -7784,8 +7784,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( int (CompiledModelTestBase.Enum32 value) => ((int)(value)), CompiledModelTestBase.Enum32 (int value) => ((CompiledModelTestBase.Enum32)(value))))); - nullableEnum32.SetValueComparer(new NullableValueComparer(nullableEnum32.TypeMapping.Comparer)); - nullableEnum32.SetKeyValueComparer(new NullableValueComparer(nullableEnum32.TypeMapping.KeyComparer)); + nullableEnum32.SetComparer(new NullableValueComparer(nullableEnum32.TypeMapping.Comparer)); + nullableEnum32.SetKeyComparer(new NullableValueComparer(nullableEnum32.TypeMapping.KeyComparer)); nullableEnum32.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableEnum32Array = runtimeEntityType.AddProperty( @@ -7915,8 +7915,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( int (CompiledModelTestBase.Enum32 value) => ((int)(value)), CompiledModelTestBase.Enum32 (int value) => ((CompiledModelTestBase.Enum32)(value))))); - nullableEnum32AsString.SetValueComparer(new NullableValueComparer(nullableEnum32AsString.TypeMapping.Comparer)); - nullableEnum32AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnum32AsString.TypeMapping.KeyComparer)); + nullableEnum32AsString.SetComparer(new NullableValueComparer(nullableEnum32AsString.TypeMapping.Comparer)); + nullableEnum32AsString.SetKeyComparer(new NullableValueComparer(nullableEnum32AsString.TypeMapping.KeyComparer)); nullableEnum32AsString.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableEnum32AsStringArray = runtimeEntityType.AddProperty( @@ -8204,8 +8204,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( long (CompiledModelTestBase.Enum64 value) => ((long)(value)), CompiledModelTestBase.Enum64 (long value) => ((CompiledModelTestBase.Enum64)(value))))); - nullableEnum64.SetValueComparer(new NullableValueComparer(nullableEnum64.TypeMapping.Comparer)); - nullableEnum64.SetKeyValueComparer(new NullableValueComparer(nullableEnum64.TypeMapping.KeyComparer)); + nullableEnum64.SetComparer(new NullableValueComparer(nullableEnum64.TypeMapping.Comparer)); + nullableEnum64.SetKeyComparer(new NullableValueComparer(nullableEnum64.TypeMapping.KeyComparer)); nullableEnum64.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableEnum64Array = runtimeEntityType.AddProperty( @@ -8335,8 +8335,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( long (CompiledModelTestBase.Enum64 value) => ((long)(value)), CompiledModelTestBase.Enum64 (long value) => ((CompiledModelTestBase.Enum64)(value))))); - nullableEnum64AsString.SetValueComparer(new NullableValueComparer(nullableEnum64AsString.TypeMapping.Comparer)); - nullableEnum64AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnum64AsString.TypeMapping.KeyComparer)); + nullableEnum64AsString.SetComparer(new NullableValueComparer(nullableEnum64AsString.TypeMapping.Comparer)); + nullableEnum64AsString.SetKeyComparer(new NullableValueComparer(nullableEnum64AsString.TypeMapping.KeyComparer)); nullableEnum64AsString.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableEnum64AsStringArray = runtimeEntityType.AddProperty( @@ -8624,8 +8624,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( short (CompiledModelTestBase.Enum8 value) => ((short)(value)), CompiledModelTestBase.Enum8 (short value) => ((CompiledModelTestBase.Enum8)(value))))); - nullableEnum8.SetValueComparer(new NullableValueComparer(nullableEnum8.TypeMapping.Comparer)); - nullableEnum8.SetKeyValueComparer(new NullableValueComparer(nullableEnum8.TypeMapping.KeyComparer)); + nullableEnum8.SetComparer(new NullableValueComparer(nullableEnum8.TypeMapping.Comparer)); + nullableEnum8.SetKeyComparer(new NullableValueComparer(nullableEnum8.TypeMapping.KeyComparer)); nullableEnum8.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableEnum8Array = runtimeEntityType.AddProperty( @@ -8755,8 +8755,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( short (CompiledModelTestBase.Enum8 value) => ((short)(value)), CompiledModelTestBase.Enum8 (short value) => ((CompiledModelTestBase.Enum8)(value))))); - nullableEnum8AsString.SetValueComparer(new NullableValueComparer(nullableEnum8AsString.TypeMapping.Comparer)); - nullableEnum8AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnum8AsString.TypeMapping.KeyComparer)); + nullableEnum8AsString.SetComparer(new NullableValueComparer(nullableEnum8AsString.TypeMapping.Comparer)); + nullableEnum8AsString.SetKeyComparer(new NullableValueComparer(nullableEnum8AsString.TypeMapping.KeyComparer)); nullableEnum8AsString.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableEnum8AsStringArray = runtimeEntityType.AddProperty( @@ -9044,8 +9044,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( int (CompiledModelTestBase.EnumU16 value) => ((int)(value)), CompiledModelTestBase.EnumU16 (int value) => ((CompiledModelTestBase.EnumU16)(value))))); - nullableEnumU16.SetValueComparer(new NullableValueComparer(nullableEnumU16.TypeMapping.Comparer)); - nullableEnumU16.SetKeyValueComparer(new NullableValueComparer(nullableEnumU16.TypeMapping.KeyComparer)); + nullableEnumU16.SetComparer(new NullableValueComparer(nullableEnumU16.TypeMapping.Comparer)); + nullableEnumU16.SetKeyComparer(new NullableValueComparer(nullableEnumU16.TypeMapping.KeyComparer)); nullableEnumU16.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableEnumU16Array = runtimeEntityType.AddProperty( @@ -9175,8 +9175,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( int (CompiledModelTestBase.EnumU16 value) => ((int)(value)), CompiledModelTestBase.EnumU16 (int value) => ((CompiledModelTestBase.EnumU16)(value))))); - nullableEnumU16AsString.SetValueComparer(new NullableValueComparer(nullableEnumU16AsString.TypeMapping.Comparer)); - nullableEnumU16AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnumU16AsString.TypeMapping.KeyComparer)); + nullableEnumU16AsString.SetComparer(new NullableValueComparer(nullableEnumU16AsString.TypeMapping.Comparer)); + nullableEnumU16AsString.SetKeyComparer(new NullableValueComparer(nullableEnumU16AsString.TypeMapping.KeyComparer)); nullableEnumU16AsString.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableEnumU16AsStringArray = runtimeEntityType.AddProperty( @@ -9464,8 +9464,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( long (CompiledModelTestBase.EnumU32 value) => ((long)(value)), CompiledModelTestBase.EnumU32 (long value) => ((CompiledModelTestBase.EnumU32)(value))))); - nullableEnumU32.SetValueComparer(new NullableValueComparer(nullableEnumU32.TypeMapping.Comparer)); - nullableEnumU32.SetKeyValueComparer(new NullableValueComparer(nullableEnumU32.TypeMapping.KeyComparer)); + nullableEnumU32.SetComparer(new NullableValueComparer(nullableEnumU32.TypeMapping.Comparer)); + nullableEnumU32.SetKeyComparer(new NullableValueComparer(nullableEnumU32.TypeMapping.KeyComparer)); nullableEnumU32.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableEnumU32Array = runtimeEntityType.AddProperty( @@ -9595,8 +9595,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( long (CompiledModelTestBase.EnumU32 value) => ((long)(value)), CompiledModelTestBase.EnumU32 (long value) => ((CompiledModelTestBase.EnumU32)(value))))); - nullableEnumU32AsString.SetValueComparer(new NullableValueComparer(nullableEnumU32AsString.TypeMapping.Comparer)); - nullableEnumU32AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnumU32AsString.TypeMapping.KeyComparer)); + nullableEnumU32AsString.SetComparer(new NullableValueComparer(nullableEnumU32AsString.TypeMapping.Comparer)); + nullableEnumU32AsString.SetKeyComparer(new NullableValueComparer(nullableEnumU32AsString.TypeMapping.KeyComparer)); nullableEnumU32AsString.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableEnumU32AsStringArray = runtimeEntityType.AddProperty( @@ -9888,8 +9888,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( decimal (CompiledModelTestBase.EnumU64 value) => ((decimal)(((long)(value)))), CompiledModelTestBase.EnumU64 (decimal value) => ((CompiledModelTestBase.EnumU64)(((long)(value))))))); - nullableEnumU64.SetValueComparer(new NullableValueComparer(nullableEnumU64.TypeMapping.Comparer)); - nullableEnumU64.SetKeyValueComparer(new NullableValueComparer(nullableEnumU64.TypeMapping.KeyComparer)); + nullableEnumU64.SetComparer(new NullableValueComparer(nullableEnumU64.TypeMapping.Comparer)); + nullableEnumU64.SetKeyComparer(new NullableValueComparer(nullableEnumU64.TypeMapping.KeyComparer)); nullableEnumU64.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableEnumU64Array = runtimeEntityType.AddProperty( @@ -10027,8 +10027,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( decimal (CompiledModelTestBase.EnumU64 value) => ((decimal)(((long)(value)))), CompiledModelTestBase.EnumU64 (decimal value) => ((CompiledModelTestBase.EnumU64)(((long)(value))))))); - nullableEnumU64AsString.SetValueComparer(new NullableValueComparer(nullableEnumU64AsString.TypeMapping.Comparer)); - nullableEnumU64AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnumU64AsString.TypeMapping.KeyComparer)); + nullableEnumU64AsString.SetComparer(new NullableValueComparer(nullableEnumU64AsString.TypeMapping.Comparer)); + nullableEnumU64AsString.SetKeyComparer(new NullableValueComparer(nullableEnumU64AsString.TypeMapping.KeyComparer)); nullableEnumU64AsString.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableEnumU64AsStringArray = runtimeEntityType.AddProperty( @@ -10328,8 +10328,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( byte (CompiledModelTestBase.EnumU8 value) => ((byte)(value)), CompiledModelTestBase.EnumU8 (byte value) => ((CompiledModelTestBase.EnumU8)(value))))); - nullableEnumU8.SetValueComparer(new NullableValueComparer(nullableEnumU8.TypeMapping.Comparer)); - nullableEnumU8.SetKeyValueComparer(new NullableValueComparer(nullableEnumU8.TypeMapping.KeyComparer)); + nullableEnumU8.SetComparer(new NullableValueComparer(nullableEnumU8.TypeMapping.Comparer)); + nullableEnumU8.SetKeyComparer(new NullableValueComparer(nullableEnumU8.TypeMapping.KeyComparer)); nullableEnumU8.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableEnumU8Array = runtimeEntityType.AddProperty( @@ -10459,8 +10459,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( byte (CompiledModelTestBase.EnumU8 value) => ((byte)(value)), CompiledModelTestBase.EnumU8 (byte value) => ((CompiledModelTestBase.EnumU8)(value))))); - nullableEnumU8AsString.SetValueComparer(new NullableValueComparer(nullableEnumU8AsString.TypeMapping.Comparer)); - nullableEnumU8AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnumU8AsString.TypeMapping.KeyComparer)); + nullableEnumU8AsString.SetComparer(new NullableValueComparer(nullableEnumU8AsString.TypeMapping.Comparer)); + nullableEnumU8AsString.SetKeyComparer(new NullableValueComparer(nullableEnumU8AsString.TypeMapping.KeyComparer)); nullableEnumU8AsString.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableEnumU8AsStringArray = runtimeEntityType.AddProperty( @@ -10740,8 +10740,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (float v1, float v2) => v1.Equals(v2), int (float v) => ((object)v).GetHashCode(), float (float v) => v)); - nullableFloat.SetValueComparer(new NullableValueComparer(nullableFloat.TypeMapping.Comparer)); - nullableFloat.SetKeyValueComparer(new NullableValueComparer(nullableFloat.TypeMapping.KeyComparer)); + nullableFloat.SetComparer(new NullableValueComparer(nullableFloat.TypeMapping.Comparer)); + nullableFloat.SetKeyComparer(new NullableValueComparer(nullableFloat.TypeMapping.KeyComparer)); nullableFloat.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableFloatArray = runtimeEntityType.AddProperty( @@ -10849,8 +10849,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas Guid (Guid v) => v), mappingInfo: new RelationalTypeMappingInfo( storeTypeName: "uniqueidentifier")); - nullableGuid.SetValueComparer(new NullableValueComparer(nullableGuid.TypeMapping.Comparer)); - nullableGuid.SetKeyValueComparer(new NullableValueComparer(nullableGuid.TypeMapping.KeyComparer)); + nullableGuid.SetComparer(new NullableValueComparer(nullableGuid.TypeMapping.Comparer)); + nullableGuid.SetKeyComparer(new NullableValueComparer(nullableGuid.TypeMapping.KeyComparer)); nullableGuid.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableGuidArray = runtimeEntityType.AddProperty( @@ -11097,8 +11097,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (short v1, short v2) => v1 == v2, int (short v) => ((int)(v)), short (short v) => v)); - nullableInt16.SetValueComparer(new NullableValueComparer(nullableInt16.TypeMapping.Comparer)); - nullableInt16.SetKeyValueComparer(new NullableValueComparer(nullableInt16.TypeMapping.KeyComparer)); + nullableInt16.SetComparer(new NullableValueComparer(nullableInt16.TypeMapping.Comparer)); + nullableInt16.SetKeyComparer(new NullableValueComparer(nullableInt16.TypeMapping.KeyComparer)); nullableInt16.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableInt16Array = runtimeEntityType.AddProperty( @@ -11204,8 +11204,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (int v1, int v2) => v1 == v2, int (int v) => v, int (int v) => v)); - nullableInt32.SetValueComparer(new NullableValueComparer(nullableInt32.TypeMapping.Comparer)); - nullableInt32.SetKeyValueComparer(new NullableValueComparer(nullableInt32.TypeMapping.KeyComparer)); + nullableInt32.SetComparer(new NullableValueComparer(nullableInt32.TypeMapping.Comparer)); + nullableInt32.SetKeyComparer(new NullableValueComparer(nullableInt32.TypeMapping.KeyComparer)); nullableInt32.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableInt32Array = runtimeEntityType.AddProperty( @@ -11311,8 +11311,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (long v1, long v2) => v1 == v2, int (long v) => ((object)v).GetHashCode(), long (long v) => v)); - nullableInt64.SetValueComparer(new NullableValueComparer(nullableInt64.TypeMapping.Comparer)); - nullableInt64.SetKeyValueComparer(new NullableValueComparer(nullableInt64.TypeMapping.KeyComparer)); + nullableInt64.SetComparer(new NullableValueComparer(nullableInt64.TypeMapping.Comparer)); + nullableInt64.SetKeyComparer(new NullableValueComparer(nullableInt64.TypeMapping.KeyComparer)); nullableInt64.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableInt64Array = runtimeEntityType.AddProperty( @@ -11426,8 +11426,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( short (sbyte v) => ((short)(v)), sbyte (short v) => ((sbyte)(v))))); - nullableInt8.SetValueComparer(new NullableValueComparer(nullableInt8.TypeMapping.Comparer)); - nullableInt8.SetKeyValueComparer(new NullableValueComparer(nullableInt8.TypeMapping.KeyComparer)); + nullableInt8.SetComparer(new NullableValueComparer(nullableInt8.TypeMapping.Comparer)); + nullableInt8.SetKeyComparer(new NullableValueComparer(nullableInt8.TypeMapping.KeyComparer)); nullableInt8.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableInt8Array = runtimeEntityType.AddProperty( @@ -11803,8 +11803,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (TimeOnly v1, TimeOnly v2) => v1.Equals(v2), int (TimeOnly v) => ((object)v).GetHashCode(), TimeOnly (TimeOnly v) => v)); - nullableTimeOnly.SetValueComparer(new NullableValueComparer(nullableTimeOnly.TypeMapping.Comparer)); - nullableTimeOnly.SetKeyValueComparer(new NullableValueComparer(nullableTimeOnly.TypeMapping.KeyComparer)); + nullableTimeOnly.SetComparer(new NullableValueComparer(nullableTimeOnly.TypeMapping.Comparer)); + nullableTimeOnly.SetKeyComparer(new NullableValueComparer(nullableTimeOnly.TypeMapping.KeyComparer)); nullableTimeOnly.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableTimeOnlyArray = runtimeEntityType.AddProperty( @@ -11910,8 +11910,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (TimeSpan v1, TimeSpan v2) => v1.Equals(v2), int (TimeSpan v) => ((object)v).GetHashCode(), TimeSpan (TimeSpan v) => v)); - nullableTimeSpan.SetValueComparer(new NullableValueComparer(nullableTimeSpan.TypeMapping.Comparer)); - nullableTimeSpan.SetKeyValueComparer(new NullableValueComparer(nullableTimeSpan.TypeMapping.KeyComparer)); + nullableTimeSpan.SetComparer(new NullableValueComparer(nullableTimeSpan.TypeMapping.Comparer)); + nullableTimeSpan.SetKeyComparer(new NullableValueComparer(nullableTimeSpan.TypeMapping.KeyComparer)); nullableTimeSpan.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableTimeSpanArray = runtimeEntityType.AddProperty( @@ -12025,8 +12025,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( int (ushort v) => ((int)(v)), ushort (int v) => ((ushort)(v))))); - nullableUInt16.SetValueComparer(new NullableValueComparer(nullableUInt16.TypeMapping.Comparer)); - nullableUInt16.SetKeyValueComparer(new NullableValueComparer(nullableUInt16.TypeMapping.KeyComparer)); + nullableUInt16.SetComparer(new NullableValueComparer(nullableUInt16.TypeMapping.Comparer)); + nullableUInt16.SetKeyComparer(new NullableValueComparer(nullableUInt16.TypeMapping.KeyComparer)); nullableUInt16.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableUInt16Array = runtimeEntityType.AddProperty( @@ -12156,8 +12156,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( long (uint v) => ((long)(v)), uint (long v) => ((uint)(v))))); - nullableUInt32.SetValueComparer(new NullableValueComparer(nullableUInt32.TypeMapping.Comparer)); - nullableUInt32.SetKeyValueComparer(new NullableValueComparer(nullableUInt32.TypeMapping.KeyComparer)); + nullableUInt32.SetComparer(new NullableValueComparer(nullableUInt32.TypeMapping.Comparer)); + nullableUInt32.SetKeyComparer(new NullableValueComparer(nullableUInt32.TypeMapping.KeyComparer)); nullableUInt32.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableUInt32Array = runtimeEntityType.AddProperty( @@ -12291,8 +12291,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( decimal (ulong v) => ((decimal)(v)), ulong (decimal v) => ((ulong)(v))))); - nullableUInt64.SetValueComparer(new NullableValueComparer(nullableUInt64.TypeMapping.Comparer)); - nullableUInt64.SetKeyValueComparer(new NullableValueComparer(nullableUInt64.TypeMapping.KeyComparer)); + nullableUInt64.SetComparer(new NullableValueComparer(nullableUInt64.TypeMapping.Comparer)); + nullableUInt64.SetKeyComparer(new NullableValueComparer(nullableUInt64.TypeMapping.KeyComparer)); nullableUInt64.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableUInt64Array = runtimeEntityType.AddProperty( @@ -12418,8 +12418,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (byte v1, byte v2) => v1 == v2, int (byte v) => ((int)(v)), byte (byte v) => v)); - nullableUInt8.SetValueComparer(new NullableValueComparer(nullableUInt8.TypeMapping.Comparer)); - nullableUInt8.SetKeyValueComparer(new NullableValueComparer(nullableUInt8.TypeMapping.KeyComparer)); + nullableUInt8.SetComparer(new NullableValueComparer(nullableUInt8.TypeMapping.Comparer)); + nullableUInt8.SetKeyComparer(new NullableValueComparer(nullableUInt8.TypeMapping.KeyComparer)); nullableUInt8.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableUInt8Array = runtimeEntityType.AddProperty( @@ -14816,242 +14816,242 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var @bool = runtimeEntityType.FindProperty("Bool")!; - var boolArray = runtimeEntityType.FindProperty("BoolArray")!; - var boolToStringConverterProperty = runtimeEntityType.FindProperty("BoolToStringConverterProperty")!; - var boolToTwoValuesConverterProperty = runtimeEntityType.FindProperty("BoolToTwoValuesConverterProperty")!; - var boolToZeroOneConverterProperty = runtimeEntityType.FindProperty("BoolToZeroOneConverterProperty")!; - var bytes = runtimeEntityType.FindProperty("Bytes")!; - var bytesArray = runtimeEntityType.FindProperty("BytesArray")!; - var bytesToStringConverterProperty = runtimeEntityType.FindProperty("BytesToStringConverterProperty")!; - var castingConverterProperty = runtimeEntityType.FindProperty("CastingConverterProperty")!; - var @char = runtimeEntityType.FindProperty("Char")!; - var charArray = runtimeEntityType.FindProperty("CharArray")!; - var charToStringConverterProperty = runtimeEntityType.FindProperty("CharToStringConverterProperty")!; - var dateOnly = runtimeEntityType.FindProperty("DateOnly")!; - var dateOnlyArray = runtimeEntityType.FindProperty("DateOnlyArray")!; - var dateOnlyToStringConverterProperty = runtimeEntityType.FindProperty("DateOnlyToStringConverterProperty")!; - var dateTime = runtimeEntityType.FindProperty("DateTime")!; - var dateTimeArray = runtimeEntityType.FindProperty("DateTimeArray")!; - var dateTimeOffsetToBinaryConverterProperty = runtimeEntityType.FindProperty("DateTimeOffsetToBinaryConverterProperty")!; - var dateTimeOffsetToBytesConverterProperty = runtimeEntityType.FindProperty("DateTimeOffsetToBytesConverterProperty")!; - var dateTimeOffsetToStringConverterProperty = runtimeEntityType.FindProperty("DateTimeOffsetToStringConverterProperty")!; - var dateTimeToBinaryConverterProperty = runtimeEntityType.FindProperty("DateTimeToBinaryConverterProperty")!; - var dateTimeToStringConverterProperty = runtimeEntityType.FindProperty("DateTimeToStringConverterProperty")!; - var dateTimeToTicksConverterProperty = runtimeEntityType.FindProperty("DateTimeToTicksConverterProperty")!; - var @decimal = runtimeEntityType.FindProperty("Decimal")!; - var decimalArray = runtimeEntityType.FindProperty("DecimalArray")!; - var decimalNumberToBytesConverterProperty = runtimeEntityType.FindProperty("DecimalNumberToBytesConverterProperty")!; - var decimalNumberToStringConverterProperty = runtimeEntityType.FindProperty("DecimalNumberToStringConverterProperty")!; - var @double = runtimeEntityType.FindProperty("Double")!; - var doubleArray = runtimeEntityType.FindProperty("DoubleArray")!; - var doubleNumberToBytesConverterProperty = runtimeEntityType.FindProperty("DoubleNumberToBytesConverterProperty")!; - var doubleNumberToStringConverterProperty = runtimeEntityType.FindProperty("DoubleNumberToStringConverterProperty")!; - var enum16 = runtimeEntityType.FindProperty("Enum16")!; - var enum16Array = runtimeEntityType.FindProperty("Enum16Array")!; - var enum16AsString = runtimeEntityType.FindProperty("Enum16AsString")!; - var enum16AsStringArray = runtimeEntityType.FindProperty("Enum16AsStringArray")!; - var enum16AsStringCollection = runtimeEntityType.FindProperty("Enum16AsStringCollection")!; - var enum16Collection = runtimeEntityType.FindProperty("Enum16Collection")!; - var enum32 = runtimeEntityType.FindProperty("Enum32")!; - var enum32Array = runtimeEntityType.FindProperty("Enum32Array")!; - var enum32AsString = runtimeEntityType.FindProperty("Enum32AsString")!; - var enum32AsStringArray = runtimeEntityType.FindProperty("Enum32AsStringArray")!; - var enum32AsStringCollection = runtimeEntityType.FindProperty("Enum32AsStringCollection")!; - var enum32Collection = runtimeEntityType.FindProperty("Enum32Collection")!; - var enum64 = runtimeEntityType.FindProperty("Enum64")!; - var enum64Array = runtimeEntityType.FindProperty("Enum64Array")!; - var enum64AsString = runtimeEntityType.FindProperty("Enum64AsString")!; - var enum64AsStringArray = runtimeEntityType.FindProperty("Enum64AsStringArray")!; - var enum64AsStringCollection = runtimeEntityType.FindProperty("Enum64AsStringCollection")!; - var enum64Collection = runtimeEntityType.FindProperty("Enum64Collection")!; - var enum8 = runtimeEntityType.FindProperty("Enum8")!; - var enum8Array = runtimeEntityType.FindProperty("Enum8Array")!; - var enum8AsString = runtimeEntityType.FindProperty("Enum8AsString")!; - var enum8AsStringArray = runtimeEntityType.FindProperty("Enum8AsStringArray")!; - var enum8AsStringCollection = runtimeEntityType.FindProperty("Enum8AsStringCollection")!; - var enum8Collection = runtimeEntityType.FindProperty("Enum8Collection")!; - var enumToNumberConverterProperty = runtimeEntityType.FindProperty("EnumToNumberConverterProperty")!; - var enumToStringConverterProperty = runtimeEntityType.FindProperty("EnumToStringConverterProperty")!; - var enumU16 = runtimeEntityType.FindProperty("EnumU16")!; - var enumU16Array = runtimeEntityType.FindProperty("EnumU16Array")!; - var enumU16AsString = runtimeEntityType.FindProperty("EnumU16AsString")!; - var enumU16AsStringArray = runtimeEntityType.FindProperty("EnumU16AsStringArray")!; - var enumU16AsStringCollection = runtimeEntityType.FindProperty("EnumU16AsStringCollection")!; - var enumU16Collection = runtimeEntityType.FindProperty("EnumU16Collection")!; - var enumU32 = runtimeEntityType.FindProperty("EnumU32")!; - var enumU32Array = runtimeEntityType.FindProperty("EnumU32Array")!; - var enumU32AsString = runtimeEntityType.FindProperty("EnumU32AsString")!; - var enumU32AsStringArray = runtimeEntityType.FindProperty("EnumU32AsStringArray")!; - var enumU32AsStringCollection = runtimeEntityType.FindProperty("EnumU32AsStringCollection")!; - var enumU32Collection = runtimeEntityType.FindProperty("EnumU32Collection")!; - var enumU64 = runtimeEntityType.FindProperty("EnumU64")!; - var enumU64Array = runtimeEntityType.FindProperty("EnumU64Array")!; - var enumU64AsString = runtimeEntityType.FindProperty("EnumU64AsString")!; - var enumU64AsStringArray = runtimeEntityType.FindProperty("EnumU64AsStringArray")!; - var enumU64AsStringCollection = runtimeEntityType.FindProperty("EnumU64AsStringCollection")!; - var enumU64Collection = runtimeEntityType.FindProperty("EnumU64Collection")!; - var enumU8 = runtimeEntityType.FindProperty("EnumU8")!; - var enumU8Array = runtimeEntityType.FindProperty("EnumU8Array")!; - var enumU8AsString = runtimeEntityType.FindProperty("EnumU8AsString")!; - var enumU8AsStringArray = runtimeEntityType.FindProperty("EnumU8AsStringArray")!; - var enumU8AsStringCollection = runtimeEntityType.FindProperty("EnumU8AsStringCollection")!; - var enumU8Collection = runtimeEntityType.FindProperty("EnumU8Collection")!; - var @float = runtimeEntityType.FindProperty("Float")!; - var floatArray = runtimeEntityType.FindProperty("FloatArray")!; - var guid = runtimeEntityType.FindProperty("Guid")!; - var guidArray = runtimeEntityType.FindProperty("GuidArray")!; - var guidToBytesConverterProperty = runtimeEntityType.FindProperty("GuidToBytesConverterProperty")!; - var guidToStringConverterProperty = runtimeEntityType.FindProperty("GuidToStringConverterProperty")!; - var iPAddress = runtimeEntityType.FindProperty("IPAddress")!; - var iPAddressArray = runtimeEntityType.FindProperty("IPAddressArray")!; - var iPAddressToBytesConverterProperty = runtimeEntityType.FindProperty("IPAddressToBytesConverterProperty")!; - var iPAddressToStringConverterProperty = runtimeEntityType.FindProperty("IPAddressToStringConverterProperty")!; - var int16 = runtimeEntityType.FindProperty("Int16")!; - var int16Array = runtimeEntityType.FindProperty("Int16Array")!; - var int32 = runtimeEntityType.FindProperty("Int32")!; - var int32Array = runtimeEntityType.FindProperty("Int32Array")!; - var int64 = runtimeEntityType.FindProperty("Int64")!; - var int64Array = runtimeEntityType.FindProperty("Int64Array")!; - var int8 = runtimeEntityType.FindProperty("Int8")!; - var int8Array = runtimeEntityType.FindProperty("Int8Array")!; - var intNumberToBytesConverterProperty = runtimeEntityType.FindProperty("IntNumberToBytesConverterProperty")!; - var intNumberToStringConverterProperty = runtimeEntityType.FindProperty("IntNumberToStringConverterProperty")!; - var nullIntToNullStringConverterProperty = runtimeEntityType.FindProperty("NullIntToNullStringConverterProperty")!; - var nullableBool = runtimeEntityType.FindProperty("NullableBool")!; - var nullableBoolArray = runtimeEntityType.FindProperty("NullableBoolArray")!; - var nullableBytes = runtimeEntityType.FindProperty("NullableBytes")!; - var nullableBytesArray = runtimeEntityType.FindProperty("NullableBytesArray")!; - var nullableChar = runtimeEntityType.FindProperty("NullableChar")!; - var nullableCharArray = runtimeEntityType.FindProperty("NullableCharArray")!; - var nullableDateOnly = runtimeEntityType.FindProperty("NullableDateOnly")!; - var nullableDateOnlyArray = runtimeEntityType.FindProperty("NullableDateOnlyArray")!; - var nullableDateTime = runtimeEntityType.FindProperty("NullableDateTime")!; - var nullableDateTimeArray = runtimeEntityType.FindProperty("NullableDateTimeArray")!; - var nullableDecimal = runtimeEntityType.FindProperty("NullableDecimal")!; - var nullableDecimalArray = runtimeEntityType.FindProperty("NullableDecimalArray")!; - var nullableDouble = runtimeEntityType.FindProperty("NullableDouble")!; - var nullableDoubleArray = runtimeEntityType.FindProperty("NullableDoubleArray")!; - var nullableEnum16 = runtimeEntityType.FindProperty("NullableEnum16")!; - var nullableEnum16Array = runtimeEntityType.FindProperty("NullableEnum16Array")!; - var nullableEnum16AsString = runtimeEntityType.FindProperty("NullableEnum16AsString")!; - var nullableEnum16AsStringArray = runtimeEntityType.FindProperty("NullableEnum16AsStringArray")!; - var nullableEnum16AsStringCollection = runtimeEntityType.FindProperty("NullableEnum16AsStringCollection")!; - var nullableEnum16Collection = runtimeEntityType.FindProperty("NullableEnum16Collection")!; - var nullableEnum32 = runtimeEntityType.FindProperty("NullableEnum32")!; - var nullableEnum32Array = runtimeEntityType.FindProperty("NullableEnum32Array")!; - var nullableEnum32AsString = runtimeEntityType.FindProperty("NullableEnum32AsString")!; - var nullableEnum32AsStringArray = runtimeEntityType.FindProperty("NullableEnum32AsStringArray")!; - var nullableEnum32AsStringCollection = runtimeEntityType.FindProperty("NullableEnum32AsStringCollection")!; - var nullableEnum32Collection = runtimeEntityType.FindProperty("NullableEnum32Collection")!; - var nullableEnum64 = runtimeEntityType.FindProperty("NullableEnum64")!; - var nullableEnum64Array = runtimeEntityType.FindProperty("NullableEnum64Array")!; - var nullableEnum64AsString = runtimeEntityType.FindProperty("NullableEnum64AsString")!; - var nullableEnum64AsStringArray = runtimeEntityType.FindProperty("NullableEnum64AsStringArray")!; - var nullableEnum64AsStringCollection = runtimeEntityType.FindProperty("NullableEnum64AsStringCollection")!; - var nullableEnum64Collection = runtimeEntityType.FindProperty("NullableEnum64Collection")!; - var nullableEnum8 = runtimeEntityType.FindProperty("NullableEnum8")!; - var nullableEnum8Array = runtimeEntityType.FindProperty("NullableEnum8Array")!; - var nullableEnum8AsString = runtimeEntityType.FindProperty("NullableEnum8AsString")!; - var nullableEnum8AsStringArray = runtimeEntityType.FindProperty("NullableEnum8AsStringArray")!; - var nullableEnum8AsStringCollection = runtimeEntityType.FindProperty("NullableEnum8AsStringCollection")!; - var nullableEnum8Collection = runtimeEntityType.FindProperty("NullableEnum8Collection")!; - var nullableEnumU16 = runtimeEntityType.FindProperty("NullableEnumU16")!; - var nullableEnumU16Array = runtimeEntityType.FindProperty("NullableEnumU16Array")!; - var nullableEnumU16AsString = runtimeEntityType.FindProperty("NullableEnumU16AsString")!; - var nullableEnumU16AsStringArray = runtimeEntityType.FindProperty("NullableEnumU16AsStringArray")!; - var nullableEnumU16AsStringCollection = runtimeEntityType.FindProperty("NullableEnumU16AsStringCollection")!; - var nullableEnumU16Collection = runtimeEntityType.FindProperty("NullableEnumU16Collection")!; - var nullableEnumU32 = runtimeEntityType.FindProperty("NullableEnumU32")!; - var nullableEnumU32Array = runtimeEntityType.FindProperty("NullableEnumU32Array")!; - var nullableEnumU32AsString = runtimeEntityType.FindProperty("NullableEnumU32AsString")!; - var nullableEnumU32AsStringArray = runtimeEntityType.FindProperty("NullableEnumU32AsStringArray")!; - var nullableEnumU32AsStringCollection = runtimeEntityType.FindProperty("NullableEnumU32AsStringCollection")!; - var nullableEnumU32Collection = runtimeEntityType.FindProperty("NullableEnumU32Collection")!; - var nullableEnumU64 = runtimeEntityType.FindProperty("NullableEnumU64")!; - var nullableEnumU64Array = runtimeEntityType.FindProperty("NullableEnumU64Array")!; - var nullableEnumU64AsString = runtimeEntityType.FindProperty("NullableEnumU64AsString")!; - var nullableEnumU64AsStringArray = runtimeEntityType.FindProperty("NullableEnumU64AsStringArray")!; - var nullableEnumU64AsStringCollection = runtimeEntityType.FindProperty("NullableEnumU64AsStringCollection")!; - var nullableEnumU64Collection = runtimeEntityType.FindProperty("NullableEnumU64Collection")!; - var nullableEnumU8 = runtimeEntityType.FindProperty("NullableEnumU8")!; - var nullableEnumU8Array = runtimeEntityType.FindProperty("NullableEnumU8Array")!; - var nullableEnumU8AsString = runtimeEntityType.FindProperty("NullableEnumU8AsString")!; - var nullableEnumU8AsStringArray = runtimeEntityType.FindProperty("NullableEnumU8AsStringArray")!; - var nullableEnumU8AsStringCollection = runtimeEntityType.FindProperty("NullableEnumU8AsStringCollection")!; - var nullableEnumU8Collection = runtimeEntityType.FindProperty("NullableEnumU8Collection")!; - var nullableFloat = runtimeEntityType.FindProperty("NullableFloat")!; - var nullableFloatArray = runtimeEntityType.FindProperty("NullableFloatArray")!; - var nullableGuid = runtimeEntityType.FindProperty("NullableGuid")!; - var nullableGuidArray = runtimeEntityType.FindProperty("NullableGuidArray")!; - var nullableIPAddress = runtimeEntityType.FindProperty("NullableIPAddress")!; - var nullableIPAddressArray = runtimeEntityType.FindProperty("NullableIPAddressArray")!; - var nullableInt16 = runtimeEntityType.FindProperty("NullableInt16")!; - var nullableInt16Array = runtimeEntityType.FindProperty("NullableInt16Array")!; - var nullableInt32 = runtimeEntityType.FindProperty("NullableInt32")!; - var nullableInt32Array = runtimeEntityType.FindProperty("NullableInt32Array")!; - var nullableInt64 = runtimeEntityType.FindProperty("NullableInt64")!; - var nullableInt64Array = runtimeEntityType.FindProperty("NullableInt64Array")!; - var nullableInt8 = runtimeEntityType.FindProperty("NullableInt8")!; - var nullableInt8Array = runtimeEntityType.FindProperty("NullableInt8Array")!; - var nullablePhysicalAddress = runtimeEntityType.FindProperty("NullablePhysicalAddress")!; - var nullablePhysicalAddressArray = runtimeEntityType.FindProperty("NullablePhysicalAddressArray")!; - var nullableString = runtimeEntityType.FindProperty("NullableString")!; - var nullableStringArray = runtimeEntityType.FindProperty("NullableStringArray")!; - var nullableTimeOnly = runtimeEntityType.FindProperty("NullableTimeOnly")!; - var nullableTimeOnlyArray = runtimeEntityType.FindProperty("NullableTimeOnlyArray")!; - var nullableTimeSpan = runtimeEntityType.FindProperty("NullableTimeSpan")!; - var nullableTimeSpanArray = runtimeEntityType.FindProperty("NullableTimeSpanArray")!; - var nullableUInt16 = runtimeEntityType.FindProperty("NullableUInt16")!; - var nullableUInt16Array = runtimeEntityType.FindProperty("NullableUInt16Array")!; - var nullableUInt32 = runtimeEntityType.FindProperty("NullableUInt32")!; - var nullableUInt32Array = runtimeEntityType.FindProperty("NullableUInt32Array")!; - var nullableUInt64 = runtimeEntityType.FindProperty("NullableUInt64")!; - var nullableUInt64Array = runtimeEntityType.FindProperty("NullableUInt64Array")!; - var nullableUInt8 = runtimeEntityType.FindProperty("NullableUInt8")!; - var nullableUInt8Array = runtimeEntityType.FindProperty("NullableUInt8Array")!; - var nullableUri = runtimeEntityType.FindProperty("NullableUri")!; - var nullableUriArray = runtimeEntityType.FindProperty("NullableUriArray")!; - var physicalAddress = runtimeEntityType.FindProperty("PhysicalAddress")!; - var physicalAddressArray = runtimeEntityType.FindProperty("PhysicalAddressArray")!; - var physicalAddressToBytesConverterProperty = runtimeEntityType.FindProperty("PhysicalAddressToBytesConverterProperty")!; - var physicalAddressToStringConverterProperty = runtimeEntityType.FindProperty("PhysicalAddressToStringConverterProperty")!; - var @string = runtimeEntityType.FindProperty("String")!; - var stringArray = runtimeEntityType.FindProperty("StringArray")!; - var stringToBoolConverterProperty = runtimeEntityType.FindProperty("StringToBoolConverterProperty")!; - var stringToBytesConverterProperty = runtimeEntityType.FindProperty("StringToBytesConverterProperty")!; - var stringToCharConverterProperty = runtimeEntityType.FindProperty("StringToCharConverterProperty")!; - var stringToDateOnlyConverterProperty = runtimeEntityType.FindProperty("StringToDateOnlyConverterProperty")!; - var stringToDateTimeConverterProperty = runtimeEntityType.FindProperty("StringToDateTimeConverterProperty")!; - var stringToDateTimeOffsetConverterProperty = runtimeEntityType.FindProperty("StringToDateTimeOffsetConverterProperty")!; - var stringToDecimalNumberConverterProperty = runtimeEntityType.FindProperty("StringToDecimalNumberConverterProperty")!; - var stringToDoubleNumberConverterProperty = runtimeEntityType.FindProperty("StringToDoubleNumberConverterProperty")!; - var stringToEnumConverterProperty = runtimeEntityType.FindProperty("StringToEnumConverterProperty")!; - var stringToGuidConverterProperty = runtimeEntityType.FindProperty("StringToGuidConverterProperty")!; - var stringToIntNumberConverterProperty = runtimeEntityType.FindProperty("StringToIntNumberConverterProperty")!; - var stringToTimeOnlyConverterProperty = runtimeEntityType.FindProperty("StringToTimeOnlyConverterProperty")!; - var stringToTimeSpanConverterProperty = runtimeEntityType.FindProperty("StringToTimeSpanConverterProperty")!; - var stringToUriConverterProperty = runtimeEntityType.FindProperty("StringToUriConverterProperty")!; - var timeOnly = runtimeEntityType.FindProperty("TimeOnly")!; - var timeOnlyArray = runtimeEntityType.FindProperty("TimeOnlyArray")!; - var timeOnlyToStringConverterProperty = runtimeEntityType.FindProperty("TimeOnlyToStringConverterProperty")!; - var timeOnlyToTicksConverterProperty = runtimeEntityType.FindProperty("TimeOnlyToTicksConverterProperty")!; - var timeSpan = runtimeEntityType.FindProperty("TimeSpan")!; - var timeSpanArray = runtimeEntityType.FindProperty("TimeSpanArray")!; - var timeSpanToStringConverterProperty = runtimeEntityType.FindProperty("TimeSpanToStringConverterProperty")!; - var timeSpanToTicksConverterProperty = runtimeEntityType.FindProperty("TimeSpanToTicksConverterProperty")!; - var uInt16 = runtimeEntityType.FindProperty("UInt16")!; - var uInt16Array = runtimeEntityType.FindProperty("UInt16Array")!; - var uInt32 = runtimeEntityType.FindProperty("UInt32")!; - var uInt32Array = runtimeEntityType.FindProperty("UInt32Array")!; - var uInt64 = runtimeEntityType.FindProperty("UInt64")!; - var uInt64Array = runtimeEntityType.FindProperty("UInt64Array")!; - var uInt8 = runtimeEntityType.FindProperty("UInt8")!; - var uInt8Array = runtimeEntityType.FindProperty("UInt8Array")!; - var uri = runtimeEntityType.FindProperty("Uri")!; - var uriArray = runtimeEntityType.FindProperty("UriArray")!; - var uriToStringConverterProperty = runtimeEntityType.FindProperty("UriToStringConverterProperty")!; + var id = runtimeEntityType.FindProperty("Id"); + var @bool = runtimeEntityType.FindProperty("Bool"); + var boolArray = runtimeEntityType.FindProperty("BoolArray"); + var boolToStringConverterProperty = runtimeEntityType.FindProperty("BoolToStringConverterProperty"); + var boolToTwoValuesConverterProperty = runtimeEntityType.FindProperty("BoolToTwoValuesConverterProperty"); + var boolToZeroOneConverterProperty = runtimeEntityType.FindProperty("BoolToZeroOneConverterProperty"); + var bytes = runtimeEntityType.FindProperty("Bytes"); + var bytesArray = runtimeEntityType.FindProperty("BytesArray"); + var bytesToStringConverterProperty = runtimeEntityType.FindProperty("BytesToStringConverterProperty"); + var castingConverterProperty = runtimeEntityType.FindProperty("CastingConverterProperty"); + var @char = runtimeEntityType.FindProperty("Char"); + var charArray = runtimeEntityType.FindProperty("CharArray"); + var charToStringConverterProperty = runtimeEntityType.FindProperty("CharToStringConverterProperty"); + var dateOnly = runtimeEntityType.FindProperty("DateOnly"); + var dateOnlyArray = runtimeEntityType.FindProperty("DateOnlyArray"); + var dateOnlyToStringConverterProperty = runtimeEntityType.FindProperty("DateOnlyToStringConverterProperty"); + var dateTime = runtimeEntityType.FindProperty("DateTime"); + var dateTimeArray = runtimeEntityType.FindProperty("DateTimeArray"); + var dateTimeOffsetToBinaryConverterProperty = runtimeEntityType.FindProperty("DateTimeOffsetToBinaryConverterProperty"); + var dateTimeOffsetToBytesConverterProperty = runtimeEntityType.FindProperty("DateTimeOffsetToBytesConverterProperty"); + var dateTimeOffsetToStringConverterProperty = runtimeEntityType.FindProperty("DateTimeOffsetToStringConverterProperty"); + var dateTimeToBinaryConverterProperty = runtimeEntityType.FindProperty("DateTimeToBinaryConverterProperty"); + var dateTimeToStringConverterProperty = runtimeEntityType.FindProperty("DateTimeToStringConverterProperty"); + var dateTimeToTicksConverterProperty = runtimeEntityType.FindProperty("DateTimeToTicksConverterProperty"); + var @decimal = runtimeEntityType.FindProperty("Decimal"); + var decimalArray = runtimeEntityType.FindProperty("DecimalArray"); + var decimalNumberToBytesConverterProperty = runtimeEntityType.FindProperty("DecimalNumberToBytesConverterProperty"); + var decimalNumberToStringConverterProperty = runtimeEntityType.FindProperty("DecimalNumberToStringConverterProperty"); + var @double = runtimeEntityType.FindProperty("Double"); + var doubleArray = runtimeEntityType.FindProperty("DoubleArray"); + var doubleNumberToBytesConverterProperty = runtimeEntityType.FindProperty("DoubleNumberToBytesConverterProperty"); + var doubleNumberToStringConverterProperty = runtimeEntityType.FindProperty("DoubleNumberToStringConverterProperty"); + var enum16 = runtimeEntityType.FindProperty("Enum16"); + var enum16Array = runtimeEntityType.FindProperty("Enum16Array"); + var enum16AsString = runtimeEntityType.FindProperty("Enum16AsString"); + var enum16AsStringArray = runtimeEntityType.FindProperty("Enum16AsStringArray"); + var enum16AsStringCollection = runtimeEntityType.FindProperty("Enum16AsStringCollection"); + var enum16Collection = runtimeEntityType.FindProperty("Enum16Collection"); + var enum32 = runtimeEntityType.FindProperty("Enum32"); + var enum32Array = runtimeEntityType.FindProperty("Enum32Array"); + var enum32AsString = runtimeEntityType.FindProperty("Enum32AsString"); + var enum32AsStringArray = runtimeEntityType.FindProperty("Enum32AsStringArray"); + var enum32AsStringCollection = runtimeEntityType.FindProperty("Enum32AsStringCollection"); + var enum32Collection = runtimeEntityType.FindProperty("Enum32Collection"); + var enum64 = runtimeEntityType.FindProperty("Enum64"); + var enum64Array = runtimeEntityType.FindProperty("Enum64Array"); + var enum64AsString = runtimeEntityType.FindProperty("Enum64AsString"); + var enum64AsStringArray = runtimeEntityType.FindProperty("Enum64AsStringArray"); + var enum64AsStringCollection = runtimeEntityType.FindProperty("Enum64AsStringCollection"); + var enum64Collection = runtimeEntityType.FindProperty("Enum64Collection"); + var enum8 = runtimeEntityType.FindProperty("Enum8"); + var enum8Array = runtimeEntityType.FindProperty("Enum8Array"); + var enum8AsString = runtimeEntityType.FindProperty("Enum8AsString"); + var enum8AsStringArray = runtimeEntityType.FindProperty("Enum8AsStringArray"); + var enum8AsStringCollection = runtimeEntityType.FindProperty("Enum8AsStringCollection"); + var enum8Collection = runtimeEntityType.FindProperty("Enum8Collection"); + var enumToNumberConverterProperty = runtimeEntityType.FindProperty("EnumToNumberConverterProperty"); + var enumToStringConverterProperty = runtimeEntityType.FindProperty("EnumToStringConverterProperty"); + var enumU16 = runtimeEntityType.FindProperty("EnumU16"); + var enumU16Array = runtimeEntityType.FindProperty("EnumU16Array"); + var enumU16AsString = runtimeEntityType.FindProperty("EnumU16AsString"); + var enumU16AsStringArray = runtimeEntityType.FindProperty("EnumU16AsStringArray"); + var enumU16AsStringCollection = runtimeEntityType.FindProperty("EnumU16AsStringCollection"); + var enumU16Collection = runtimeEntityType.FindProperty("EnumU16Collection"); + var enumU32 = runtimeEntityType.FindProperty("EnumU32"); + var enumU32Array = runtimeEntityType.FindProperty("EnumU32Array"); + var enumU32AsString = runtimeEntityType.FindProperty("EnumU32AsString"); + var enumU32AsStringArray = runtimeEntityType.FindProperty("EnumU32AsStringArray"); + var enumU32AsStringCollection = runtimeEntityType.FindProperty("EnumU32AsStringCollection"); + var enumU32Collection = runtimeEntityType.FindProperty("EnumU32Collection"); + var enumU64 = runtimeEntityType.FindProperty("EnumU64"); + var enumU64Array = runtimeEntityType.FindProperty("EnumU64Array"); + var enumU64AsString = runtimeEntityType.FindProperty("EnumU64AsString"); + var enumU64AsStringArray = runtimeEntityType.FindProperty("EnumU64AsStringArray"); + var enumU64AsStringCollection = runtimeEntityType.FindProperty("EnumU64AsStringCollection"); + var enumU64Collection = runtimeEntityType.FindProperty("EnumU64Collection"); + var enumU8 = runtimeEntityType.FindProperty("EnumU8"); + var enumU8Array = runtimeEntityType.FindProperty("EnumU8Array"); + var enumU8AsString = runtimeEntityType.FindProperty("EnumU8AsString"); + var enumU8AsStringArray = runtimeEntityType.FindProperty("EnumU8AsStringArray"); + var enumU8AsStringCollection = runtimeEntityType.FindProperty("EnumU8AsStringCollection"); + var enumU8Collection = runtimeEntityType.FindProperty("EnumU8Collection"); + var @float = runtimeEntityType.FindProperty("Float"); + var floatArray = runtimeEntityType.FindProperty("FloatArray"); + var guid = runtimeEntityType.FindProperty("Guid"); + var guidArray = runtimeEntityType.FindProperty("GuidArray"); + var guidToBytesConverterProperty = runtimeEntityType.FindProperty("GuidToBytesConverterProperty"); + var guidToStringConverterProperty = runtimeEntityType.FindProperty("GuidToStringConverterProperty"); + var iPAddress = runtimeEntityType.FindProperty("IPAddress"); + var iPAddressArray = runtimeEntityType.FindProperty("IPAddressArray"); + var iPAddressToBytesConverterProperty = runtimeEntityType.FindProperty("IPAddressToBytesConverterProperty"); + var iPAddressToStringConverterProperty = runtimeEntityType.FindProperty("IPAddressToStringConverterProperty"); + var int16 = runtimeEntityType.FindProperty("Int16"); + var int16Array = runtimeEntityType.FindProperty("Int16Array"); + var int32 = runtimeEntityType.FindProperty("Int32"); + var int32Array = runtimeEntityType.FindProperty("Int32Array"); + var int64 = runtimeEntityType.FindProperty("Int64"); + var int64Array = runtimeEntityType.FindProperty("Int64Array"); + var int8 = runtimeEntityType.FindProperty("Int8"); + var int8Array = runtimeEntityType.FindProperty("Int8Array"); + var intNumberToBytesConverterProperty = runtimeEntityType.FindProperty("IntNumberToBytesConverterProperty"); + var intNumberToStringConverterProperty = runtimeEntityType.FindProperty("IntNumberToStringConverterProperty"); + var nullIntToNullStringConverterProperty = runtimeEntityType.FindProperty("NullIntToNullStringConverterProperty"); + var nullableBool = runtimeEntityType.FindProperty("NullableBool"); + var nullableBoolArray = runtimeEntityType.FindProperty("NullableBoolArray"); + var nullableBytes = runtimeEntityType.FindProperty("NullableBytes"); + var nullableBytesArray = runtimeEntityType.FindProperty("NullableBytesArray"); + var nullableChar = runtimeEntityType.FindProperty("NullableChar"); + var nullableCharArray = runtimeEntityType.FindProperty("NullableCharArray"); + var nullableDateOnly = runtimeEntityType.FindProperty("NullableDateOnly"); + var nullableDateOnlyArray = runtimeEntityType.FindProperty("NullableDateOnlyArray"); + var nullableDateTime = runtimeEntityType.FindProperty("NullableDateTime"); + var nullableDateTimeArray = runtimeEntityType.FindProperty("NullableDateTimeArray"); + var nullableDecimal = runtimeEntityType.FindProperty("NullableDecimal"); + var nullableDecimalArray = runtimeEntityType.FindProperty("NullableDecimalArray"); + var nullableDouble = runtimeEntityType.FindProperty("NullableDouble"); + var nullableDoubleArray = runtimeEntityType.FindProperty("NullableDoubleArray"); + var nullableEnum16 = runtimeEntityType.FindProperty("NullableEnum16"); + var nullableEnum16Array = runtimeEntityType.FindProperty("NullableEnum16Array"); + var nullableEnum16AsString = runtimeEntityType.FindProperty("NullableEnum16AsString"); + var nullableEnum16AsStringArray = runtimeEntityType.FindProperty("NullableEnum16AsStringArray"); + var nullableEnum16AsStringCollection = runtimeEntityType.FindProperty("NullableEnum16AsStringCollection"); + var nullableEnum16Collection = runtimeEntityType.FindProperty("NullableEnum16Collection"); + var nullableEnum32 = runtimeEntityType.FindProperty("NullableEnum32"); + var nullableEnum32Array = runtimeEntityType.FindProperty("NullableEnum32Array"); + var nullableEnum32AsString = runtimeEntityType.FindProperty("NullableEnum32AsString"); + var nullableEnum32AsStringArray = runtimeEntityType.FindProperty("NullableEnum32AsStringArray"); + var nullableEnum32AsStringCollection = runtimeEntityType.FindProperty("NullableEnum32AsStringCollection"); + var nullableEnum32Collection = runtimeEntityType.FindProperty("NullableEnum32Collection"); + var nullableEnum64 = runtimeEntityType.FindProperty("NullableEnum64"); + var nullableEnum64Array = runtimeEntityType.FindProperty("NullableEnum64Array"); + var nullableEnum64AsString = runtimeEntityType.FindProperty("NullableEnum64AsString"); + var nullableEnum64AsStringArray = runtimeEntityType.FindProperty("NullableEnum64AsStringArray"); + var nullableEnum64AsStringCollection = runtimeEntityType.FindProperty("NullableEnum64AsStringCollection"); + var nullableEnum64Collection = runtimeEntityType.FindProperty("NullableEnum64Collection"); + var nullableEnum8 = runtimeEntityType.FindProperty("NullableEnum8"); + var nullableEnum8Array = runtimeEntityType.FindProperty("NullableEnum8Array"); + var nullableEnum8AsString = runtimeEntityType.FindProperty("NullableEnum8AsString"); + var nullableEnum8AsStringArray = runtimeEntityType.FindProperty("NullableEnum8AsStringArray"); + var nullableEnum8AsStringCollection = runtimeEntityType.FindProperty("NullableEnum8AsStringCollection"); + var nullableEnum8Collection = runtimeEntityType.FindProperty("NullableEnum8Collection"); + var nullableEnumU16 = runtimeEntityType.FindProperty("NullableEnumU16"); + var nullableEnumU16Array = runtimeEntityType.FindProperty("NullableEnumU16Array"); + var nullableEnumU16AsString = runtimeEntityType.FindProperty("NullableEnumU16AsString"); + var nullableEnumU16AsStringArray = runtimeEntityType.FindProperty("NullableEnumU16AsStringArray"); + var nullableEnumU16AsStringCollection = runtimeEntityType.FindProperty("NullableEnumU16AsStringCollection"); + var nullableEnumU16Collection = runtimeEntityType.FindProperty("NullableEnumU16Collection"); + var nullableEnumU32 = runtimeEntityType.FindProperty("NullableEnumU32"); + var nullableEnumU32Array = runtimeEntityType.FindProperty("NullableEnumU32Array"); + var nullableEnumU32AsString = runtimeEntityType.FindProperty("NullableEnumU32AsString"); + var nullableEnumU32AsStringArray = runtimeEntityType.FindProperty("NullableEnumU32AsStringArray"); + var nullableEnumU32AsStringCollection = runtimeEntityType.FindProperty("NullableEnumU32AsStringCollection"); + var nullableEnumU32Collection = runtimeEntityType.FindProperty("NullableEnumU32Collection"); + var nullableEnumU64 = runtimeEntityType.FindProperty("NullableEnumU64"); + var nullableEnumU64Array = runtimeEntityType.FindProperty("NullableEnumU64Array"); + var nullableEnumU64AsString = runtimeEntityType.FindProperty("NullableEnumU64AsString"); + var nullableEnumU64AsStringArray = runtimeEntityType.FindProperty("NullableEnumU64AsStringArray"); + var nullableEnumU64AsStringCollection = runtimeEntityType.FindProperty("NullableEnumU64AsStringCollection"); + var nullableEnumU64Collection = runtimeEntityType.FindProperty("NullableEnumU64Collection"); + var nullableEnumU8 = runtimeEntityType.FindProperty("NullableEnumU8"); + var nullableEnumU8Array = runtimeEntityType.FindProperty("NullableEnumU8Array"); + var nullableEnumU8AsString = runtimeEntityType.FindProperty("NullableEnumU8AsString"); + var nullableEnumU8AsStringArray = runtimeEntityType.FindProperty("NullableEnumU8AsStringArray"); + var nullableEnumU8AsStringCollection = runtimeEntityType.FindProperty("NullableEnumU8AsStringCollection"); + var nullableEnumU8Collection = runtimeEntityType.FindProperty("NullableEnumU8Collection"); + var nullableFloat = runtimeEntityType.FindProperty("NullableFloat"); + var nullableFloatArray = runtimeEntityType.FindProperty("NullableFloatArray"); + var nullableGuid = runtimeEntityType.FindProperty("NullableGuid"); + var nullableGuidArray = runtimeEntityType.FindProperty("NullableGuidArray"); + var nullableIPAddress = runtimeEntityType.FindProperty("NullableIPAddress"); + var nullableIPAddressArray = runtimeEntityType.FindProperty("NullableIPAddressArray"); + var nullableInt16 = runtimeEntityType.FindProperty("NullableInt16"); + var nullableInt16Array = runtimeEntityType.FindProperty("NullableInt16Array"); + var nullableInt32 = runtimeEntityType.FindProperty("NullableInt32"); + var nullableInt32Array = runtimeEntityType.FindProperty("NullableInt32Array"); + var nullableInt64 = runtimeEntityType.FindProperty("NullableInt64"); + var nullableInt64Array = runtimeEntityType.FindProperty("NullableInt64Array"); + var nullableInt8 = runtimeEntityType.FindProperty("NullableInt8"); + var nullableInt8Array = runtimeEntityType.FindProperty("NullableInt8Array"); + var nullablePhysicalAddress = runtimeEntityType.FindProperty("NullablePhysicalAddress"); + var nullablePhysicalAddressArray = runtimeEntityType.FindProperty("NullablePhysicalAddressArray"); + var nullableString = runtimeEntityType.FindProperty("NullableString"); + var nullableStringArray = runtimeEntityType.FindProperty("NullableStringArray"); + var nullableTimeOnly = runtimeEntityType.FindProperty("NullableTimeOnly"); + var nullableTimeOnlyArray = runtimeEntityType.FindProperty("NullableTimeOnlyArray"); + var nullableTimeSpan = runtimeEntityType.FindProperty("NullableTimeSpan"); + var nullableTimeSpanArray = runtimeEntityType.FindProperty("NullableTimeSpanArray"); + var nullableUInt16 = runtimeEntityType.FindProperty("NullableUInt16"); + var nullableUInt16Array = runtimeEntityType.FindProperty("NullableUInt16Array"); + var nullableUInt32 = runtimeEntityType.FindProperty("NullableUInt32"); + var nullableUInt32Array = runtimeEntityType.FindProperty("NullableUInt32Array"); + var nullableUInt64 = runtimeEntityType.FindProperty("NullableUInt64"); + var nullableUInt64Array = runtimeEntityType.FindProperty("NullableUInt64Array"); + var nullableUInt8 = runtimeEntityType.FindProperty("NullableUInt8"); + var nullableUInt8Array = runtimeEntityType.FindProperty("NullableUInt8Array"); + var nullableUri = runtimeEntityType.FindProperty("NullableUri"); + var nullableUriArray = runtimeEntityType.FindProperty("NullableUriArray"); + var physicalAddress = runtimeEntityType.FindProperty("PhysicalAddress"); + var physicalAddressArray = runtimeEntityType.FindProperty("PhysicalAddressArray"); + var physicalAddressToBytesConverterProperty = runtimeEntityType.FindProperty("PhysicalAddressToBytesConverterProperty"); + var physicalAddressToStringConverterProperty = runtimeEntityType.FindProperty("PhysicalAddressToStringConverterProperty"); + var @string = runtimeEntityType.FindProperty("String"); + var stringArray = runtimeEntityType.FindProperty("StringArray"); + var stringToBoolConverterProperty = runtimeEntityType.FindProperty("StringToBoolConverterProperty"); + var stringToBytesConverterProperty = runtimeEntityType.FindProperty("StringToBytesConverterProperty"); + var stringToCharConverterProperty = runtimeEntityType.FindProperty("StringToCharConverterProperty"); + var stringToDateOnlyConverterProperty = runtimeEntityType.FindProperty("StringToDateOnlyConverterProperty"); + var stringToDateTimeConverterProperty = runtimeEntityType.FindProperty("StringToDateTimeConverterProperty"); + var stringToDateTimeOffsetConverterProperty = runtimeEntityType.FindProperty("StringToDateTimeOffsetConverterProperty"); + var stringToDecimalNumberConverterProperty = runtimeEntityType.FindProperty("StringToDecimalNumberConverterProperty"); + var stringToDoubleNumberConverterProperty = runtimeEntityType.FindProperty("StringToDoubleNumberConverterProperty"); + var stringToEnumConverterProperty = runtimeEntityType.FindProperty("StringToEnumConverterProperty"); + var stringToGuidConverterProperty = runtimeEntityType.FindProperty("StringToGuidConverterProperty"); + var stringToIntNumberConverterProperty = runtimeEntityType.FindProperty("StringToIntNumberConverterProperty"); + var stringToTimeOnlyConverterProperty = runtimeEntityType.FindProperty("StringToTimeOnlyConverterProperty"); + var stringToTimeSpanConverterProperty = runtimeEntityType.FindProperty("StringToTimeSpanConverterProperty"); + var stringToUriConverterProperty = runtimeEntityType.FindProperty("StringToUriConverterProperty"); + var timeOnly = runtimeEntityType.FindProperty("TimeOnly"); + var timeOnlyArray = runtimeEntityType.FindProperty("TimeOnlyArray"); + var timeOnlyToStringConverterProperty = runtimeEntityType.FindProperty("TimeOnlyToStringConverterProperty"); + var timeOnlyToTicksConverterProperty = runtimeEntityType.FindProperty("TimeOnlyToTicksConverterProperty"); + var timeSpan = runtimeEntityType.FindProperty("TimeSpan"); + var timeSpanArray = runtimeEntityType.FindProperty("TimeSpanArray"); + var timeSpanToStringConverterProperty = runtimeEntityType.FindProperty("TimeSpanToStringConverterProperty"); + var timeSpanToTicksConverterProperty = runtimeEntityType.FindProperty("TimeSpanToTicksConverterProperty"); + var uInt16 = runtimeEntityType.FindProperty("UInt16"); + var uInt16Array = runtimeEntityType.FindProperty("UInt16Array"); + var uInt32 = runtimeEntityType.FindProperty("UInt32"); + var uInt32Array = runtimeEntityType.FindProperty("UInt32Array"); + var uInt64 = runtimeEntityType.FindProperty("UInt64"); + var uInt64Array = runtimeEntityType.FindProperty("UInt64Array"); + var uInt8 = runtimeEntityType.FindProperty("UInt8"); + var uInt8Array = runtimeEntityType.FindProperty("UInt8Array"); + var uri = runtimeEntityType.FindProperty("Uri"); + var uriArray = runtimeEntityType.FindProperty("UriArray"); + var uriToStringConverterProperty = runtimeEntityType.FindProperty("UriToStringConverterProperty"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedType0EntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedType0EntityType.cs index bb6ac5f6f83..aecb144873f 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedType0EntityType.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedType0EntityType.cs @@ -856,19 +856,19 @@ public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEnt public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var principalDerivedId = runtimeEntityType.FindProperty("PrincipalDerivedId")!; - var principalDerivedAlternateId = runtimeEntityType.FindProperty("PrincipalDerivedAlternateId")!; - var id = runtimeEntityType.FindProperty("Id")!; - var details = runtimeEntityType.FindProperty("Details")!; - var number = runtimeEntityType.FindProperty("Number")!; - var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray")!; - var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable")!; - var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList")!; - var refTypeList = runtimeEntityType.FindProperty("RefTypeList")!; - var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList")!; - var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList")!; + var principalDerivedId = runtimeEntityType.FindProperty("PrincipalDerivedId"); + var principalDerivedAlternateId = runtimeEntityType.FindProperty("PrincipalDerivedAlternateId"); + var id = runtimeEntityType.FindProperty("Id"); + var details = runtimeEntityType.FindProperty("Details"); + var number = runtimeEntityType.FindProperty("Number"); + var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray"); + var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable"); + var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList"); + var refTypeList = runtimeEntityType.FindProperty("RefTypeList"); + var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList"); + var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList"); var key = runtimeEntityType.FindKey(new[] { principalDerivedId, principalDerivedAlternateId, id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateCompositeFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory>(key)); diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedTypeEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedTypeEntityType.cs index e18976c80b2..58454e04fd9 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedTypeEntityType.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedTypeEntityType.cs @@ -868,18 +868,18 @@ public static RuntimeForeignKey CreateForeignKey2(RuntimeEntityType declaringEnt public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var principalBaseId = runtimeEntityType.FindProperty("PrincipalBaseId")!; - var principalBaseAlternateId = runtimeEntityType.FindProperty("PrincipalBaseAlternateId")!; - var details = runtimeEntityType.FindProperty("Details")!; - var number = runtimeEntityType.FindProperty("Number")!; - var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray")!; - var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable")!; - var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList")!; - var refTypeList = runtimeEntityType.FindProperty("RefTypeList")!; - var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList")!; - var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList")!; + var principalBaseId = runtimeEntityType.FindProperty("PrincipalBaseId"); + var principalBaseAlternateId = runtimeEntityType.FindProperty("PrincipalBaseAlternateId"); + var details = runtimeEntityType.FindProperty("Details"); + var number = runtimeEntityType.FindProperty("Number"); + var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray"); + var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable"); + var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList"); + var refTypeList = runtimeEntityType.FindProperty("RefTypeList"); + var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList"); + var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList"); var key = runtimeEntityType.FindKey(new[] { principalBaseId, principalBaseAlternateId }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateCompositeFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory>(key)); diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBaseEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBaseEntityType.cs index c00c76d4544..59869dd8c15 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBaseEntityType.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBaseEntityType.cs @@ -78,9 +78,9 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (long v1, long v2) => v1 == v2, int (long v) => ((object)v).GetHashCode(), long (long v) => v)); - id.SetValueComparer(new NullableValueComparer(id.TypeMapping.Comparer)); - id.SetKeyValueComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); id.SetCurrentValueComparer(new EntryCurrentValueComparer(id)); + id.SetComparer(new NullableValueComparer(id.TypeMapping.Comparer)); + id.SetKeyComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); var overrides = new StoreObjectDictionary(); var idPrincipalDerived = new RuntimeRelationalPropertyOverrides( @@ -238,8 +238,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( int (CompiledModelTestBase.AnEnum value) => ((int)(value)), CompiledModelTestBase.AnEnum (int value) => ((CompiledModelTestBase.AnEnum)(value))))); - enum2.SetValueComparer(new NullableValueComparer(enum2.TypeMapping.Comparer)); - enum2.SetKeyValueComparer(new NullableValueComparer(enum2.TypeMapping.KeyComparer)); + enum2.SetComparer(new NullableValueComparer(enum2.TypeMapping.Comparer)); + enum2.SetKeyComparer(new NullableValueComparer(enum2.TypeMapping.KeyComparer)); enum2.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var flagsEnum1 = runtimeEntityType.AddProperty( @@ -975,27 +975,27 @@ public static RuntimeSkipNavigation CreateSkipNavigation1(RuntimeEntityType decl public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var alternateId = runtimeEntityType.FindProperty("AlternateId")!; - var enum1 = runtimeEntityType.FindProperty("Enum1")!; - var enum2 = runtimeEntityType.FindProperty("Enum2")!; - var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1")!; - var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2")!; - var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray")!; - var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable")!; - var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList")!; - var refTypeList = runtimeEntityType.FindProperty("RefTypeList")!; - var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList")!; - var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList")!; + var id = runtimeEntityType.FindProperty("Id"); + var alternateId = runtimeEntityType.FindProperty("AlternateId"); + var enum1 = runtimeEntityType.FindProperty("Enum1"); + var enum2 = runtimeEntityType.FindProperty("Enum2"); + var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1"); + var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2"); + var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray"); + var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable"); + var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList"); + var refTypeList = runtimeEntityType.FindProperty("RefTypeList"); + var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList"); + var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); var key0 = runtimeEntityType.FindKey(new[] { id, alternateId }); key0.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateCompositeFactory(key0)); key0.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory>(key0)); - var owned = runtimeEntityType.FindNavigation("Owned")!; + var owned = runtimeEntityType.FindNavigation("Owned"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { @@ -1014,7 +1014,7 @@ public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) ISnapshot (InternalEntityEntry source) => { var entity7 = ((CompiledModelTestBase.PrincipalBase)(source.Entity)); - return ((ISnapshot)(new Snapshot((source.GetCurrentValue(id) == null ? null : ((ValueComparer)(((IProperty)id).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(id))), ((ValueComparer)(((IProperty)alternateId).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(alternateId)), PrincipalBaseUnsafeAccessors._ownedField(entity7), null))); + return ((ISnapshot)(new Snapshot((source.GetCurrentValue(id) == null ? null : ((ValueComparer)(((IProperty)id).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(id))), ((ValueComparer)(((IProperty)alternateId).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(alternateId)), PrincipalBaseUnsafeAccessors._ownedField(entity7), (object)(null)))); }); runtimeEntityType.Counts = new PropertyCounts( propertyCount: 14, diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs index 1dfe2531b5f..762b316cf9a 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs @@ -386,11 +386,11 @@ public static RuntimeForeignKey CreateForeignKey2(RuntimeEntityType declaringEnt public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var derivedsId = runtimeEntityType.FindProperty("DerivedsId")!; - var derivedsAlternateId = runtimeEntityType.FindProperty("DerivedsAlternateId")!; - var principalsId = runtimeEntityType.FindProperty("PrincipalsId")!; - var principalsAlternateId = runtimeEntityType.FindProperty("PrincipalsAlternateId")!; - var rowid = runtimeEntityType.FindProperty("rowid")!; + var derivedsId = runtimeEntityType.FindProperty("DerivedsId"); + var derivedsAlternateId = runtimeEntityType.FindProperty("DerivedsAlternateId"); + var principalsId = runtimeEntityType.FindProperty("PrincipalsId"); + var principalsAlternateId = runtimeEntityType.FindProperty("PrincipalsAlternateId"); + var rowid = runtimeEntityType.FindProperty("rowid"); var key = runtimeEntityType.FindKey(new[] { derivedsId, derivedsAlternateId, principalsId, principalsAlternateId }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateCompositeFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory>(key)); diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalDerivedEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalDerivedEntityType.cs index fc5026f95d1..5de696ad512 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalDerivedEntityType.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalDerivedEntityType.cs @@ -100,23 +100,23 @@ public static RuntimeSkipNavigation CreateSkipNavigation1(RuntimeEntityType decl public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var alternateId = runtimeEntityType.FindProperty("AlternateId")!; - var enum1 = runtimeEntityType.FindProperty("Enum1")!; - var enum2 = runtimeEntityType.FindProperty("Enum2")!; - var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1")!; - var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2")!; - var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray")!; - var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable")!; - var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList")!; - var refTypeList = runtimeEntityType.FindProperty("RefTypeList")!; - var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList")!; - var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList")!; - var owned = runtimeEntityType.FindNavigation("Owned")!; - var dependent = runtimeEntityType.FindNavigation("Dependent")!; - var manyOwned = runtimeEntityType.FindNavigation("ManyOwned")!; + var id = runtimeEntityType.FindProperty("Id"); + var alternateId = runtimeEntityType.FindProperty("AlternateId"); + var enum1 = runtimeEntityType.FindProperty("Enum1"); + var enum2 = runtimeEntityType.FindProperty("Enum2"); + var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1"); + var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2"); + var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray"); + var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable"); + var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList"); + var refTypeList = runtimeEntityType.FindProperty("RefTypeList"); + var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList"); + var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList"); + var owned = runtimeEntityType.FindNavigation("Owned"); + var dependent = runtimeEntityType.FindNavigation("Dependent"); + var manyOwned = runtimeEntityType.FindNavigation("ManyOwned"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { @@ -135,7 +135,7 @@ public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) ISnapshot (InternalEntityEntry source) => { var entity7 = ((CompiledModelTestBase.PrincipalDerived>)(source.Entity)); - return ((ISnapshot)(new Snapshot((source.GetCurrentValue(id) == null ? null : ((ValueComparer)(((IProperty)id).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(id))), ((ValueComparer)(((IProperty)alternateId).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(alternateId)), PrincipalBaseUnsafeAccessors._ownedField(entity7), null, PrincipalDerivedUnsafeAccessors>.Dependent(entity7), SnapshotFactoryFactory.SnapshotCollection(PrincipalDerivedUnsafeAccessors>.ManyOwned(entity7)), null))); + return ((ISnapshot)(new Snapshot((source.GetCurrentValue(id) == null ? null : ((ValueComparer)(((IProperty)id).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(id))), ((ValueComparer)(((IProperty)alternateId).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(alternateId)), PrincipalBaseUnsafeAccessors._ownedField(entity7), (object)(null), PrincipalDerivedUnsafeAccessors>.Dependent(entity7), SnapshotFactoryFactory.SnapshotCollection(PrincipalDerivedUnsafeAccessors>.ManyOwned(entity7)), (object)(null)))); }); runtimeEntityType.Counts = new PropertyCounts( propertyCount: 14, diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/DependentBaseEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/DependentBaseEntityType.cs index 92f584448c3..29c9d8da74e 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/DependentBaseEntityType.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/DependentBaseEntityType.cs @@ -187,8 +187,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (byte v1, byte v2) => v1 == v2, int (byte v) => ((int)(v)), byte (byte v) => v)); - id.SetValueComparer(new NullableValueComparer(id.TypeMapping.Comparer)); - id.SetKeyValueComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); + id.SetComparer(new NullableValueComparer(id.TypeMapping.Comparer)); + id.SetKeyComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); id.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var key = runtimeEntityType.AddKey( @@ -286,14 +286,14 @@ public static RuntimeForeignKey CreateForeignKey2(RuntimeEntityType declaringEnt public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var principalId = runtimeEntityType.FindProperty("PrincipalId")!; - var principalAlternateId = runtimeEntityType.FindProperty("PrincipalAlternateId")!; - var enumDiscriminator = runtimeEntityType.FindProperty("EnumDiscriminator")!; - var id = runtimeEntityType.FindProperty("Id")!; + var principalId = runtimeEntityType.FindProperty("PrincipalId"); + var principalAlternateId = runtimeEntityType.FindProperty("PrincipalAlternateId"); + var enumDiscriminator = runtimeEntityType.FindProperty("EnumDiscriminator"); + var id = runtimeEntityType.FindProperty("Id"); var key = runtimeEntityType.FindKey(new[] { principalId, principalAlternateId }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateCompositeFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory>(key)); - var principal = runtimeEntityType.FindNavigation("Principal")!; + var principal = runtimeEntityType.FindNavigation("Principal"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/DependentDerivedEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/DependentDerivedEntityType.cs index ffaeb589c27..ebd7aee13f6 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/DependentDerivedEntityType.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/DependentDerivedEntityType.cs @@ -121,13 +121,13 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var principalId = runtimeEntityType.FindProperty("PrincipalId")!; - var principalAlternateId = runtimeEntityType.FindProperty("PrincipalAlternateId")!; - var enumDiscriminator = runtimeEntityType.FindProperty("EnumDiscriminator")!; - var id = runtimeEntityType.FindProperty("Id")!; - var data = runtimeEntityType.FindProperty("Data")!; - var money = runtimeEntityType.FindProperty("Money")!; - var principal = runtimeEntityType.FindNavigation("Principal")!; + var principalId = runtimeEntityType.FindProperty("PrincipalId"); + var principalAlternateId = runtimeEntityType.FindProperty("PrincipalAlternateId"); + var enumDiscriminator = runtimeEntityType.FindProperty("EnumDiscriminator"); + var id = runtimeEntityType.FindProperty("Id"); + var data = runtimeEntityType.FindProperty("Data"); + var money = runtimeEntityType.FindProperty("Money"); + var principal = runtimeEntityType.FindNavigation("Principal"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/ManyTypesEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/ManyTypesEntityType.cs index acf2fc670f0..7363b3af85d 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/ManyTypesEntityType.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/ManyTypesEntityType.cs @@ -6569,8 +6569,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (bool v1, bool v2) => v1 == v2, int (bool v) => ((object)v).GetHashCode(), bool (bool v) => v)); - nullableBool.SetValueComparer(new NullableValueComparer(nullableBool.TypeMapping.Comparer)); - nullableBool.SetKeyValueComparer(new NullableValueComparer(nullableBool.TypeMapping.KeyComparer)); + nullableBool.SetComparer(new NullableValueComparer(nullableBool.TypeMapping.Comparer)); + nullableBool.SetKeyComparer(new NullableValueComparer(nullableBool.TypeMapping.KeyComparer)); nullableBool.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableBoolArray = runtimeEntityType.AddProperty( @@ -6800,8 +6800,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( string (char v) => string.Format(CultureInfo.InvariantCulture, "{0}", ((object)(v))), char (string v) => (v.Length < 1 ? '\0' : v[0])))); - nullableChar.SetValueComparer(new NullableValueComparer(nullableChar.TypeMapping.Comparer)); - nullableChar.SetKeyValueComparer(new NullableValueComparer(nullableChar.TypeMapping.KeyComparer)); + nullableChar.SetComparer(new NullableValueComparer(nullableChar.TypeMapping.Comparer)); + nullableChar.SetKeyComparer(new NullableValueComparer(nullableChar.TypeMapping.KeyComparer)); nullableChar.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableCharArray = runtimeEntityType.AddProperty( @@ -6928,8 +6928,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (DateOnly v1, DateOnly v2) => v1.Equals(v2), int (DateOnly v) => ((object)v).GetHashCode(), DateOnly (DateOnly v) => v)); - nullableDateOnly.SetValueComparer(new NullableValueComparer(nullableDateOnly.TypeMapping.Comparer)); - nullableDateOnly.SetKeyValueComparer(new NullableValueComparer(nullableDateOnly.TypeMapping.KeyComparer)); + nullableDateOnly.SetComparer(new NullableValueComparer(nullableDateOnly.TypeMapping.Comparer)); + nullableDateOnly.SetKeyComparer(new NullableValueComparer(nullableDateOnly.TypeMapping.KeyComparer)); nullableDateOnly.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableDateOnlyArray = runtimeEntityType.AddProperty( @@ -7035,8 +7035,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (DateTime v1, DateTime v2) => v1.Equals(v2), int (DateTime v) => ((object)v).GetHashCode(), DateTime (DateTime v) => v)); - nullableDateTime.SetValueComparer(new NullableValueComparer(nullableDateTime.TypeMapping.Comparer)); - nullableDateTime.SetKeyValueComparer(new NullableValueComparer(nullableDateTime.TypeMapping.KeyComparer)); + nullableDateTime.SetComparer(new NullableValueComparer(nullableDateTime.TypeMapping.Comparer)); + nullableDateTime.SetKeyComparer(new NullableValueComparer(nullableDateTime.TypeMapping.KeyComparer)); nullableDateTime.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableDateTimeArray = runtimeEntityType.AddProperty( @@ -7142,8 +7142,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (decimal v1, decimal v2) => v1 == v2, int (decimal v) => ((object)v).GetHashCode(), decimal (decimal v) => v)); - nullableDecimal.SetValueComparer(new NullableValueComparer(nullableDecimal.TypeMapping.Comparer)); - nullableDecimal.SetKeyValueComparer(new NullableValueComparer(nullableDecimal.TypeMapping.KeyComparer)); + nullableDecimal.SetComparer(new NullableValueComparer(nullableDecimal.TypeMapping.Comparer)); + nullableDecimal.SetKeyComparer(new NullableValueComparer(nullableDecimal.TypeMapping.KeyComparer)); nullableDecimal.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableDecimalArray = runtimeEntityType.AddProperty( @@ -7249,8 +7249,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (double v1, double v2) => v1.Equals(v2), int (double v) => ((object)v).GetHashCode(), double (double v) => v)); - nullableDouble.SetValueComparer(new NullableValueComparer(nullableDouble.TypeMapping.Comparer)); - nullableDouble.SetKeyValueComparer(new NullableValueComparer(nullableDouble.TypeMapping.KeyComparer)); + nullableDouble.SetComparer(new NullableValueComparer(nullableDouble.TypeMapping.Comparer)); + nullableDouble.SetKeyComparer(new NullableValueComparer(nullableDouble.TypeMapping.KeyComparer)); nullableDouble.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableDoubleArray = runtimeEntityType.AddProperty( @@ -7364,8 +7364,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( short (CompiledModelTestBase.Enum16 value) => ((short)(value)), CompiledModelTestBase.Enum16 (short value) => ((CompiledModelTestBase.Enum16)(value))))); - nullableEnum16.SetValueComparer(new NullableValueComparer(nullableEnum16.TypeMapping.Comparer)); - nullableEnum16.SetKeyValueComparer(new NullableValueComparer(nullableEnum16.TypeMapping.KeyComparer)); + nullableEnum16.SetComparer(new NullableValueComparer(nullableEnum16.TypeMapping.Comparer)); + nullableEnum16.SetKeyComparer(new NullableValueComparer(nullableEnum16.TypeMapping.KeyComparer)); nullableEnum16.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableEnum16Array = runtimeEntityType.AddProperty( @@ -7495,8 +7495,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( short (CompiledModelTestBase.Enum16 value) => ((short)(value)), CompiledModelTestBase.Enum16 (short value) => ((CompiledModelTestBase.Enum16)(value))))); - nullableEnum16AsString.SetValueComparer(new NullableValueComparer(nullableEnum16AsString.TypeMapping.Comparer)); - nullableEnum16AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnum16AsString.TypeMapping.KeyComparer)); + nullableEnum16AsString.SetComparer(new NullableValueComparer(nullableEnum16AsString.TypeMapping.Comparer)); + nullableEnum16AsString.SetKeyComparer(new NullableValueComparer(nullableEnum16AsString.TypeMapping.KeyComparer)); nullableEnum16AsString.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableEnum16AsStringArray = runtimeEntityType.AddProperty( @@ -7784,8 +7784,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( int (CompiledModelTestBase.Enum32 value) => ((int)(value)), CompiledModelTestBase.Enum32 (int value) => ((CompiledModelTestBase.Enum32)(value))))); - nullableEnum32.SetValueComparer(new NullableValueComparer(nullableEnum32.TypeMapping.Comparer)); - nullableEnum32.SetKeyValueComparer(new NullableValueComparer(nullableEnum32.TypeMapping.KeyComparer)); + nullableEnum32.SetComparer(new NullableValueComparer(nullableEnum32.TypeMapping.Comparer)); + nullableEnum32.SetKeyComparer(new NullableValueComparer(nullableEnum32.TypeMapping.KeyComparer)); nullableEnum32.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableEnum32Array = runtimeEntityType.AddProperty( @@ -7915,8 +7915,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( int (CompiledModelTestBase.Enum32 value) => ((int)(value)), CompiledModelTestBase.Enum32 (int value) => ((CompiledModelTestBase.Enum32)(value))))); - nullableEnum32AsString.SetValueComparer(new NullableValueComparer(nullableEnum32AsString.TypeMapping.Comparer)); - nullableEnum32AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnum32AsString.TypeMapping.KeyComparer)); + nullableEnum32AsString.SetComparer(new NullableValueComparer(nullableEnum32AsString.TypeMapping.Comparer)); + nullableEnum32AsString.SetKeyComparer(new NullableValueComparer(nullableEnum32AsString.TypeMapping.KeyComparer)); nullableEnum32AsString.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableEnum32AsStringArray = runtimeEntityType.AddProperty( @@ -8204,8 +8204,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( long (CompiledModelTestBase.Enum64 value) => ((long)(value)), CompiledModelTestBase.Enum64 (long value) => ((CompiledModelTestBase.Enum64)(value))))); - nullableEnum64.SetValueComparer(new NullableValueComparer(nullableEnum64.TypeMapping.Comparer)); - nullableEnum64.SetKeyValueComparer(new NullableValueComparer(nullableEnum64.TypeMapping.KeyComparer)); + nullableEnum64.SetComparer(new NullableValueComparer(nullableEnum64.TypeMapping.Comparer)); + nullableEnum64.SetKeyComparer(new NullableValueComparer(nullableEnum64.TypeMapping.KeyComparer)); nullableEnum64.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableEnum64Array = runtimeEntityType.AddProperty( @@ -8335,8 +8335,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( long (CompiledModelTestBase.Enum64 value) => ((long)(value)), CompiledModelTestBase.Enum64 (long value) => ((CompiledModelTestBase.Enum64)(value))))); - nullableEnum64AsString.SetValueComparer(new NullableValueComparer(nullableEnum64AsString.TypeMapping.Comparer)); - nullableEnum64AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnum64AsString.TypeMapping.KeyComparer)); + nullableEnum64AsString.SetComparer(new NullableValueComparer(nullableEnum64AsString.TypeMapping.Comparer)); + nullableEnum64AsString.SetKeyComparer(new NullableValueComparer(nullableEnum64AsString.TypeMapping.KeyComparer)); nullableEnum64AsString.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableEnum64AsStringArray = runtimeEntityType.AddProperty( @@ -8624,8 +8624,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( short (CompiledModelTestBase.Enum8 value) => ((short)(value)), CompiledModelTestBase.Enum8 (short value) => ((CompiledModelTestBase.Enum8)(value))))); - nullableEnum8.SetValueComparer(new NullableValueComparer(nullableEnum8.TypeMapping.Comparer)); - nullableEnum8.SetKeyValueComparer(new NullableValueComparer(nullableEnum8.TypeMapping.KeyComparer)); + nullableEnum8.SetComparer(new NullableValueComparer(nullableEnum8.TypeMapping.Comparer)); + nullableEnum8.SetKeyComparer(new NullableValueComparer(nullableEnum8.TypeMapping.KeyComparer)); nullableEnum8.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableEnum8Array = runtimeEntityType.AddProperty( @@ -8755,8 +8755,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( short (CompiledModelTestBase.Enum8 value) => ((short)(value)), CompiledModelTestBase.Enum8 (short value) => ((CompiledModelTestBase.Enum8)(value))))); - nullableEnum8AsString.SetValueComparer(new NullableValueComparer(nullableEnum8AsString.TypeMapping.Comparer)); - nullableEnum8AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnum8AsString.TypeMapping.KeyComparer)); + nullableEnum8AsString.SetComparer(new NullableValueComparer(nullableEnum8AsString.TypeMapping.Comparer)); + nullableEnum8AsString.SetKeyComparer(new NullableValueComparer(nullableEnum8AsString.TypeMapping.KeyComparer)); nullableEnum8AsString.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableEnum8AsStringArray = runtimeEntityType.AddProperty( @@ -9044,8 +9044,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( int (CompiledModelTestBase.EnumU16 value) => ((int)(value)), CompiledModelTestBase.EnumU16 (int value) => ((CompiledModelTestBase.EnumU16)(value))))); - nullableEnumU16.SetValueComparer(new NullableValueComparer(nullableEnumU16.TypeMapping.Comparer)); - nullableEnumU16.SetKeyValueComparer(new NullableValueComparer(nullableEnumU16.TypeMapping.KeyComparer)); + nullableEnumU16.SetComparer(new NullableValueComparer(nullableEnumU16.TypeMapping.Comparer)); + nullableEnumU16.SetKeyComparer(new NullableValueComparer(nullableEnumU16.TypeMapping.KeyComparer)); nullableEnumU16.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableEnumU16Array = runtimeEntityType.AddProperty( @@ -9175,8 +9175,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( int (CompiledModelTestBase.EnumU16 value) => ((int)(value)), CompiledModelTestBase.EnumU16 (int value) => ((CompiledModelTestBase.EnumU16)(value))))); - nullableEnumU16AsString.SetValueComparer(new NullableValueComparer(nullableEnumU16AsString.TypeMapping.Comparer)); - nullableEnumU16AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnumU16AsString.TypeMapping.KeyComparer)); + nullableEnumU16AsString.SetComparer(new NullableValueComparer(nullableEnumU16AsString.TypeMapping.Comparer)); + nullableEnumU16AsString.SetKeyComparer(new NullableValueComparer(nullableEnumU16AsString.TypeMapping.KeyComparer)); nullableEnumU16AsString.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableEnumU16AsStringArray = runtimeEntityType.AddProperty( @@ -9464,8 +9464,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( long (CompiledModelTestBase.EnumU32 value) => ((long)(value)), CompiledModelTestBase.EnumU32 (long value) => ((CompiledModelTestBase.EnumU32)(value))))); - nullableEnumU32.SetValueComparer(new NullableValueComparer(nullableEnumU32.TypeMapping.Comparer)); - nullableEnumU32.SetKeyValueComparer(new NullableValueComparer(nullableEnumU32.TypeMapping.KeyComparer)); + nullableEnumU32.SetComparer(new NullableValueComparer(nullableEnumU32.TypeMapping.Comparer)); + nullableEnumU32.SetKeyComparer(new NullableValueComparer(nullableEnumU32.TypeMapping.KeyComparer)); nullableEnumU32.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableEnumU32Array = runtimeEntityType.AddProperty( @@ -9595,8 +9595,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( long (CompiledModelTestBase.EnumU32 value) => ((long)(value)), CompiledModelTestBase.EnumU32 (long value) => ((CompiledModelTestBase.EnumU32)(value))))); - nullableEnumU32AsString.SetValueComparer(new NullableValueComparer(nullableEnumU32AsString.TypeMapping.Comparer)); - nullableEnumU32AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnumU32AsString.TypeMapping.KeyComparer)); + nullableEnumU32AsString.SetComparer(new NullableValueComparer(nullableEnumU32AsString.TypeMapping.Comparer)); + nullableEnumU32AsString.SetKeyComparer(new NullableValueComparer(nullableEnumU32AsString.TypeMapping.KeyComparer)); nullableEnumU32AsString.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableEnumU32AsStringArray = runtimeEntityType.AddProperty( @@ -9888,8 +9888,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( decimal (CompiledModelTestBase.EnumU64 value) => ((decimal)(((long)(value)))), CompiledModelTestBase.EnumU64 (decimal value) => ((CompiledModelTestBase.EnumU64)(((long)(value))))))); - nullableEnumU64.SetValueComparer(new NullableValueComparer(nullableEnumU64.TypeMapping.Comparer)); - nullableEnumU64.SetKeyValueComparer(new NullableValueComparer(nullableEnumU64.TypeMapping.KeyComparer)); + nullableEnumU64.SetComparer(new NullableValueComparer(nullableEnumU64.TypeMapping.Comparer)); + nullableEnumU64.SetKeyComparer(new NullableValueComparer(nullableEnumU64.TypeMapping.KeyComparer)); nullableEnumU64.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableEnumU64Array = runtimeEntityType.AddProperty( @@ -10027,8 +10027,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( decimal (CompiledModelTestBase.EnumU64 value) => ((decimal)(((long)(value)))), CompiledModelTestBase.EnumU64 (decimal value) => ((CompiledModelTestBase.EnumU64)(((long)(value))))))); - nullableEnumU64AsString.SetValueComparer(new NullableValueComparer(nullableEnumU64AsString.TypeMapping.Comparer)); - nullableEnumU64AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnumU64AsString.TypeMapping.KeyComparer)); + nullableEnumU64AsString.SetComparer(new NullableValueComparer(nullableEnumU64AsString.TypeMapping.Comparer)); + nullableEnumU64AsString.SetKeyComparer(new NullableValueComparer(nullableEnumU64AsString.TypeMapping.KeyComparer)); nullableEnumU64AsString.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableEnumU64AsStringArray = runtimeEntityType.AddProperty( @@ -10328,8 +10328,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( byte (CompiledModelTestBase.EnumU8 value) => ((byte)(value)), CompiledModelTestBase.EnumU8 (byte value) => ((CompiledModelTestBase.EnumU8)(value))))); - nullableEnumU8.SetValueComparer(new NullableValueComparer(nullableEnumU8.TypeMapping.Comparer)); - nullableEnumU8.SetKeyValueComparer(new NullableValueComparer(nullableEnumU8.TypeMapping.KeyComparer)); + nullableEnumU8.SetComparer(new NullableValueComparer(nullableEnumU8.TypeMapping.Comparer)); + nullableEnumU8.SetKeyComparer(new NullableValueComparer(nullableEnumU8.TypeMapping.KeyComparer)); nullableEnumU8.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableEnumU8Array = runtimeEntityType.AddProperty( @@ -10459,8 +10459,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( byte (CompiledModelTestBase.EnumU8 value) => ((byte)(value)), CompiledModelTestBase.EnumU8 (byte value) => ((CompiledModelTestBase.EnumU8)(value))))); - nullableEnumU8AsString.SetValueComparer(new NullableValueComparer(nullableEnumU8AsString.TypeMapping.Comparer)); - nullableEnumU8AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnumU8AsString.TypeMapping.KeyComparer)); + nullableEnumU8AsString.SetComparer(new NullableValueComparer(nullableEnumU8AsString.TypeMapping.Comparer)); + nullableEnumU8AsString.SetKeyComparer(new NullableValueComparer(nullableEnumU8AsString.TypeMapping.KeyComparer)); nullableEnumU8AsString.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableEnumU8AsStringArray = runtimeEntityType.AddProperty( @@ -10740,8 +10740,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (float v1, float v2) => v1.Equals(v2), int (float v) => ((object)v).GetHashCode(), float (float v) => v)); - nullableFloat.SetValueComparer(new NullableValueComparer(nullableFloat.TypeMapping.Comparer)); - nullableFloat.SetKeyValueComparer(new NullableValueComparer(nullableFloat.TypeMapping.KeyComparer)); + nullableFloat.SetComparer(new NullableValueComparer(nullableFloat.TypeMapping.Comparer)); + nullableFloat.SetKeyComparer(new NullableValueComparer(nullableFloat.TypeMapping.KeyComparer)); nullableFloat.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableFloatArray = runtimeEntityType.AddProperty( @@ -10849,8 +10849,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas Guid (Guid v) => v), mappingInfo: new RelationalTypeMappingInfo( storeTypeName: "uniqueidentifier")); - nullableGuid.SetValueComparer(new NullableValueComparer(nullableGuid.TypeMapping.Comparer)); - nullableGuid.SetKeyValueComparer(new NullableValueComparer(nullableGuid.TypeMapping.KeyComparer)); + nullableGuid.SetComparer(new NullableValueComparer(nullableGuid.TypeMapping.Comparer)); + nullableGuid.SetKeyComparer(new NullableValueComparer(nullableGuid.TypeMapping.KeyComparer)); nullableGuid.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableGuidArray = runtimeEntityType.AddProperty( @@ -11097,8 +11097,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (short v1, short v2) => v1 == v2, int (short v) => ((int)(v)), short (short v) => v)); - nullableInt16.SetValueComparer(new NullableValueComparer(nullableInt16.TypeMapping.Comparer)); - nullableInt16.SetKeyValueComparer(new NullableValueComparer(nullableInt16.TypeMapping.KeyComparer)); + nullableInt16.SetComparer(new NullableValueComparer(nullableInt16.TypeMapping.Comparer)); + nullableInt16.SetKeyComparer(new NullableValueComparer(nullableInt16.TypeMapping.KeyComparer)); nullableInt16.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableInt16Array = runtimeEntityType.AddProperty( @@ -11204,8 +11204,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (int v1, int v2) => v1 == v2, int (int v) => v, int (int v) => v)); - nullableInt32.SetValueComparer(new NullableValueComparer(nullableInt32.TypeMapping.Comparer)); - nullableInt32.SetKeyValueComparer(new NullableValueComparer(nullableInt32.TypeMapping.KeyComparer)); + nullableInt32.SetComparer(new NullableValueComparer(nullableInt32.TypeMapping.Comparer)); + nullableInt32.SetKeyComparer(new NullableValueComparer(nullableInt32.TypeMapping.KeyComparer)); nullableInt32.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableInt32Array = runtimeEntityType.AddProperty( @@ -11311,8 +11311,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (long v1, long v2) => v1 == v2, int (long v) => ((object)v).GetHashCode(), long (long v) => v)); - nullableInt64.SetValueComparer(new NullableValueComparer(nullableInt64.TypeMapping.Comparer)); - nullableInt64.SetKeyValueComparer(new NullableValueComparer(nullableInt64.TypeMapping.KeyComparer)); + nullableInt64.SetComparer(new NullableValueComparer(nullableInt64.TypeMapping.Comparer)); + nullableInt64.SetKeyComparer(new NullableValueComparer(nullableInt64.TypeMapping.KeyComparer)); nullableInt64.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableInt64Array = runtimeEntityType.AddProperty( @@ -11426,8 +11426,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( short (sbyte v) => ((short)(v)), sbyte (short v) => ((sbyte)(v))))); - nullableInt8.SetValueComparer(new NullableValueComparer(nullableInt8.TypeMapping.Comparer)); - nullableInt8.SetKeyValueComparer(new NullableValueComparer(nullableInt8.TypeMapping.KeyComparer)); + nullableInt8.SetComparer(new NullableValueComparer(nullableInt8.TypeMapping.Comparer)); + nullableInt8.SetKeyComparer(new NullableValueComparer(nullableInt8.TypeMapping.KeyComparer)); nullableInt8.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableInt8Array = runtimeEntityType.AddProperty( @@ -11803,8 +11803,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (TimeOnly v1, TimeOnly v2) => v1.Equals(v2), int (TimeOnly v) => ((object)v).GetHashCode(), TimeOnly (TimeOnly v) => v)); - nullableTimeOnly.SetValueComparer(new NullableValueComparer(nullableTimeOnly.TypeMapping.Comparer)); - nullableTimeOnly.SetKeyValueComparer(new NullableValueComparer(nullableTimeOnly.TypeMapping.KeyComparer)); + nullableTimeOnly.SetComparer(new NullableValueComparer(nullableTimeOnly.TypeMapping.Comparer)); + nullableTimeOnly.SetKeyComparer(new NullableValueComparer(nullableTimeOnly.TypeMapping.KeyComparer)); nullableTimeOnly.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableTimeOnlyArray = runtimeEntityType.AddProperty( @@ -11910,8 +11910,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (TimeSpan v1, TimeSpan v2) => v1.Equals(v2), int (TimeSpan v) => ((object)v).GetHashCode(), TimeSpan (TimeSpan v) => v)); - nullableTimeSpan.SetValueComparer(new NullableValueComparer(nullableTimeSpan.TypeMapping.Comparer)); - nullableTimeSpan.SetKeyValueComparer(new NullableValueComparer(nullableTimeSpan.TypeMapping.KeyComparer)); + nullableTimeSpan.SetComparer(new NullableValueComparer(nullableTimeSpan.TypeMapping.Comparer)); + nullableTimeSpan.SetKeyComparer(new NullableValueComparer(nullableTimeSpan.TypeMapping.KeyComparer)); nullableTimeSpan.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableTimeSpanArray = runtimeEntityType.AddProperty( @@ -12025,8 +12025,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( int (ushort v) => ((int)(v)), ushort (int v) => ((ushort)(v))))); - nullableUInt16.SetValueComparer(new NullableValueComparer(nullableUInt16.TypeMapping.Comparer)); - nullableUInt16.SetKeyValueComparer(new NullableValueComparer(nullableUInt16.TypeMapping.KeyComparer)); + nullableUInt16.SetComparer(new NullableValueComparer(nullableUInt16.TypeMapping.Comparer)); + nullableUInt16.SetKeyComparer(new NullableValueComparer(nullableUInt16.TypeMapping.KeyComparer)); nullableUInt16.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableUInt16Array = runtimeEntityType.AddProperty( @@ -12156,8 +12156,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( long (uint v) => ((long)(v)), uint (long v) => ((uint)(v))))); - nullableUInt32.SetValueComparer(new NullableValueComparer(nullableUInt32.TypeMapping.Comparer)); - nullableUInt32.SetKeyValueComparer(new NullableValueComparer(nullableUInt32.TypeMapping.KeyComparer)); + nullableUInt32.SetComparer(new NullableValueComparer(nullableUInt32.TypeMapping.Comparer)); + nullableUInt32.SetKeyComparer(new NullableValueComparer(nullableUInt32.TypeMapping.KeyComparer)); nullableUInt32.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableUInt32Array = runtimeEntityType.AddProperty( @@ -12291,8 +12291,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( decimal (ulong v) => ((decimal)(v)), ulong (decimal v) => ((ulong)(v))))); - nullableUInt64.SetValueComparer(new NullableValueComparer(nullableUInt64.TypeMapping.Comparer)); - nullableUInt64.SetKeyValueComparer(new NullableValueComparer(nullableUInt64.TypeMapping.KeyComparer)); + nullableUInt64.SetComparer(new NullableValueComparer(nullableUInt64.TypeMapping.Comparer)); + nullableUInt64.SetKeyComparer(new NullableValueComparer(nullableUInt64.TypeMapping.KeyComparer)); nullableUInt64.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableUInt64Array = runtimeEntityType.AddProperty( @@ -12418,8 +12418,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (byte v1, byte v2) => v1 == v2, int (byte v) => ((int)(v)), byte (byte v) => v)); - nullableUInt8.SetValueComparer(new NullableValueComparer(nullableUInt8.TypeMapping.Comparer)); - nullableUInt8.SetKeyValueComparer(new NullableValueComparer(nullableUInt8.TypeMapping.KeyComparer)); + nullableUInt8.SetComparer(new NullableValueComparer(nullableUInt8.TypeMapping.Comparer)); + nullableUInt8.SetKeyComparer(new NullableValueComparer(nullableUInt8.TypeMapping.KeyComparer)); nullableUInt8.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var nullableUInt8Array = runtimeEntityType.AddProperty( @@ -14816,242 +14816,242 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var @bool = runtimeEntityType.FindProperty("Bool")!; - var boolArray = runtimeEntityType.FindProperty("BoolArray")!; - var boolToStringConverterProperty = runtimeEntityType.FindProperty("BoolToStringConverterProperty")!; - var boolToTwoValuesConverterProperty = runtimeEntityType.FindProperty("BoolToTwoValuesConverterProperty")!; - var boolToZeroOneConverterProperty = runtimeEntityType.FindProperty("BoolToZeroOneConverterProperty")!; - var bytes = runtimeEntityType.FindProperty("Bytes")!; - var bytesArray = runtimeEntityType.FindProperty("BytesArray")!; - var bytesToStringConverterProperty = runtimeEntityType.FindProperty("BytesToStringConverterProperty")!; - var castingConverterProperty = runtimeEntityType.FindProperty("CastingConverterProperty")!; - var @char = runtimeEntityType.FindProperty("Char")!; - var charArray = runtimeEntityType.FindProperty("CharArray")!; - var charToStringConverterProperty = runtimeEntityType.FindProperty("CharToStringConverterProperty")!; - var dateOnly = runtimeEntityType.FindProperty("DateOnly")!; - var dateOnlyArray = runtimeEntityType.FindProperty("DateOnlyArray")!; - var dateOnlyToStringConverterProperty = runtimeEntityType.FindProperty("DateOnlyToStringConverterProperty")!; - var dateTime = runtimeEntityType.FindProperty("DateTime")!; - var dateTimeArray = runtimeEntityType.FindProperty("DateTimeArray")!; - var dateTimeOffsetToBinaryConverterProperty = runtimeEntityType.FindProperty("DateTimeOffsetToBinaryConverterProperty")!; - var dateTimeOffsetToBytesConverterProperty = runtimeEntityType.FindProperty("DateTimeOffsetToBytesConverterProperty")!; - var dateTimeOffsetToStringConverterProperty = runtimeEntityType.FindProperty("DateTimeOffsetToStringConverterProperty")!; - var dateTimeToBinaryConverterProperty = runtimeEntityType.FindProperty("DateTimeToBinaryConverterProperty")!; - var dateTimeToStringConverterProperty = runtimeEntityType.FindProperty("DateTimeToStringConverterProperty")!; - var dateTimeToTicksConverterProperty = runtimeEntityType.FindProperty("DateTimeToTicksConverterProperty")!; - var @decimal = runtimeEntityType.FindProperty("Decimal")!; - var decimalArray = runtimeEntityType.FindProperty("DecimalArray")!; - var decimalNumberToBytesConverterProperty = runtimeEntityType.FindProperty("DecimalNumberToBytesConverterProperty")!; - var decimalNumberToStringConverterProperty = runtimeEntityType.FindProperty("DecimalNumberToStringConverterProperty")!; - var @double = runtimeEntityType.FindProperty("Double")!; - var doubleArray = runtimeEntityType.FindProperty("DoubleArray")!; - var doubleNumberToBytesConverterProperty = runtimeEntityType.FindProperty("DoubleNumberToBytesConverterProperty")!; - var doubleNumberToStringConverterProperty = runtimeEntityType.FindProperty("DoubleNumberToStringConverterProperty")!; - var enum16 = runtimeEntityType.FindProperty("Enum16")!; - var enum16Array = runtimeEntityType.FindProperty("Enum16Array")!; - var enum16AsString = runtimeEntityType.FindProperty("Enum16AsString")!; - var enum16AsStringArray = runtimeEntityType.FindProperty("Enum16AsStringArray")!; - var enum16AsStringCollection = runtimeEntityType.FindProperty("Enum16AsStringCollection")!; - var enum16Collection = runtimeEntityType.FindProperty("Enum16Collection")!; - var enum32 = runtimeEntityType.FindProperty("Enum32")!; - var enum32Array = runtimeEntityType.FindProperty("Enum32Array")!; - var enum32AsString = runtimeEntityType.FindProperty("Enum32AsString")!; - var enum32AsStringArray = runtimeEntityType.FindProperty("Enum32AsStringArray")!; - var enum32AsStringCollection = runtimeEntityType.FindProperty("Enum32AsStringCollection")!; - var enum32Collection = runtimeEntityType.FindProperty("Enum32Collection")!; - var enum64 = runtimeEntityType.FindProperty("Enum64")!; - var enum64Array = runtimeEntityType.FindProperty("Enum64Array")!; - var enum64AsString = runtimeEntityType.FindProperty("Enum64AsString")!; - var enum64AsStringArray = runtimeEntityType.FindProperty("Enum64AsStringArray")!; - var enum64AsStringCollection = runtimeEntityType.FindProperty("Enum64AsStringCollection")!; - var enum64Collection = runtimeEntityType.FindProperty("Enum64Collection")!; - var enum8 = runtimeEntityType.FindProperty("Enum8")!; - var enum8Array = runtimeEntityType.FindProperty("Enum8Array")!; - var enum8AsString = runtimeEntityType.FindProperty("Enum8AsString")!; - var enum8AsStringArray = runtimeEntityType.FindProperty("Enum8AsStringArray")!; - var enum8AsStringCollection = runtimeEntityType.FindProperty("Enum8AsStringCollection")!; - var enum8Collection = runtimeEntityType.FindProperty("Enum8Collection")!; - var enumToNumberConverterProperty = runtimeEntityType.FindProperty("EnumToNumberConverterProperty")!; - var enumToStringConverterProperty = runtimeEntityType.FindProperty("EnumToStringConverterProperty")!; - var enumU16 = runtimeEntityType.FindProperty("EnumU16")!; - var enumU16Array = runtimeEntityType.FindProperty("EnumU16Array")!; - var enumU16AsString = runtimeEntityType.FindProperty("EnumU16AsString")!; - var enumU16AsStringArray = runtimeEntityType.FindProperty("EnumU16AsStringArray")!; - var enumU16AsStringCollection = runtimeEntityType.FindProperty("EnumU16AsStringCollection")!; - var enumU16Collection = runtimeEntityType.FindProperty("EnumU16Collection")!; - var enumU32 = runtimeEntityType.FindProperty("EnumU32")!; - var enumU32Array = runtimeEntityType.FindProperty("EnumU32Array")!; - var enumU32AsString = runtimeEntityType.FindProperty("EnumU32AsString")!; - var enumU32AsStringArray = runtimeEntityType.FindProperty("EnumU32AsStringArray")!; - var enumU32AsStringCollection = runtimeEntityType.FindProperty("EnumU32AsStringCollection")!; - var enumU32Collection = runtimeEntityType.FindProperty("EnumU32Collection")!; - var enumU64 = runtimeEntityType.FindProperty("EnumU64")!; - var enumU64Array = runtimeEntityType.FindProperty("EnumU64Array")!; - var enumU64AsString = runtimeEntityType.FindProperty("EnumU64AsString")!; - var enumU64AsStringArray = runtimeEntityType.FindProperty("EnumU64AsStringArray")!; - var enumU64AsStringCollection = runtimeEntityType.FindProperty("EnumU64AsStringCollection")!; - var enumU64Collection = runtimeEntityType.FindProperty("EnumU64Collection")!; - var enumU8 = runtimeEntityType.FindProperty("EnumU8")!; - var enumU8Array = runtimeEntityType.FindProperty("EnumU8Array")!; - var enumU8AsString = runtimeEntityType.FindProperty("EnumU8AsString")!; - var enumU8AsStringArray = runtimeEntityType.FindProperty("EnumU8AsStringArray")!; - var enumU8AsStringCollection = runtimeEntityType.FindProperty("EnumU8AsStringCollection")!; - var enumU8Collection = runtimeEntityType.FindProperty("EnumU8Collection")!; - var @float = runtimeEntityType.FindProperty("Float")!; - var floatArray = runtimeEntityType.FindProperty("FloatArray")!; - var guid = runtimeEntityType.FindProperty("Guid")!; - var guidArray = runtimeEntityType.FindProperty("GuidArray")!; - var guidToBytesConverterProperty = runtimeEntityType.FindProperty("GuidToBytesConverterProperty")!; - var guidToStringConverterProperty = runtimeEntityType.FindProperty("GuidToStringConverterProperty")!; - var iPAddress = runtimeEntityType.FindProperty("IPAddress")!; - var iPAddressArray = runtimeEntityType.FindProperty("IPAddressArray")!; - var iPAddressToBytesConverterProperty = runtimeEntityType.FindProperty("IPAddressToBytesConverterProperty")!; - var iPAddressToStringConverterProperty = runtimeEntityType.FindProperty("IPAddressToStringConverterProperty")!; - var int16 = runtimeEntityType.FindProperty("Int16")!; - var int16Array = runtimeEntityType.FindProperty("Int16Array")!; - var int32 = runtimeEntityType.FindProperty("Int32")!; - var int32Array = runtimeEntityType.FindProperty("Int32Array")!; - var int64 = runtimeEntityType.FindProperty("Int64")!; - var int64Array = runtimeEntityType.FindProperty("Int64Array")!; - var int8 = runtimeEntityType.FindProperty("Int8")!; - var int8Array = runtimeEntityType.FindProperty("Int8Array")!; - var intNumberToBytesConverterProperty = runtimeEntityType.FindProperty("IntNumberToBytesConverterProperty")!; - var intNumberToStringConverterProperty = runtimeEntityType.FindProperty("IntNumberToStringConverterProperty")!; - var nullIntToNullStringConverterProperty = runtimeEntityType.FindProperty("NullIntToNullStringConverterProperty")!; - var nullableBool = runtimeEntityType.FindProperty("NullableBool")!; - var nullableBoolArray = runtimeEntityType.FindProperty("NullableBoolArray")!; - var nullableBytes = runtimeEntityType.FindProperty("NullableBytes")!; - var nullableBytesArray = runtimeEntityType.FindProperty("NullableBytesArray")!; - var nullableChar = runtimeEntityType.FindProperty("NullableChar")!; - var nullableCharArray = runtimeEntityType.FindProperty("NullableCharArray")!; - var nullableDateOnly = runtimeEntityType.FindProperty("NullableDateOnly")!; - var nullableDateOnlyArray = runtimeEntityType.FindProperty("NullableDateOnlyArray")!; - var nullableDateTime = runtimeEntityType.FindProperty("NullableDateTime")!; - var nullableDateTimeArray = runtimeEntityType.FindProperty("NullableDateTimeArray")!; - var nullableDecimal = runtimeEntityType.FindProperty("NullableDecimal")!; - var nullableDecimalArray = runtimeEntityType.FindProperty("NullableDecimalArray")!; - var nullableDouble = runtimeEntityType.FindProperty("NullableDouble")!; - var nullableDoubleArray = runtimeEntityType.FindProperty("NullableDoubleArray")!; - var nullableEnum16 = runtimeEntityType.FindProperty("NullableEnum16")!; - var nullableEnum16Array = runtimeEntityType.FindProperty("NullableEnum16Array")!; - var nullableEnum16AsString = runtimeEntityType.FindProperty("NullableEnum16AsString")!; - var nullableEnum16AsStringArray = runtimeEntityType.FindProperty("NullableEnum16AsStringArray")!; - var nullableEnum16AsStringCollection = runtimeEntityType.FindProperty("NullableEnum16AsStringCollection")!; - var nullableEnum16Collection = runtimeEntityType.FindProperty("NullableEnum16Collection")!; - var nullableEnum32 = runtimeEntityType.FindProperty("NullableEnum32")!; - var nullableEnum32Array = runtimeEntityType.FindProperty("NullableEnum32Array")!; - var nullableEnum32AsString = runtimeEntityType.FindProperty("NullableEnum32AsString")!; - var nullableEnum32AsStringArray = runtimeEntityType.FindProperty("NullableEnum32AsStringArray")!; - var nullableEnum32AsStringCollection = runtimeEntityType.FindProperty("NullableEnum32AsStringCollection")!; - var nullableEnum32Collection = runtimeEntityType.FindProperty("NullableEnum32Collection")!; - var nullableEnum64 = runtimeEntityType.FindProperty("NullableEnum64")!; - var nullableEnum64Array = runtimeEntityType.FindProperty("NullableEnum64Array")!; - var nullableEnum64AsString = runtimeEntityType.FindProperty("NullableEnum64AsString")!; - var nullableEnum64AsStringArray = runtimeEntityType.FindProperty("NullableEnum64AsStringArray")!; - var nullableEnum64AsStringCollection = runtimeEntityType.FindProperty("NullableEnum64AsStringCollection")!; - var nullableEnum64Collection = runtimeEntityType.FindProperty("NullableEnum64Collection")!; - var nullableEnum8 = runtimeEntityType.FindProperty("NullableEnum8")!; - var nullableEnum8Array = runtimeEntityType.FindProperty("NullableEnum8Array")!; - var nullableEnum8AsString = runtimeEntityType.FindProperty("NullableEnum8AsString")!; - var nullableEnum8AsStringArray = runtimeEntityType.FindProperty("NullableEnum8AsStringArray")!; - var nullableEnum8AsStringCollection = runtimeEntityType.FindProperty("NullableEnum8AsStringCollection")!; - var nullableEnum8Collection = runtimeEntityType.FindProperty("NullableEnum8Collection")!; - var nullableEnumU16 = runtimeEntityType.FindProperty("NullableEnumU16")!; - var nullableEnumU16Array = runtimeEntityType.FindProperty("NullableEnumU16Array")!; - var nullableEnumU16AsString = runtimeEntityType.FindProperty("NullableEnumU16AsString")!; - var nullableEnumU16AsStringArray = runtimeEntityType.FindProperty("NullableEnumU16AsStringArray")!; - var nullableEnumU16AsStringCollection = runtimeEntityType.FindProperty("NullableEnumU16AsStringCollection")!; - var nullableEnumU16Collection = runtimeEntityType.FindProperty("NullableEnumU16Collection")!; - var nullableEnumU32 = runtimeEntityType.FindProperty("NullableEnumU32")!; - var nullableEnumU32Array = runtimeEntityType.FindProperty("NullableEnumU32Array")!; - var nullableEnumU32AsString = runtimeEntityType.FindProperty("NullableEnumU32AsString")!; - var nullableEnumU32AsStringArray = runtimeEntityType.FindProperty("NullableEnumU32AsStringArray")!; - var nullableEnumU32AsStringCollection = runtimeEntityType.FindProperty("NullableEnumU32AsStringCollection")!; - var nullableEnumU32Collection = runtimeEntityType.FindProperty("NullableEnumU32Collection")!; - var nullableEnumU64 = runtimeEntityType.FindProperty("NullableEnumU64")!; - var nullableEnumU64Array = runtimeEntityType.FindProperty("NullableEnumU64Array")!; - var nullableEnumU64AsString = runtimeEntityType.FindProperty("NullableEnumU64AsString")!; - var nullableEnumU64AsStringArray = runtimeEntityType.FindProperty("NullableEnumU64AsStringArray")!; - var nullableEnumU64AsStringCollection = runtimeEntityType.FindProperty("NullableEnumU64AsStringCollection")!; - var nullableEnumU64Collection = runtimeEntityType.FindProperty("NullableEnumU64Collection")!; - var nullableEnumU8 = runtimeEntityType.FindProperty("NullableEnumU8")!; - var nullableEnumU8Array = runtimeEntityType.FindProperty("NullableEnumU8Array")!; - var nullableEnumU8AsString = runtimeEntityType.FindProperty("NullableEnumU8AsString")!; - var nullableEnumU8AsStringArray = runtimeEntityType.FindProperty("NullableEnumU8AsStringArray")!; - var nullableEnumU8AsStringCollection = runtimeEntityType.FindProperty("NullableEnumU8AsStringCollection")!; - var nullableEnumU8Collection = runtimeEntityType.FindProperty("NullableEnumU8Collection")!; - var nullableFloat = runtimeEntityType.FindProperty("NullableFloat")!; - var nullableFloatArray = runtimeEntityType.FindProperty("NullableFloatArray")!; - var nullableGuid = runtimeEntityType.FindProperty("NullableGuid")!; - var nullableGuidArray = runtimeEntityType.FindProperty("NullableGuidArray")!; - var nullableIPAddress = runtimeEntityType.FindProperty("NullableIPAddress")!; - var nullableIPAddressArray = runtimeEntityType.FindProperty("NullableIPAddressArray")!; - var nullableInt16 = runtimeEntityType.FindProperty("NullableInt16")!; - var nullableInt16Array = runtimeEntityType.FindProperty("NullableInt16Array")!; - var nullableInt32 = runtimeEntityType.FindProperty("NullableInt32")!; - var nullableInt32Array = runtimeEntityType.FindProperty("NullableInt32Array")!; - var nullableInt64 = runtimeEntityType.FindProperty("NullableInt64")!; - var nullableInt64Array = runtimeEntityType.FindProperty("NullableInt64Array")!; - var nullableInt8 = runtimeEntityType.FindProperty("NullableInt8")!; - var nullableInt8Array = runtimeEntityType.FindProperty("NullableInt8Array")!; - var nullablePhysicalAddress = runtimeEntityType.FindProperty("NullablePhysicalAddress")!; - var nullablePhysicalAddressArray = runtimeEntityType.FindProperty("NullablePhysicalAddressArray")!; - var nullableString = runtimeEntityType.FindProperty("NullableString")!; - var nullableStringArray = runtimeEntityType.FindProperty("NullableStringArray")!; - var nullableTimeOnly = runtimeEntityType.FindProperty("NullableTimeOnly")!; - var nullableTimeOnlyArray = runtimeEntityType.FindProperty("NullableTimeOnlyArray")!; - var nullableTimeSpan = runtimeEntityType.FindProperty("NullableTimeSpan")!; - var nullableTimeSpanArray = runtimeEntityType.FindProperty("NullableTimeSpanArray")!; - var nullableUInt16 = runtimeEntityType.FindProperty("NullableUInt16")!; - var nullableUInt16Array = runtimeEntityType.FindProperty("NullableUInt16Array")!; - var nullableUInt32 = runtimeEntityType.FindProperty("NullableUInt32")!; - var nullableUInt32Array = runtimeEntityType.FindProperty("NullableUInt32Array")!; - var nullableUInt64 = runtimeEntityType.FindProperty("NullableUInt64")!; - var nullableUInt64Array = runtimeEntityType.FindProperty("NullableUInt64Array")!; - var nullableUInt8 = runtimeEntityType.FindProperty("NullableUInt8")!; - var nullableUInt8Array = runtimeEntityType.FindProperty("NullableUInt8Array")!; - var nullableUri = runtimeEntityType.FindProperty("NullableUri")!; - var nullableUriArray = runtimeEntityType.FindProperty("NullableUriArray")!; - var physicalAddress = runtimeEntityType.FindProperty("PhysicalAddress")!; - var physicalAddressArray = runtimeEntityType.FindProperty("PhysicalAddressArray")!; - var physicalAddressToBytesConverterProperty = runtimeEntityType.FindProperty("PhysicalAddressToBytesConverterProperty")!; - var physicalAddressToStringConverterProperty = runtimeEntityType.FindProperty("PhysicalAddressToStringConverterProperty")!; - var @string = runtimeEntityType.FindProperty("String")!; - var stringArray = runtimeEntityType.FindProperty("StringArray")!; - var stringToBoolConverterProperty = runtimeEntityType.FindProperty("StringToBoolConverterProperty")!; - var stringToBytesConverterProperty = runtimeEntityType.FindProperty("StringToBytesConverterProperty")!; - var stringToCharConverterProperty = runtimeEntityType.FindProperty("StringToCharConverterProperty")!; - var stringToDateOnlyConverterProperty = runtimeEntityType.FindProperty("StringToDateOnlyConverterProperty")!; - var stringToDateTimeConverterProperty = runtimeEntityType.FindProperty("StringToDateTimeConverterProperty")!; - var stringToDateTimeOffsetConverterProperty = runtimeEntityType.FindProperty("StringToDateTimeOffsetConverterProperty")!; - var stringToDecimalNumberConverterProperty = runtimeEntityType.FindProperty("StringToDecimalNumberConverterProperty")!; - var stringToDoubleNumberConverterProperty = runtimeEntityType.FindProperty("StringToDoubleNumberConverterProperty")!; - var stringToEnumConverterProperty = runtimeEntityType.FindProperty("StringToEnumConverterProperty")!; - var stringToGuidConverterProperty = runtimeEntityType.FindProperty("StringToGuidConverterProperty")!; - var stringToIntNumberConverterProperty = runtimeEntityType.FindProperty("StringToIntNumberConverterProperty")!; - var stringToTimeOnlyConverterProperty = runtimeEntityType.FindProperty("StringToTimeOnlyConverterProperty")!; - var stringToTimeSpanConverterProperty = runtimeEntityType.FindProperty("StringToTimeSpanConverterProperty")!; - var stringToUriConverterProperty = runtimeEntityType.FindProperty("StringToUriConverterProperty")!; - var timeOnly = runtimeEntityType.FindProperty("TimeOnly")!; - var timeOnlyArray = runtimeEntityType.FindProperty("TimeOnlyArray")!; - var timeOnlyToStringConverterProperty = runtimeEntityType.FindProperty("TimeOnlyToStringConverterProperty")!; - var timeOnlyToTicksConverterProperty = runtimeEntityType.FindProperty("TimeOnlyToTicksConverterProperty")!; - var timeSpan = runtimeEntityType.FindProperty("TimeSpan")!; - var timeSpanArray = runtimeEntityType.FindProperty("TimeSpanArray")!; - var timeSpanToStringConverterProperty = runtimeEntityType.FindProperty("TimeSpanToStringConverterProperty")!; - var timeSpanToTicksConverterProperty = runtimeEntityType.FindProperty("TimeSpanToTicksConverterProperty")!; - var uInt16 = runtimeEntityType.FindProperty("UInt16")!; - var uInt16Array = runtimeEntityType.FindProperty("UInt16Array")!; - var uInt32 = runtimeEntityType.FindProperty("UInt32")!; - var uInt32Array = runtimeEntityType.FindProperty("UInt32Array")!; - var uInt64 = runtimeEntityType.FindProperty("UInt64")!; - var uInt64Array = runtimeEntityType.FindProperty("UInt64Array")!; - var uInt8 = runtimeEntityType.FindProperty("UInt8")!; - var uInt8Array = runtimeEntityType.FindProperty("UInt8Array")!; - var uri = runtimeEntityType.FindProperty("Uri")!; - var uriArray = runtimeEntityType.FindProperty("UriArray")!; - var uriToStringConverterProperty = runtimeEntityType.FindProperty("UriToStringConverterProperty")!; + var id = runtimeEntityType.FindProperty("Id"); + var @bool = runtimeEntityType.FindProperty("Bool"); + var boolArray = runtimeEntityType.FindProperty("BoolArray"); + var boolToStringConverterProperty = runtimeEntityType.FindProperty("BoolToStringConverterProperty"); + var boolToTwoValuesConverterProperty = runtimeEntityType.FindProperty("BoolToTwoValuesConverterProperty"); + var boolToZeroOneConverterProperty = runtimeEntityType.FindProperty("BoolToZeroOneConverterProperty"); + var bytes = runtimeEntityType.FindProperty("Bytes"); + var bytesArray = runtimeEntityType.FindProperty("BytesArray"); + var bytesToStringConverterProperty = runtimeEntityType.FindProperty("BytesToStringConverterProperty"); + var castingConverterProperty = runtimeEntityType.FindProperty("CastingConverterProperty"); + var @char = runtimeEntityType.FindProperty("Char"); + var charArray = runtimeEntityType.FindProperty("CharArray"); + var charToStringConverterProperty = runtimeEntityType.FindProperty("CharToStringConverterProperty"); + var dateOnly = runtimeEntityType.FindProperty("DateOnly"); + var dateOnlyArray = runtimeEntityType.FindProperty("DateOnlyArray"); + var dateOnlyToStringConverterProperty = runtimeEntityType.FindProperty("DateOnlyToStringConverterProperty"); + var dateTime = runtimeEntityType.FindProperty("DateTime"); + var dateTimeArray = runtimeEntityType.FindProperty("DateTimeArray"); + var dateTimeOffsetToBinaryConverterProperty = runtimeEntityType.FindProperty("DateTimeOffsetToBinaryConverterProperty"); + var dateTimeOffsetToBytesConverterProperty = runtimeEntityType.FindProperty("DateTimeOffsetToBytesConverterProperty"); + var dateTimeOffsetToStringConverterProperty = runtimeEntityType.FindProperty("DateTimeOffsetToStringConverterProperty"); + var dateTimeToBinaryConverterProperty = runtimeEntityType.FindProperty("DateTimeToBinaryConverterProperty"); + var dateTimeToStringConverterProperty = runtimeEntityType.FindProperty("DateTimeToStringConverterProperty"); + var dateTimeToTicksConverterProperty = runtimeEntityType.FindProperty("DateTimeToTicksConverterProperty"); + var @decimal = runtimeEntityType.FindProperty("Decimal"); + var decimalArray = runtimeEntityType.FindProperty("DecimalArray"); + var decimalNumberToBytesConverterProperty = runtimeEntityType.FindProperty("DecimalNumberToBytesConverterProperty"); + var decimalNumberToStringConverterProperty = runtimeEntityType.FindProperty("DecimalNumberToStringConverterProperty"); + var @double = runtimeEntityType.FindProperty("Double"); + var doubleArray = runtimeEntityType.FindProperty("DoubleArray"); + var doubleNumberToBytesConverterProperty = runtimeEntityType.FindProperty("DoubleNumberToBytesConverterProperty"); + var doubleNumberToStringConverterProperty = runtimeEntityType.FindProperty("DoubleNumberToStringConverterProperty"); + var enum16 = runtimeEntityType.FindProperty("Enum16"); + var enum16Array = runtimeEntityType.FindProperty("Enum16Array"); + var enum16AsString = runtimeEntityType.FindProperty("Enum16AsString"); + var enum16AsStringArray = runtimeEntityType.FindProperty("Enum16AsStringArray"); + var enum16AsStringCollection = runtimeEntityType.FindProperty("Enum16AsStringCollection"); + var enum16Collection = runtimeEntityType.FindProperty("Enum16Collection"); + var enum32 = runtimeEntityType.FindProperty("Enum32"); + var enum32Array = runtimeEntityType.FindProperty("Enum32Array"); + var enum32AsString = runtimeEntityType.FindProperty("Enum32AsString"); + var enum32AsStringArray = runtimeEntityType.FindProperty("Enum32AsStringArray"); + var enum32AsStringCollection = runtimeEntityType.FindProperty("Enum32AsStringCollection"); + var enum32Collection = runtimeEntityType.FindProperty("Enum32Collection"); + var enum64 = runtimeEntityType.FindProperty("Enum64"); + var enum64Array = runtimeEntityType.FindProperty("Enum64Array"); + var enum64AsString = runtimeEntityType.FindProperty("Enum64AsString"); + var enum64AsStringArray = runtimeEntityType.FindProperty("Enum64AsStringArray"); + var enum64AsStringCollection = runtimeEntityType.FindProperty("Enum64AsStringCollection"); + var enum64Collection = runtimeEntityType.FindProperty("Enum64Collection"); + var enum8 = runtimeEntityType.FindProperty("Enum8"); + var enum8Array = runtimeEntityType.FindProperty("Enum8Array"); + var enum8AsString = runtimeEntityType.FindProperty("Enum8AsString"); + var enum8AsStringArray = runtimeEntityType.FindProperty("Enum8AsStringArray"); + var enum8AsStringCollection = runtimeEntityType.FindProperty("Enum8AsStringCollection"); + var enum8Collection = runtimeEntityType.FindProperty("Enum8Collection"); + var enumToNumberConverterProperty = runtimeEntityType.FindProperty("EnumToNumberConverterProperty"); + var enumToStringConverterProperty = runtimeEntityType.FindProperty("EnumToStringConverterProperty"); + var enumU16 = runtimeEntityType.FindProperty("EnumU16"); + var enumU16Array = runtimeEntityType.FindProperty("EnumU16Array"); + var enumU16AsString = runtimeEntityType.FindProperty("EnumU16AsString"); + var enumU16AsStringArray = runtimeEntityType.FindProperty("EnumU16AsStringArray"); + var enumU16AsStringCollection = runtimeEntityType.FindProperty("EnumU16AsStringCollection"); + var enumU16Collection = runtimeEntityType.FindProperty("EnumU16Collection"); + var enumU32 = runtimeEntityType.FindProperty("EnumU32"); + var enumU32Array = runtimeEntityType.FindProperty("EnumU32Array"); + var enumU32AsString = runtimeEntityType.FindProperty("EnumU32AsString"); + var enumU32AsStringArray = runtimeEntityType.FindProperty("EnumU32AsStringArray"); + var enumU32AsStringCollection = runtimeEntityType.FindProperty("EnumU32AsStringCollection"); + var enumU32Collection = runtimeEntityType.FindProperty("EnumU32Collection"); + var enumU64 = runtimeEntityType.FindProperty("EnumU64"); + var enumU64Array = runtimeEntityType.FindProperty("EnumU64Array"); + var enumU64AsString = runtimeEntityType.FindProperty("EnumU64AsString"); + var enumU64AsStringArray = runtimeEntityType.FindProperty("EnumU64AsStringArray"); + var enumU64AsStringCollection = runtimeEntityType.FindProperty("EnumU64AsStringCollection"); + var enumU64Collection = runtimeEntityType.FindProperty("EnumU64Collection"); + var enumU8 = runtimeEntityType.FindProperty("EnumU8"); + var enumU8Array = runtimeEntityType.FindProperty("EnumU8Array"); + var enumU8AsString = runtimeEntityType.FindProperty("EnumU8AsString"); + var enumU8AsStringArray = runtimeEntityType.FindProperty("EnumU8AsStringArray"); + var enumU8AsStringCollection = runtimeEntityType.FindProperty("EnumU8AsStringCollection"); + var enumU8Collection = runtimeEntityType.FindProperty("EnumU8Collection"); + var @float = runtimeEntityType.FindProperty("Float"); + var floatArray = runtimeEntityType.FindProperty("FloatArray"); + var guid = runtimeEntityType.FindProperty("Guid"); + var guidArray = runtimeEntityType.FindProperty("GuidArray"); + var guidToBytesConverterProperty = runtimeEntityType.FindProperty("GuidToBytesConverterProperty"); + var guidToStringConverterProperty = runtimeEntityType.FindProperty("GuidToStringConverterProperty"); + var iPAddress = runtimeEntityType.FindProperty("IPAddress"); + var iPAddressArray = runtimeEntityType.FindProperty("IPAddressArray"); + var iPAddressToBytesConverterProperty = runtimeEntityType.FindProperty("IPAddressToBytesConverterProperty"); + var iPAddressToStringConverterProperty = runtimeEntityType.FindProperty("IPAddressToStringConverterProperty"); + var int16 = runtimeEntityType.FindProperty("Int16"); + var int16Array = runtimeEntityType.FindProperty("Int16Array"); + var int32 = runtimeEntityType.FindProperty("Int32"); + var int32Array = runtimeEntityType.FindProperty("Int32Array"); + var int64 = runtimeEntityType.FindProperty("Int64"); + var int64Array = runtimeEntityType.FindProperty("Int64Array"); + var int8 = runtimeEntityType.FindProperty("Int8"); + var int8Array = runtimeEntityType.FindProperty("Int8Array"); + var intNumberToBytesConverterProperty = runtimeEntityType.FindProperty("IntNumberToBytesConverterProperty"); + var intNumberToStringConverterProperty = runtimeEntityType.FindProperty("IntNumberToStringConverterProperty"); + var nullIntToNullStringConverterProperty = runtimeEntityType.FindProperty("NullIntToNullStringConverterProperty"); + var nullableBool = runtimeEntityType.FindProperty("NullableBool"); + var nullableBoolArray = runtimeEntityType.FindProperty("NullableBoolArray"); + var nullableBytes = runtimeEntityType.FindProperty("NullableBytes"); + var nullableBytesArray = runtimeEntityType.FindProperty("NullableBytesArray"); + var nullableChar = runtimeEntityType.FindProperty("NullableChar"); + var nullableCharArray = runtimeEntityType.FindProperty("NullableCharArray"); + var nullableDateOnly = runtimeEntityType.FindProperty("NullableDateOnly"); + var nullableDateOnlyArray = runtimeEntityType.FindProperty("NullableDateOnlyArray"); + var nullableDateTime = runtimeEntityType.FindProperty("NullableDateTime"); + var nullableDateTimeArray = runtimeEntityType.FindProperty("NullableDateTimeArray"); + var nullableDecimal = runtimeEntityType.FindProperty("NullableDecimal"); + var nullableDecimalArray = runtimeEntityType.FindProperty("NullableDecimalArray"); + var nullableDouble = runtimeEntityType.FindProperty("NullableDouble"); + var nullableDoubleArray = runtimeEntityType.FindProperty("NullableDoubleArray"); + var nullableEnum16 = runtimeEntityType.FindProperty("NullableEnum16"); + var nullableEnum16Array = runtimeEntityType.FindProperty("NullableEnum16Array"); + var nullableEnum16AsString = runtimeEntityType.FindProperty("NullableEnum16AsString"); + var nullableEnum16AsStringArray = runtimeEntityType.FindProperty("NullableEnum16AsStringArray"); + var nullableEnum16AsStringCollection = runtimeEntityType.FindProperty("NullableEnum16AsStringCollection"); + var nullableEnum16Collection = runtimeEntityType.FindProperty("NullableEnum16Collection"); + var nullableEnum32 = runtimeEntityType.FindProperty("NullableEnum32"); + var nullableEnum32Array = runtimeEntityType.FindProperty("NullableEnum32Array"); + var nullableEnum32AsString = runtimeEntityType.FindProperty("NullableEnum32AsString"); + var nullableEnum32AsStringArray = runtimeEntityType.FindProperty("NullableEnum32AsStringArray"); + var nullableEnum32AsStringCollection = runtimeEntityType.FindProperty("NullableEnum32AsStringCollection"); + var nullableEnum32Collection = runtimeEntityType.FindProperty("NullableEnum32Collection"); + var nullableEnum64 = runtimeEntityType.FindProperty("NullableEnum64"); + var nullableEnum64Array = runtimeEntityType.FindProperty("NullableEnum64Array"); + var nullableEnum64AsString = runtimeEntityType.FindProperty("NullableEnum64AsString"); + var nullableEnum64AsStringArray = runtimeEntityType.FindProperty("NullableEnum64AsStringArray"); + var nullableEnum64AsStringCollection = runtimeEntityType.FindProperty("NullableEnum64AsStringCollection"); + var nullableEnum64Collection = runtimeEntityType.FindProperty("NullableEnum64Collection"); + var nullableEnum8 = runtimeEntityType.FindProperty("NullableEnum8"); + var nullableEnum8Array = runtimeEntityType.FindProperty("NullableEnum8Array"); + var nullableEnum8AsString = runtimeEntityType.FindProperty("NullableEnum8AsString"); + var nullableEnum8AsStringArray = runtimeEntityType.FindProperty("NullableEnum8AsStringArray"); + var nullableEnum8AsStringCollection = runtimeEntityType.FindProperty("NullableEnum8AsStringCollection"); + var nullableEnum8Collection = runtimeEntityType.FindProperty("NullableEnum8Collection"); + var nullableEnumU16 = runtimeEntityType.FindProperty("NullableEnumU16"); + var nullableEnumU16Array = runtimeEntityType.FindProperty("NullableEnumU16Array"); + var nullableEnumU16AsString = runtimeEntityType.FindProperty("NullableEnumU16AsString"); + var nullableEnumU16AsStringArray = runtimeEntityType.FindProperty("NullableEnumU16AsStringArray"); + var nullableEnumU16AsStringCollection = runtimeEntityType.FindProperty("NullableEnumU16AsStringCollection"); + var nullableEnumU16Collection = runtimeEntityType.FindProperty("NullableEnumU16Collection"); + var nullableEnumU32 = runtimeEntityType.FindProperty("NullableEnumU32"); + var nullableEnumU32Array = runtimeEntityType.FindProperty("NullableEnumU32Array"); + var nullableEnumU32AsString = runtimeEntityType.FindProperty("NullableEnumU32AsString"); + var nullableEnumU32AsStringArray = runtimeEntityType.FindProperty("NullableEnumU32AsStringArray"); + var nullableEnumU32AsStringCollection = runtimeEntityType.FindProperty("NullableEnumU32AsStringCollection"); + var nullableEnumU32Collection = runtimeEntityType.FindProperty("NullableEnumU32Collection"); + var nullableEnumU64 = runtimeEntityType.FindProperty("NullableEnumU64"); + var nullableEnumU64Array = runtimeEntityType.FindProperty("NullableEnumU64Array"); + var nullableEnumU64AsString = runtimeEntityType.FindProperty("NullableEnumU64AsString"); + var nullableEnumU64AsStringArray = runtimeEntityType.FindProperty("NullableEnumU64AsStringArray"); + var nullableEnumU64AsStringCollection = runtimeEntityType.FindProperty("NullableEnumU64AsStringCollection"); + var nullableEnumU64Collection = runtimeEntityType.FindProperty("NullableEnumU64Collection"); + var nullableEnumU8 = runtimeEntityType.FindProperty("NullableEnumU8"); + var nullableEnumU8Array = runtimeEntityType.FindProperty("NullableEnumU8Array"); + var nullableEnumU8AsString = runtimeEntityType.FindProperty("NullableEnumU8AsString"); + var nullableEnumU8AsStringArray = runtimeEntityType.FindProperty("NullableEnumU8AsStringArray"); + var nullableEnumU8AsStringCollection = runtimeEntityType.FindProperty("NullableEnumU8AsStringCollection"); + var nullableEnumU8Collection = runtimeEntityType.FindProperty("NullableEnumU8Collection"); + var nullableFloat = runtimeEntityType.FindProperty("NullableFloat"); + var nullableFloatArray = runtimeEntityType.FindProperty("NullableFloatArray"); + var nullableGuid = runtimeEntityType.FindProperty("NullableGuid"); + var nullableGuidArray = runtimeEntityType.FindProperty("NullableGuidArray"); + var nullableIPAddress = runtimeEntityType.FindProperty("NullableIPAddress"); + var nullableIPAddressArray = runtimeEntityType.FindProperty("NullableIPAddressArray"); + var nullableInt16 = runtimeEntityType.FindProperty("NullableInt16"); + var nullableInt16Array = runtimeEntityType.FindProperty("NullableInt16Array"); + var nullableInt32 = runtimeEntityType.FindProperty("NullableInt32"); + var nullableInt32Array = runtimeEntityType.FindProperty("NullableInt32Array"); + var nullableInt64 = runtimeEntityType.FindProperty("NullableInt64"); + var nullableInt64Array = runtimeEntityType.FindProperty("NullableInt64Array"); + var nullableInt8 = runtimeEntityType.FindProperty("NullableInt8"); + var nullableInt8Array = runtimeEntityType.FindProperty("NullableInt8Array"); + var nullablePhysicalAddress = runtimeEntityType.FindProperty("NullablePhysicalAddress"); + var nullablePhysicalAddressArray = runtimeEntityType.FindProperty("NullablePhysicalAddressArray"); + var nullableString = runtimeEntityType.FindProperty("NullableString"); + var nullableStringArray = runtimeEntityType.FindProperty("NullableStringArray"); + var nullableTimeOnly = runtimeEntityType.FindProperty("NullableTimeOnly"); + var nullableTimeOnlyArray = runtimeEntityType.FindProperty("NullableTimeOnlyArray"); + var nullableTimeSpan = runtimeEntityType.FindProperty("NullableTimeSpan"); + var nullableTimeSpanArray = runtimeEntityType.FindProperty("NullableTimeSpanArray"); + var nullableUInt16 = runtimeEntityType.FindProperty("NullableUInt16"); + var nullableUInt16Array = runtimeEntityType.FindProperty("NullableUInt16Array"); + var nullableUInt32 = runtimeEntityType.FindProperty("NullableUInt32"); + var nullableUInt32Array = runtimeEntityType.FindProperty("NullableUInt32Array"); + var nullableUInt64 = runtimeEntityType.FindProperty("NullableUInt64"); + var nullableUInt64Array = runtimeEntityType.FindProperty("NullableUInt64Array"); + var nullableUInt8 = runtimeEntityType.FindProperty("NullableUInt8"); + var nullableUInt8Array = runtimeEntityType.FindProperty("NullableUInt8Array"); + var nullableUri = runtimeEntityType.FindProperty("NullableUri"); + var nullableUriArray = runtimeEntityType.FindProperty("NullableUriArray"); + var physicalAddress = runtimeEntityType.FindProperty("PhysicalAddress"); + var physicalAddressArray = runtimeEntityType.FindProperty("PhysicalAddressArray"); + var physicalAddressToBytesConverterProperty = runtimeEntityType.FindProperty("PhysicalAddressToBytesConverterProperty"); + var physicalAddressToStringConverterProperty = runtimeEntityType.FindProperty("PhysicalAddressToStringConverterProperty"); + var @string = runtimeEntityType.FindProperty("String"); + var stringArray = runtimeEntityType.FindProperty("StringArray"); + var stringToBoolConverterProperty = runtimeEntityType.FindProperty("StringToBoolConverterProperty"); + var stringToBytesConverterProperty = runtimeEntityType.FindProperty("StringToBytesConverterProperty"); + var stringToCharConverterProperty = runtimeEntityType.FindProperty("StringToCharConverterProperty"); + var stringToDateOnlyConverterProperty = runtimeEntityType.FindProperty("StringToDateOnlyConverterProperty"); + var stringToDateTimeConverterProperty = runtimeEntityType.FindProperty("StringToDateTimeConverterProperty"); + var stringToDateTimeOffsetConverterProperty = runtimeEntityType.FindProperty("StringToDateTimeOffsetConverterProperty"); + var stringToDecimalNumberConverterProperty = runtimeEntityType.FindProperty("StringToDecimalNumberConverterProperty"); + var stringToDoubleNumberConverterProperty = runtimeEntityType.FindProperty("StringToDoubleNumberConverterProperty"); + var stringToEnumConverterProperty = runtimeEntityType.FindProperty("StringToEnumConverterProperty"); + var stringToGuidConverterProperty = runtimeEntityType.FindProperty("StringToGuidConverterProperty"); + var stringToIntNumberConverterProperty = runtimeEntityType.FindProperty("StringToIntNumberConverterProperty"); + var stringToTimeOnlyConverterProperty = runtimeEntityType.FindProperty("StringToTimeOnlyConverterProperty"); + var stringToTimeSpanConverterProperty = runtimeEntityType.FindProperty("StringToTimeSpanConverterProperty"); + var stringToUriConverterProperty = runtimeEntityType.FindProperty("StringToUriConverterProperty"); + var timeOnly = runtimeEntityType.FindProperty("TimeOnly"); + var timeOnlyArray = runtimeEntityType.FindProperty("TimeOnlyArray"); + var timeOnlyToStringConverterProperty = runtimeEntityType.FindProperty("TimeOnlyToStringConverterProperty"); + var timeOnlyToTicksConverterProperty = runtimeEntityType.FindProperty("TimeOnlyToTicksConverterProperty"); + var timeSpan = runtimeEntityType.FindProperty("TimeSpan"); + var timeSpanArray = runtimeEntityType.FindProperty("TimeSpanArray"); + var timeSpanToStringConverterProperty = runtimeEntityType.FindProperty("TimeSpanToStringConverterProperty"); + var timeSpanToTicksConverterProperty = runtimeEntityType.FindProperty("TimeSpanToTicksConverterProperty"); + var uInt16 = runtimeEntityType.FindProperty("UInt16"); + var uInt16Array = runtimeEntityType.FindProperty("UInt16Array"); + var uInt32 = runtimeEntityType.FindProperty("UInt32"); + var uInt32Array = runtimeEntityType.FindProperty("UInt32Array"); + var uInt64 = runtimeEntityType.FindProperty("UInt64"); + var uInt64Array = runtimeEntityType.FindProperty("UInt64Array"); + var uInt8 = runtimeEntityType.FindProperty("UInt8"); + var uInt8Array = runtimeEntityType.FindProperty("UInt8Array"); + var uri = runtimeEntityType.FindProperty("Uri"); + var uriArray = runtimeEntityType.FindProperty("UriArray"); + var uriToStringConverterProperty = runtimeEntityType.FindProperty("UriToStringConverterProperty"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/OwnedType0EntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/OwnedType0EntityType.cs index dc99359270a..e3769f85a94 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/OwnedType0EntityType.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/OwnedType0EntityType.cs @@ -103,25 +103,25 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas principalDerivedAlternateId.SetCurrentValueComparer(new EntryCurrentValueComparer(principalDerivedAlternateId)); principalDerivedAlternateId.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); - var id = runtimeEntityType.AddProperty( - "Id", + var __synthesizedOrdinal = runtimeEntityType.AddProperty( + "__synthesizedOrdinal", typeof(int), valueGenerated: ValueGenerated.OnAdd, afterSaveBehavior: PropertySaveBehavior.Throw, sentinel: 0); - id.SetAccessors( + __synthesizedOrdinal.SetAccessors( int (InternalEntityEntry entry) => (entry.FlaggedAsStoreGenerated(2) ? entry.ReadStoreGeneratedValue(2) : (entry.FlaggedAsTemporary(2) && entry.ReadShadowValue(2) == 0 ? entry.ReadTemporaryValue(2) : entry.ReadShadowValue(2))), int (InternalEntityEntry entry) => entry.ReadShadowValue(2), - int (InternalEntityEntry entry) => entry.ReadOriginalValue(id, 2), - int (InternalEntityEntry entry) => entry.ReadRelationshipSnapshotValue(id, 2), + int (InternalEntityEntry entry) => entry.ReadOriginalValue(__synthesizedOrdinal, 2), + int (InternalEntityEntry entry) => entry.ReadRelationshipSnapshotValue(__synthesizedOrdinal, 2), object (ValueBuffer valueBuffer) => valueBuffer[2]); - id.SetPropertyIndexes( + __synthesizedOrdinal.SetPropertyIndexes( index: 2, originalValueIndex: 2, shadowIndex: 2, relationshipIndex: 2, storeGenerationIndex: 2); - id.TypeMapping = IntTypeMapping.Default.Clone( + __synthesizedOrdinal.TypeMapping = IntTypeMapping.Default.Clone( comparer: new ValueComparer( bool (int v1, int v2) => v1 == v2, int (int v) => v, @@ -134,8 +134,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (int v1, int v2) => v1 == v2, int (int v) => v, int (int v) => v)); - id.SetCurrentValueComparer(new EntryCurrentValueComparer(id)); - id.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + __synthesizedOrdinal.SetCurrentValueComparer(new EntryCurrentValueComparer(__synthesizedOrdinal)); + __synthesizedOrdinal.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); var details = runtimeEntityType.AddProperty( "Details", @@ -802,7 +802,7 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas storeGenerationIndex: -1); var key = runtimeEntityType.AddKey( - new[] { principalDerivedId, principalDerivedAlternateId, id }); + new[] { principalDerivedId, principalDerivedAlternateId, __synthesizedOrdinal }); runtimeEntityType.SetPrimaryKey(key); return runtimeEntityType; @@ -856,41 +856,41 @@ public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEnt public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var principalDerivedId = runtimeEntityType.FindProperty("PrincipalDerivedId")!; - var principalDerivedAlternateId = runtimeEntityType.FindProperty("PrincipalDerivedAlternateId")!; - var id = runtimeEntityType.FindProperty("Id")!; - var details = runtimeEntityType.FindProperty("Details")!; - var number = runtimeEntityType.FindProperty("Number")!; - var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray")!; - var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable")!; - var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList")!; - var refTypeList = runtimeEntityType.FindProperty("RefTypeList")!; - var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList")!; - var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList")!; - var key = runtimeEntityType.FindKey(new[] { principalDerivedId, principalDerivedAlternateId, id }); + var principalDerivedId = runtimeEntityType.FindProperty("PrincipalDerivedId"); + var principalDerivedAlternateId = runtimeEntityType.FindProperty("PrincipalDerivedAlternateId"); + var __synthesizedOrdinal = runtimeEntityType.FindProperty("__synthesizedOrdinal"); + var details = runtimeEntityType.FindProperty("Details"); + var number = runtimeEntityType.FindProperty("Number"); + var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray"); + var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable"); + var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList"); + var refTypeList = runtimeEntityType.FindProperty("RefTypeList"); + var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList"); + var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList"); + var key = runtimeEntityType.FindKey(new[] { principalDerivedId, principalDerivedAlternateId, __synthesizedOrdinal }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateCompositeFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory>(key)); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { var entity7 = ((CompiledModelTestBase.OwnedType)(source.Entity)); - return ((ISnapshot)(new Snapshot, IList, List, DateTime[], IEnumerable, IList, List>(((ValueComparer)(((IProperty)principalDerivedId).GetValueComparer())).Snapshot(source.GetCurrentValue(principalDerivedId)), ((ValueComparer)(((IProperty)principalDerivedAlternateId).GetValueComparer())).Snapshot(source.GetCurrentValue(principalDerivedAlternateId)), ((ValueComparer)(((IProperty)id).GetValueComparer())).Snapshot(source.GetCurrentValue(id)), (source.GetCurrentValue(details) == null ? null : ((ValueComparer)(((IProperty)details).GetValueComparer())).Snapshot(source.GetCurrentValue(details))), ((ValueComparer)(((IProperty)number).GetValueComparer())).Snapshot(source.GetCurrentValue(number)), (((object)(source.GetCurrentValue(refTypeArray))) == null ? null : ((IPAddress[])(((ValueComparer)(((IProperty)refTypeArray).GetValueComparer())).Snapshot(((object)(source.GetCurrentValue(refTypeArray))))))), (((object)(source.GetCurrentValue>(refTypeEnumerable))) == null ? null : ((IEnumerable)(((ValueComparer)(((IProperty)refTypeEnumerable).GetValueComparer())).Snapshot(((object)(source.GetCurrentValue>(refTypeEnumerable))))))), (((object)(source.GetCurrentValue>(refTypeIList))) == null ? null : ((IList)(((ValueComparer)(((IProperty)refTypeIList).GetValueComparer())).Snapshot(((object)(source.GetCurrentValue>(refTypeIList))))))), (((object)(source.GetCurrentValue>(refTypeList))) == null ? null : ((List)(((ValueComparer)(((IProperty)refTypeList).GetValueComparer())).Snapshot(((object)(source.GetCurrentValue>(refTypeList))))))), (((IEnumerable)(source.GetCurrentValue(valueTypeArray))) == null ? null : ((DateTime[])(((ValueComparer>)(((IProperty)valueTypeArray).GetValueComparer())).Snapshot(((IEnumerable)(source.GetCurrentValue(valueTypeArray))))))), (source.GetCurrentValue>(valueTypeEnumerable) == null ? null : ((ValueComparer>)(((IProperty)valueTypeEnumerable).GetValueComparer())).Snapshot(source.GetCurrentValue>(valueTypeEnumerable))), (((IEnumerable)(source.GetCurrentValue>(valueTypeIList))) == null ? null : ((IList)(((ValueComparer>)(((IProperty)valueTypeIList).GetValueComparer())).Snapshot(((IEnumerable)(source.GetCurrentValue>(valueTypeIList))))))), (((IEnumerable)(source.GetCurrentValue>(valueTypeList))) == null ? null : ((List)(((ValueComparer>)(((IProperty)valueTypeList).GetValueComparer())).Snapshot(((IEnumerable)(source.GetCurrentValue>(valueTypeList)))))))))); + return ((ISnapshot)(new Snapshot, IList, List, DateTime[], IEnumerable, IList, List>(((ValueComparer)(((IProperty)principalDerivedId).GetValueComparer())).Snapshot(source.GetCurrentValue(principalDerivedId)), ((ValueComparer)(((IProperty)principalDerivedAlternateId).GetValueComparer())).Snapshot(source.GetCurrentValue(principalDerivedAlternateId)), ((ValueComparer)(((IProperty)__synthesizedOrdinal).GetValueComparer())).Snapshot(source.GetCurrentValue(__synthesizedOrdinal)), (source.GetCurrentValue(details) == null ? null : ((ValueComparer)(((IProperty)details).GetValueComparer())).Snapshot(source.GetCurrentValue(details))), ((ValueComparer)(((IProperty)number).GetValueComparer())).Snapshot(source.GetCurrentValue(number)), (((object)(source.GetCurrentValue(refTypeArray))) == null ? null : ((IPAddress[])(((ValueComparer)(((IProperty)refTypeArray).GetValueComparer())).Snapshot(((object)(source.GetCurrentValue(refTypeArray))))))), (((object)(source.GetCurrentValue>(refTypeEnumerable))) == null ? null : ((IEnumerable)(((ValueComparer)(((IProperty)refTypeEnumerable).GetValueComparer())).Snapshot(((object)(source.GetCurrentValue>(refTypeEnumerable))))))), (((object)(source.GetCurrentValue>(refTypeIList))) == null ? null : ((IList)(((ValueComparer)(((IProperty)refTypeIList).GetValueComparer())).Snapshot(((object)(source.GetCurrentValue>(refTypeIList))))))), (((object)(source.GetCurrentValue>(refTypeList))) == null ? null : ((List)(((ValueComparer)(((IProperty)refTypeList).GetValueComparer())).Snapshot(((object)(source.GetCurrentValue>(refTypeList))))))), (((IEnumerable)(source.GetCurrentValue(valueTypeArray))) == null ? null : ((DateTime[])(((ValueComparer>)(((IProperty)valueTypeArray).GetValueComparer())).Snapshot(((IEnumerable)(source.GetCurrentValue(valueTypeArray))))))), (source.GetCurrentValue>(valueTypeEnumerable) == null ? null : ((ValueComparer>)(((IProperty)valueTypeEnumerable).GetValueComparer())).Snapshot(source.GetCurrentValue>(valueTypeEnumerable))), (((IEnumerable)(source.GetCurrentValue>(valueTypeIList))) == null ? null : ((IList)(((ValueComparer>)(((IProperty)valueTypeIList).GetValueComparer())).Snapshot(((IEnumerable)(source.GetCurrentValue>(valueTypeIList))))))), (((IEnumerable)(source.GetCurrentValue>(valueTypeList))) == null ? null : ((List)(((ValueComparer>)(((IProperty)valueTypeList).GetValueComparer())).Snapshot(((IEnumerable)(source.GetCurrentValue>(valueTypeList)))))))))); }); runtimeEntityType.SetStoreGeneratedValuesFactory( - ISnapshot () => ((ISnapshot)(new Snapshot(((ValueComparer)(((IProperty)principalDerivedId).GetValueComparer())).Snapshot(default(long)), ((ValueComparer)(((IProperty)principalDerivedAlternateId).GetValueComparer())).Snapshot(default(Guid)), ((ValueComparer)(((IProperty)id).GetValueComparer())).Snapshot(default(int)))))); + ISnapshot () => ((ISnapshot)(new Snapshot(((ValueComparer)(((IProperty)principalDerivedId).GetValueComparer())).Snapshot(default(long)), ((ValueComparer)(((IProperty)principalDerivedAlternateId).GetValueComparer())).Snapshot(default(Guid)), ((ValueComparer)(((IProperty)__synthesizedOrdinal).GetValueComparer())).Snapshot(default(int)))))); runtimeEntityType.SetTemporaryValuesFactory( ISnapshot (InternalEntityEntry source) => ((ISnapshot)(new Snapshot(default(long), default(Guid), default(int))))); runtimeEntityType.SetShadowValuesFactory( - ISnapshot (IDictionary source) => ((ISnapshot)(new Snapshot((source.ContainsKey("PrincipalDerivedId") ? ((long)(source["PrincipalDerivedId"])) : 0L), (source.ContainsKey("PrincipalDerivedAlternateId") ? ((Guid)(source["PrincipalDerivedAlternateId"])) : new Guid("00000000-0000-0000-0000-000000000000")), (source.ContainsKey("Id") ? ((int)(source["Id"])) : 0))))); + ISnapshot (IDictionary source) => ((ISnapshot)(new Snapshot((source.ContainsKey("PrincipalDerivedId") ? ((long)(source["PrincipalDerivedId"])) : 0L), (source.ContainsKey("PrincipalDerivedAlternateId") ? ((Guid)(source["PrincipalDerivedAlternateId"])) : new Guid("00000000-0000-0000-0000-000000000000")), (source.ContainsKey("__synthesizedOrdinal") ? ((int)(source["__synthesizedOrdinal"])) : 0))))); runtimeEntityType.SetEmptyShadowValuesFactory( ISnapshot () => ((ISnapshot)(new Snapshot(default(long), default(Guid), default(int))))); runtimeEntityType.SetRelationshipSnapshotFactory( ISnapshot (InternalEntityEntry source) => { var entity7 = ((CompiledModelTestBase.OwnedType)(source.Entity)); - return ((ISnapshot)(new Snapshot(((ValueComparer)(((IProperty)principalDerivedId).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(principalDerivedId)), ((ValueComparer)(((IProperty)principalDerivedAlternateId).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(principalDerivedAlternateId)), ((ValueComparer)(((IProperty)id).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(id))))); + return ((ISnapshot)(new Snapshot(((ValueComparer)(((IProperty)principalDerivedId).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(principalDerivedId)), ((ValueComparer)(((IProperty)principalDerivedAlternateId).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(principalDerivedAlternateId)), ((ValueComparer)(((IProperty)__synthesizedOrdinal).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(__synthesizedOrdinal))))); }); runtimeEntityType.Counts = new PropertyCounts( propertyCount: 13, diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/OwnedTypeEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/OwnedTypeEntityType.cs index 854fb50a7cc..7d8c447f6c0 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/OwnedTypeEntityType.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/OwnedTypeEntityType.cs @@ -833,18 +833,18 @@ public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEnt public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var principalBaseId = runtimeEntityType.FindProperty("PrincipalBaseId")!; - var principalBaseAlternateId = runtimeEntityType.FindProperty("PrincipalBaseAlternateId")!; - var details = runtimeEntityType.FindProperty("Details")!; - var number = runtimeEntityType.FindProperty("Number")!; - var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray")!; - var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable")!; - var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList")!; - var refTypeList = runtimeEntityType.FindProperty("RefTypeList")!; - var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList")!; - var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList")!; + var principalBaseId = runtimeEntityType.FindProperty("PrincipalBaseId"); + var principalBaseAlternateId = runtimeEntityType.FindProperty("PrincipalBaseAlternateId"); + var details = runtimeEntityType.FindProperty("Details"); + var number = runtimeEntityType.FindProperty("Number"); + var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray"); + var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable"); + var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList"); + var refTypeList = runtimeEntityType.FindProperty("RefTypeList"); + var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList"); + var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList"); var key = runtimeEntityType.FindKey(new[] { principalBaseId, principalBaseAlternateId }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateCompositeFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory>(key)); diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/PrincipalBaseEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/PrincipalBaseEntityType.cs index 343b3fef963..670fa352a16 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/PrincipalBaseEntityType.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/PrincipalBaseEntityType.cs @@ -79,9 +79,9 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (long v1, long v2) => v1 == v2, int (long v) => ((object)v).GetHashCode(), long (long v) => v)); - id.SetValueComparer(new NullableValueComparer(id.TypeMapping.Comparer)); - id.SetKeyValueComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); id.SetCurrentValueComparer(new EntryCurrentValueComparer(id)); + id.SetComparer(new NullableValueComparer(id.TypeMapping.Comparer)); + id.SetKeyComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); id.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var alternateId = runtimeEntityType.AddProperty( @@ -267,8 +267,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( int (CompiledModelTestBase.AnEnum value) => ((int)(value)), CompiledModelTestBase.AnEnum (int value) => ((CompiledModelTestBase.AnEnum)(value))))); - enum2.SetValueComparer(new NullableValueComparer(enum2.TypeMapping.Comparer)); - enum2.SetKeyValueComparer(new NullableValueComparer(enum2.TypeMapping.KeyComparer)); + enum2.SetComparer(new NullableValueComparer(enum2.TypeMapping.Comparer)); + enum2.SetKeyComparer(new NullableValueComparer(enum2.TypeMapping.KeyComparer)); enum2.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var flagsEnum1 = runtimeEntityType.AddProperty( @@ -1004,28 +1004,28 @@ public static RuntimeSkipNavigation CreateSkipNavigation1(RuntimeEntityType decl public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var alternateId = runtimeEntityType.FindProperty("AlternateId")!; - var discriminator = runtimeEntityType.FindProperty("Discriminator")!; - var enum1 = runtimeEntityType.FindProperty("Enum1")!; - var enum2 = runtimeEntityType.FindProperty("Enum2")!; - var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1")!; - var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2")!; - var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray")!; - var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable")!; - var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList")!; - var refTypeList = runtimeEntityType.FindProperty("RefTypeList")!; - var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList")!; - var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList")!; + var id = runtimeEntityType.FindProperty("Id"); + var alternateId = runtimeEntityType.FindProperty("AlternateId"); + var discriminator = runtimeEntityType.FindProperty("Discriminator"); + var enum1 = runtimeEntityType.FindProperty("Enum1"); + var enum2 = runtimeEntityType.FindProperty("Enum2"); + var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1"); + var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2"); + var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray"); + var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable"); + var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList"); + var refTypeList = runtimeEntityType.FindProperty("RefTypeList"); + var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList"); + var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); var key0 = runtimeEntityType.FindKey(new[] { id, alternateId }); key0.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateCompositeFactory(key0)); key0.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory>(key0)); - var owned = runtimeEntityType.FindNavigation("Owned")!; + var owned = runtimeEntityType.FindNavigation("Owned"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { @@ -1044,7 +1044,7 @@ public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) ISnapshot (InternalEntityEntry source) => { var entity7 = ((CompiledModelTestBase.PrincipalBase)(source.Entity)); - return ((ISnapshot)(new Snapshot((source.GetCurrentValue(id) == null ? null : ((ValueComparer)(((IProperty)id).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(id))), ((ValueComparer)(((IProperty)alternateId).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(alternateId)), PrincipalBaseUnsafeAccessors._ownedField(entity7), null))); + return ((ISnapshot)(new Snapshot((source.GetCurrentValue(id) == null ? null : ((ValueComparer)(((IProperty)id).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(id))), ((ValueComparer)(((IProperty)alternateId).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(alternateId)), PrincipalBaseUnsafeAccessors._ownedField(entity7), (object)(null)))); }); runtimeEntityType.Counts = new PropertyCounts( propertyCount: 15, diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs index 1dfe2531b5f..762b316cf9a 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs @@ -386,11 +386,11 @@ public static RuntimeForeignKey CreateForeignKey2(RuntimeEntityType declaringEnt public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var derivedsId = runtimeEntityType.FindProperty("DerivedsId")!; - var derivedsAlternateId = runtimeEntityType.FindProperty("DerivedsAlternateId")!; - var principalsId = runtimeEntityType.FindProperty("PrincipalsId")!; - var principalsAlternateId = runtimeEntityType.FindProperty("PrincipalsAlternateId")!; - var rowid = runtimeEntityType.FindProperty("rowid")!; + var derivedsId = runtimeEntityType.FindProperty("DerivedsId"); + var derivedsAlternateId = runtimeEntityType.FindProperty("DerivedsAlternateId"); + var principalsId = runtimeEntityType.FindProperty("PrincipalsId"); + var principalsAlternateId = runtimeEntityType.FindProperty("PrincipalsAlternateId"); + var rowid = runtimeEntityType.FindProperty("rowid"); var key = runtimeEntityType.FindKey(new[] { derivedsId, derivedsAlternateId, principalsId, principalsAlternateId }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateCompositeFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory>(key)); diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/PrincipalDerivedEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/PrincipalDerivedEntityType.cs index ae4fc02a942..c163ccd8002 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/PrincipalDerivedEntityType.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/PrincipalDerivedEntityType.cs @@ -87,24 +87,24 @@ public static RuntimeSkipNavigation CreateSkipNavigation1(RuntimeEntityType decl public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var alternateId = runtimeEntityType.FindProperty("AlternateId")!; - var discriminator = runtimeEntityType.FindProperty("Discriminator")!; - var enum1 = runtimeEntityType.FindProperty("Enum1")!; - var enum2 = runtimeEntityType.FindProperty("Enum2")!; - var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1")!; - var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2")!; - var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray")!; - var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable")!; - var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList")!; - var refTypeList = runtimeEntityType.FindProperty("RefTypeList")!; - var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList")!; - var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList")!; - var owned = runtimeEntityType.FindNavigation("Owned")!; - var dependent = runtimeEntityType.FindNavigation("Dependent")!; - var manyOwned = runtimeEntityType.FindNavigation("ManyOwned")!; + var id = runtimeEntityType.FindProperty("Id"); + var alternateId = runtimeEntityType.FindProperty("AlternateId"); + var discriminator = runtimeEntityType.FindProperty("Discriminator"); + var enum1 = runtimeEntityType.FindProperty("Enum1"); + var enum2 = runtimeEntityType.FindProperty("Enum2"); + var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1"); + var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2"); + var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray"); + var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable"); + var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList"); + var refTypeList = runtimeEntityType.FindProperty("RefTypeList"); + var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList"); + var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList"); + var owned = runtimeEntityType.FindNavigation("Owned"); + var dependent = runtimeEntityType.FindNavigation("Dependent"); + var manyOwned = runtimeEntityType.FindNavigation("ManyOwned"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { @@ -123,7 +123,7 @@ public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) ISnapshot (InternalEntityEntry source) => { var entity7 = ((CompiledModelTestBase.PrincipalDerived>)(source.Entity)); - return ((ISnapshot)(new Snapshot((source.GetCurrentValue(id) == null ? null : ((ValueComparer)(((IProperty)id).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(id))), ((ValueComparer)(((IProperty)alternateId).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(alternateId)), PrincipalBaseUnsafeAccessors._ownedField(entity7), null, PrincipalDerivedUnsafeAccessors>.Dependent(entity7), SnapshotFactoryFactory.SnapshotCollection(PrincipalDerivedUnsafeAccessors>.ManyOwned(entity7)), null))); + return ((ISnapshot)(new Snapshot((source.GetCurrentValue(id) == null ? null : ((ValueComparer)(((IProperty)id).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(id))), ((ValueComparer)(((IProperty)alternateId).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(alternateId)), PrincipalBaseUnsafeAccessors._ownedField(entity7), (object)(null), PrincipalDerivedUnsafeAccessors>.Dependent(entity7), SnapshotFactoryFactory.SnapshotCollection(PrincipalDerivedUnsafeAccessors>.ManyOwned(entity7)), (object)(null)))); }); runtimeEntityType.Counts = new PropertyCounts( propertyCount: 15, diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/CheckConstraints/DataEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/CheckConstraints/DataEntityType.cs index 5e6c430cf8b..5e83c15c5d8 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/CheckConstraints/DataEntityType.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/CheckConstraints/DataEntityType.cs @@ -118,8 +118,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var blob = runtimeEntityType.FindProperty("Blob")!; + var id = runtimeEntityType.FindProperty("Id"); + var blob = runtimeEntityType.FindProperty("Blob"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalBaseEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalBaseEntityType.cs index 498d6dc463e..b88d873aec4 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalBaseEntityType.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalBaseEntityType.cs @@ -81,9 +81,9 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (long v1, long v2) => v1 == v2, int (long v) => ((object)v).GetHashCode(), long (long v) => v)); - id.SetValueComparer(new NullableValueComparer(id.TypeMapping.Comparer)); - id.SetKeyValueComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); id.SetCurrentValueComparer(new EntryCurrentValueComparer(id)); + id.SetComparer(new NullableValueComparer(id.TypeMapping.Comparer)); + id.SetKeyComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); id.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); var discriminator = runtimeEntityType.AddProperty( @@ -222,8 +222,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( int (CompiledModelTestBase.AnEnum value) => ((int)(value)), CompiledModelTestBase.AnEnum (int value) => ((CompiledModelTestBase.AnEnum)(value))))); - enum2.SetValueComparer(new NullableValueComparer(enum2.TypeMapping.Comparer)); - enum2.SetKeyValueComparer(new NullableValueComparer(enum2.TypeMapping.KeyComparer)); + enum2.SetComparer(new NullableValueComparer(enum2.TypeMapping.Comparer)); + enum2.SetKeyComparer(new NullableValueComparer(enum2.TypeMapping.KeyComparer)); enum2.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var flagsEnum1 = runtimeEntityType.AddProperty( @@ -355,9 +355,9 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (long v1, long v2) => v1 == v2, int (long v) => ((object)v).GetHashCode(), long (long v) => v)); - principalBaseId.SetValueComparer(new NullableValueComparer(principalBaseId.TypeMapping.Comparer)); - principalBaseId.SetKeyValueComparer(new NullableValueComparer(principalBaseId.TypeMapping.KeyComparer)); principalBaseId.SetCurrentValueComparer(new EntryCurrentValueComparer(principalBaseId)); + principalBaseId.SetComparer(new NullableValueComparer(principalBaseId.TypeMapping.Comparer)); + principalBaseId.SetKeyComparer(new NullableValueComparer(principalBaseId.TypeMapping.KeyComparer)); principalBaseId.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var refTypeArray = runtimeEntityType.AddProperty( @@ -1943,8 +1943,8 @@ public static RuntimeComplexProperty Create(RuntimeComplexType declaringType) new ValueConverter( int (CompiledModelTestBase.AnEnum value) => ((int)(value)), CompiledModelTestBase.AnEnum (int value) => ((CompiledModelTestBase.AnEnum)(value))))); - enum2.SetValueComparer(new NullableValueComparer(enum2.TypeMapping.Comparer)); - enum2.SetKeyValueComparer(new NullableValueComparer(enum2.TypeMapping.KeyComparer)); + enum2.SetComparer(new NullableValueComparer(enum2.TypeMapping.Comparer)); + enum2.SetKeyComparer(new NullableValueComparer(enum2.TypeMapping.KeyComparer)); enum2.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var flagsEnum1 = complexType.AddProperty( @@ -2117,8 +2117,8 @@ public static RuntimeComplexProperty Create(RuntimeComplexType declaringType) bool (long v1, long v2) => v1 == v2, int (long v) => ((object)v).GetHashCode(), long (long v) => v)); - id.SetValueComparer(new NullableValueComparer(id.TypeMapping.Comparer)); - id.SetKeyValueComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); + id.SetComparer(new NullableValueComparer(id.TypeMapping.Comparer)); + id.SetKeyComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); id.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var refTypeArray = complexType.AddProperty( @@ -2821,53 +2821,53 @@ public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEnt public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var discriminator = runtimeEntityType.FindProperty("Discriminator")!; - var enum1 = runtimeEntityType.FindProperty("Enum1")!; - var enum2 = runtimeEntityType.FindProperty("Enum2")!; - var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1")!; - var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2")!; - var principalBaseId = runtimeEntityType.FindProperty("PrincipalBaseId")!; - var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray")!; - var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable")!; - var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList")!; - var refTypeList = runtimeEntityType.FindProperty("RefTypeList")!; - var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList")!; - var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList")!; - var owned = runtimeEntityType.FindComplexProperty("Owned")!; + var id = runtimeEntityType.FindProperty("Id"); + var discriminator = runtimeEntityType.FindProperty("Discriminator"); + var enum1 = runtimeEntityType.FindProperty("Enum1"); + var enum2 = runtimeEntityType.FindProperty("Enum2"); + var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1"); + var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2"); + var principalBaseId = runtimeEntityType.FindProperty("PrincipalBaseId"); + var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray"); + var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable"); + var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList"); + var refTypeList = runtimeEntityType.FindProperty("RefTypeList"); + var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList"); + var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList"); + var owned = runtimeEntityType.FindComplexProperty("Owned"); var ownedType = owned.ComplexType; - var details = ownedType.FindProperty("Details")!; - var number = ownedType.FindProperty("Number")!; - var refTypeArray0 = ownedType.FindProperty("RefTypeArray")!; - var refTypeEnumerable0 = ownedType.FindProperty("RefTypeEnumerable")!; - var refTypeIList0 = ownedType.FindProperty("RefTypeIList")!; - var refTypeList0 = ownedType.FindProperty("RefTypeList")!; - var valueTypeArray0 = ownedType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable0 = ownedType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList0 = ownedType.FindProperty("ValueTypeIList")!; - var valueTypeList0 = ownedType.FindProperty("ValueTypeList")!; - var principal = ownedType.FindComplexProperty("Principal")!; + var details = ownedType.FindProperty("Details"); + var number = ownedType.FindProperty("Number"); + var refTypeArray0 = ownedType.FindProperty("RefTypeArray"); + var refTypeEnumerable0 = ownedType.FindProperty("RefTypeEnumerable"); + var refTypeIList0 = ownedType.FindProperty("RefTypeIList"); + var refTypeList0 = ownedType.FindProperty("RefTypeList"); + var valueTypeArray0 = ownedType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable0 = ownedType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList0 = ownedType.FindProperty("ValueTypeIList"); + var valueTypeList0 = ownedType.FindProperty("ValueTypeList"); + var principal = ownedType.FindComplexProperty("Principal"); var principalBase = principal.ComplexType; - var alternateId = principalBase.FindProperty("AlternateId")!; - var enum10 = principalBase.FindProperty("Enum1")!; - var enum20 = principalBase.FindProperty("Enum2")!; - var flagsEnum10 = principalBase.FindProperty("FlagsEnum1")!; - var flagsEnum20 = principalBase.FindProperty("FlagsEnum2")!; - var id0 = principalBase.FindProperty("Id")!; - var refTypeArray1 = principalBase.FindProperty("RefTypeArray")!; - var refTypeEnumerable1 = principalBase.FindProperty("RefTypeEnumerable")!; - var refTypeIList1 = principalBase.FindProperty("RefTypeIList")!; - var refTypeList1 = principalBase.FindProperty("RefTypeList")!; - var valueTypeArray1 = principalBase.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable1 = principalBase.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList1 = principalBase.FindProperty("ValueTypeIList")!; - var valueTypeList1 = principalBase.FindProperty("ValueTypeList")!; + var alternateId = principalBase.FindProperty("AlternateId"); + var enum10 = principalBase.FindProperty("Enum1"); + var enum20 = principalBase.FindProperty("Enum2"); + var flagsEnum10 = principalBase.FindProperty("FlagsEnum1"); + var flagsEnum20 = principalBase.FindProperty("FlagsEnum2"); + var id0 = principalBase.FindProperty("Id"); + var refTypeArray1 = principalBase.FindProperty("RefTypeArray"); + var refTypeEnumerable1 = principalBase.FindProperty("RefTypeEnumerable"); + var refTypeIList1 = principalBase.FindProperty("RefTypeIList"); + var refTypeList1 = principalBase.FindProperty("RefTypeList"); + var valueTypeArray1 = principalBase.FindProperty("ValueTypeArray"); + var valueTypeEnumerable1 = principalBase.FindProperty("ValueTypeEnumerable"); + var valueTypeIList1 = principalBase.FindProperty("ValueTypeIList"); + var valueTypeList1 = principalBase.FindProperty("ValueTypeList"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); - var deriveds = runtimeEntityType.FindNavigation("Deriveds")!; + var deriveds = runtimeEntityType.FindNavigation("Deriveds"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalDerivedEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalDerivedEntityType.cs index a2fada2d58f..c853af35e1d 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalDerivedEntityType.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalDerivedEntityType.cs @@ -33,50 +33,50 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var discriminator = runtimeEntityType.FindProperty("Discriminator")!; - var enum1 = runtimeEntityType.FindProperty("Enum1")!; - var enum2 = runtimeEntityType.FindProperty("Enum2")!; - var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1")!; - var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2")!; - var principalBaseId = runtimeEntityType.FindProperty("PrincipalBaseId")!; - var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray")!; - var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable")!; - var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList")!; - var refTypeList = runtimeEntityType.FindProperty("RefTypeList")!; - var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList")!; - var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList")!; - var owned = runtimeEntityType.FindComplexProperty("Owned")!; + var id = runtimeEntityType.FindProperty("Id"); + var discriminator = runtimeEntityType.FindProperty("Discriminator"); + var enum1 = runtimeEntityType.FindProperty("Enum1"); + var enum2 = runtimeEntityType.FindProperty("Enum2"); + var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1"); + var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2"); + var principalBaseId = runtimeEntityType.FindProperty("PrincipalBaseId"); + var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray"); + var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable"); + var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList"); + var refTypeList = runtimeEntityType.FindProperty("RefTypeList"); + var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList"); + var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList"); + var owned = runtimeEntityType.FindComplexProperty("Owned"); var ownedType = owned.ComplexType; - var details = ownedType.FindProperty("Details")!; - var number = ownedType.FindProperty("Number")!; - var refTypeArray0 = ownedType.FindProperty("RefTypeArray")!; - var refTypeEnumerable0 = ownedType.FindProperty("RefTypeEnumerable")!; - var refTypeIList0 = ownedType.FindProperty("RefTypeIList")!; - var refTypeList0 = ownedType.FindProperty("RefTypeList")!; - var valueTypeArray0 = ownedType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable0 = ownedType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList0 = ownedType.FindProperty("ValueTypeIList")!; - var valueTypeList0 = ownedType.FindProperty("ValueTypeList")!; - var principal = ownedType.FindComplexProperty("Principal")!; + var details = ownedType.FindProperty("Details"); + var number = ownedType.FindProperty("Number"); + var refTypeArray0 = ownedType.FindProperty("RefTypeArray"); + var refTypeEnumerable0 = ownedType.FindProperty("RefTypeEnumerable"); + var refTypeIList0 = ownedType.FindProperty("RefTypeIList"); + var refTypeList0 = ownedType.FindProperty("RefTypeList"); + var valueTypeArray0 = ownedType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable0 = ownedType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList0 = ownedType.FindProperty("ValueTypeIList"); + var valueTypeList0 = ownedType.FindProperty("ValueTypeList"); + var principal = ownedType.FindComplexProperty("Principal"); var principalBase = principal.ComplexType; - var alternateId = principalBase.FindProperty("AlternateId")!; - var enum10 = principalBase.FindProperty("Enum1")!; - var enum20 = principalBase.FindProperty("Enum2")!; - var flagsEnum10 = principalBase.FindProperty("FlagsEnum1")!; - var flagsEnum20 = principalBase.FindProperty("FlagsEnum2")!; - var id0 = principalBase.FindProperty("Id")!; - var refTypeArray1 = principalBase.FindProperty("RefTypeArray")!; - var refTypeEnumerable1 = principalBase.FindProperty("RefTypeEnumerable")!; - var refTypeIList1 = principalBase.FindProperty("RefTypeIList")!; - var refTypeList1 = principalBase.FindProperty("RefTypeList")!; - var valueTypeArray1 = principalBase.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable1 = principalBase.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList1 = principalBase.FindProperty("ValueTypeIList")!; - var valueTypeList1 = principalBase.FindProperty("ValueTypeList")!; - var deriveds = runtimeEntityType.FindNavigation("Deriveds")!; + var alternateId = principalBase.FindProperty("AlternateId"); + var enum10 = principalBase.FindProperty("Enum1"); + var enum20 = principalBase.FindProperty("Enum2"); + var flagsEnum10 = principalBase.FindProperty("FlagsEnum1"); + var flagsEnum20 = principalBase.FindProperty("FlagsEnum2"); + var id0 = principalBase.FindProperty("Id"); + var refTypeArray1 = principalBase.FindProperty("RefTypeArray"); + var refTypeEnumerable1 = principalBase.FindProperty("RefTypeEnumerable"); + var refTypeIList1 = principalBase.FindProperty("RefTypeIList"); + var refTypeList1 = principalBase.FindProperty("RefTypeList"); + var valueTypeArray1 = principalBase.FindProperty("ValueTypeArray"); + var valueTypeEnumerable1 = principalBase.FindProperty("ValueTypeEnumerable"); + var valueTypeIList1 = principalBase.FindProperty("ValueTypeIList"); + var valueTypeList1 = principalBase.FindProperty("ValueTypeList"); + var deriveds = runtimeEntityType.FindNavigation("Deriveds"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/DbFunctions/DataEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/DbFunctions/DataEntityType.cs index 49f8ef0b958..3e275c80011 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/DbFunctions/DataEntityType.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/DbFunctions/DataEntityType.cs @@ -79,7 +79,7 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var blob = runtimeEntityType.FindProperty("Blob")!; + var blob = runtimeEntityType.FindProperty("Blob"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Dynamic_schema/DataEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Dynamic_schema/DataEntityType.cs index 5e6c430cf8b..5e83c15c5d8 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Dynamic_schema/DataEntityType.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Dynamic_schema/DataEntityType.cs @@ -118,8 +118,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var blob = runtimeEntityType.FindProperty("Blob")!; + var id = runtimeEntityType.FindProperty("Id"); + var blob = runtimeEntityType.FindProperty("Blob"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Key_HiLo_sequence/DataEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Key_HiLo_sequence/DataEntityType.cs index 4134a16f1e8..19be07dd2e1 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Key_HiLo_sequence/DataEntityType.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Key_HiLo_sequence/DataEntityType.cs @@ -120,8 +120,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var blob = runtimeEntityType.FindProperty("Blob")!; + var id = runtimeEntityType.FindProperty("Id"); + var blob = runtimeEntityType.FindProperty("Blob"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Key_sequence/DataEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Key_sequence/DataEntityType.cs index ff7c32df70a..946135c2b50 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Key_sequence/DataEntityType.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Key_sequence/DataEntityType.cs @@ -121,8 +121,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var blob = runtimeEntityType.FindProperty("Blob")!; + var id = runtimeEntityType.FindProperty("Id"); + var blob = runtimeEntityType.FindProperty("Blob"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextAssemblyAttributes.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextAssemblyAttributes.cs new file mode 100644 index 00000000000..c224873f6fa --- /dev/null +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextAssemblyAttributes.cs @@ -0,0 +1,9 @@ +// +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using TestNamespace; + +#pragma warning disable 219, 612, 618 +#nullable disable + +[assembly: DbContextModel(typeof(DbContext), typeof(DbContextModel))] diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextModel.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextModel.cs new file mode 100644 index 00000000000..583ee4d90cc --- /dev/null +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextModel.cs @@ -0,0 +1,48 @@ +// +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [DbContext(typeof(DbContext))] + public partial class DbContextModel : RuntimeModel + { + private static readonly bool _useOldBehavior31751 = + System.AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue31751", out var enabled31751) && enabled31751; + + static DbContextModel() + { + var model = new DbContextModel(); + + if (_useOldBehavior31751) + { + model.Initialize(); + } + else + { + var thread = new System.Threading.Thread(RunInitialization, 10 * 1024 * 1024); + thread.Start(); + thread.Join(); + + void RunInitialization() + { + model.Initialize(); + } + } + + model.Customize(); + _instance = (DbContextModel)model.FinalizeModel(); + } + + private static DbContextModel _instance; + public static IModel Instance => _instance; + + partial void Initialize(); + + partial void Customize(); + } +} diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextModelBuilder.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextModelBuilder.cs new file mode 100644 index 00000000000..e87c7bc1cdd --- /dev/null +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextModelBuilder.cs @@ -0,0 +1,54 @@ +// +using System; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + public partial class DbContextModel + { + private DbContextModel() + : base(skipDetectChanges: false, modelId: new Guid("00000000-0000-0000-0000-000000000000"), entityTypeCount: 8) + { + } + + partial void Initialize() + { + var dependentBase = DependentBaseEntityType.Create(this); + var manyTypes = ManyTypesEntityType.Create(this); + var principalBase = PrincipalBaseEntityType.Create(this); + var ownedType = OwnedTypeEntityType.Create(this); + var ownedType0 = OwnedType0EntityType.Create(this); + var principalBasePrincipalDerivedDependentBasebyte = PrincipalBasePrincipalDerivedDependentBasebyteEntityType.Create(this); + var dependentDerived = DependentDerivedEntityType.Create(this, dependentBase); + var principalDerived = PrincipalDerivedEntityType.Create(this, principalBase); + + DependentBaseEntityType.CreateForeignKey1(dependentBase, principalBase); + DependentBaseEntityType.CreateForeignKey2(dependentBase, principalDerived); + OwnedTypeEntityType.CreateForeignKey1(ownedType, principalBase); + OwnedTypeEntityType.CreateForeignKey2(ownedType, ownedType); + OwnedType0EntityType.CreateForeignKey1(ownedType0, principalDerived); + PrincipalBasePrincipalDerivedDependentBasebyteEntityType.CreateForeignKey1(principalBasePrincipalDerivedDependentBasebyte, principalDerived); + PrincipalBasePrincipalDerivedDependentBasebyteEntityType.CreateForeignKey2(principalBasePrincipalDerivedDependentBasebyte, principalBase); + PrincipalDerivedEntityType.CreateForeignKey1(principalDerived, principalBase); + + PrincipalBaseEntityType.CreateSkipNavigation1(principalBase, principalDerived, principalBasePrincipalDerivedDependentBasebyte); + PrincipalDerivedEntityType.CreateSkipNavigation1(principalDerived, principalBase, principalBasePrincipalDerivedDependentBasebyte); + + DependentBaseEntityType.CreateAnnotations(dependentBase); + ManyTypesEntityType.CreateAnnotations(manyTypes); + PrincipalBaseEntityType.CreateAnnotations(principalBase); + OwnedTypeEntityType.CreateAnnotations(ownedType); + OwnedType0EntityType.CreateAnnotations(ownedType0); + PrincipalBasePrincipalDerivedDependentBasebyteEntityType.CreateAnnotations(principalBasePrincipalDerivedDependentBasebyte); + DependentDerivedEntityType.CreateAnnotations(dependentDerived); + PrincipalDerivedEntityType.CreateAnnotations(principalDerived); + + AddAnnotation("Relational:MaxIdentifierLength", 128); + AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + } + } +} diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DependentBaseEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DependentBaseEntityType.cs new file mode 100644 index 00000000000..a856329d746 --- /dev/null +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DependentBaseEntityType.cs @@ -0,0 +1,130 @@ +// +using System; +using System.Reflection; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; +using Microsoft.EntityFrameworkCore.ValueGeneration; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class DependentBaseEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+DependentBase", + typeof(CompiledModelTestBase.DependentBase), + baseEntityType, + discriminatorProperty: "EnumDiscriminator", + discriminatorValue: CompiledModelTestBase.Enum1.One, + derivedTypesCount: 1, + propertyCount: 4, + navigationCount: 1, + foreignKeyCount: 2, + unnamedIndexCount: 1, + keyCount: 1); + + var principalId = runtimeEntityType.AddProperty( + "PrincipalId", + typeof(long), + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: 0L); + principalId.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var principalAlternateId = runtimeEntityType.AddProperty( + "PrincipalAlternateId", + typeof(Guid), + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: new Guid("00000000-0000-0000-0000-000000000000")); + principalAlternateId.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enumDiscriminator = runtimeEntityType.AddProperty( + "EnumDiscriminator", + typeof(CompiledModelTestBase.Enum1), + afterSaveBehavior: PropertySaveBehavior.Throw, + valueGeneratorFactory: new DiscriminatorValueGeneratorFactory().Create); + enumDiscriminator.SetSentinelFromProviderValue(0); + enumDiscriminator.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var id = runtimeEntityType.AddProperty( + "Id", + typeof(byte?), + propertyInfo: typeof(CompiledModelTestBase.DependentBase).GetProperty("Id", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.DependentBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + id.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var key = runtimeEntityType.AddKey( + new[] { principalId, principalAlternateId }); + runtimeEntityType.SetPrimaryKey(key); + + var index = runtimeEntityType.AddIndex( + new[] { principalId }, + unique: true); + + return runtimeEntityType; + } + + public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("PrincipalId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("Id") }), + principalEntityType, + deleteBehavior: DeleteBehavior.Cascade, + unique: true, + required: true); + + return runtimeForeignKey; + } + + public static RuntimeForeignKey CreateForeignKey2(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("PrincipalId"), declaringEntityType.FindProperty("PrincipalAlternateId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("Id"), principalEntityType.FindProperty("AlternateId") }), + principalEntityType, + deleteBehavior: DeleteBehavior.ClientNoAction, + unique: true, + required: true); + + var principal = declaringEntityType.AddNavigation("Principal", + runtimeForeignKey, + onDependent: true, + typeof(CompiledModelTestBase.PrincipalDerived>), + propertyInfo: typeof(CompiledModelTestBase.DependentBase).GetProperty("Principal", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.DependentBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var dependent = principalEntityType.AddNavigation("Dependent", + runtimeForeignKey, + onDependent: false, + typeof(CompiledModelTestBase.DependentBase), + propertyInfo: typeof(CompiledModelTestBase.PrincipalDerived>).GetProperty("Dependent", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalDerived>).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + eagerLoaded: true, + lazyLoadingEnabled: false); + + return runtimeForeignKey; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + runtimeEntityType.AddAnnotation("DiscriminatorMappingComplete", false); + runtimeEntityType.AddAnnotation("Relational:FunctionName", null); + runtimeEntityType.AddAnnotation("Relational:MappingStrategy", "TPH"); + runtimeEntityType.AddAnnotation("Relational:Schema", null); + runtimeEntityType.AddAnnotation("Relational:SqlQuery", null); + runtimeEntityType.AddAnnotation("Relational:TableName", "DependentBase"); + runtimeEntityType.AddAnnotation("Relational:ViewName", null); + runtimeEntityType.AddAnnotation("Relational:ViewSchema", null); + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DependentDerivedEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DependentDerivedEntityType.cs new file mode 100644 index 00000000000..f07c884257b --- /dev/null +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DependentDerivedEntityType.cs @@ -0,0 +1,62 @@ +// +using System; +using System.Reflection; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class DependentDerivedEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+DependentDerived", + typeof(CompiledModelTestBase.DependentDerived), + baseEntityType, + discriminatorProperty: "EnumDiscriminator", + discriminatorValue: CompiledModelTestBase.Enum1.Two, + propertyCount: 2); + + var data = runtimeEntityType.AddProperty( + "Data", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.DependentDerived).GetProperty("Data", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.DependentDerived).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true, + maxLength: 20, + unicode: false); + data.AddAnnotation("Relational:IsFixedLength", true); + data.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var money = runtimeEntityType.AddProperty( + "Money", + typeof(decimal), + precision: 9, + scale: 3, + sentinel: 0m); + money.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + return runtimeEntityType; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + runtimeEntityType.AddAnnotation("Relational:FunctionName", null); + runtimeEntityType.AddAnnotation("Relational:Schema", null); + runtimeEntityType.AddAnnotation("Relational:SqlQuery", null); + runtimeEntityType.AddAnnotation("Relational:TableName", "DependentBase"); + runtimeEntityType.AddAnnotation("Relational:ViewName", null); + runtimeEntityType.AddAnnotation("Relational:ViewSchema", null); + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/ManyTypesEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/ManyTypesEntityType.cs new file mode 100644 index 00000000000..037fc1fd1e4 --- /dev/null +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/ManyTypesEntityType.cs @@ -0,0 +1,1896 @@ +// +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.NetworkInformation; +using System.Reflection; +using System.Text; +using Microsoft.EntityFrameworkCore.ChangeTracking; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; +using Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal; +using Microsoft.EntityFrameworkCore.Storage; +using Microsoft.EntityFrameworkCore.Storage.Json; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class ManyTypesEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+ManyTypes", + typeof(CompiledModelTestBase.ManyTypes), + baseEntityType, + propertyCount: 236, + keyCount: 1); + + var id = runtimeEntityType.AddProperty( + "Id", + typeof(CompiledModelTestBase.ManyTypesId), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Id", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueGenerated: ValueGenerated.OnAdd, + afterSaveBehavior: PropertySaveBehavior.Throw, + valueConverter: new CompiledModelTestBase.ManyTypesIdConverter()); + id.SetSentinelFromProviderValue(0); + id.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + var @bool = runtimeEntityType.AddProperty( + "Bool", + typeof(bool), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Bool", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: false); + @bool.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var boolArray = runtimeEntityType.AddProperty( + "BoolArray", + typeof(bool[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BoolArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + boolArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var boolToStringConverterProperty = runtimeEntityType.AddProperty( + "BoolToStringConverterProperty", + typeof(bool), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BoolToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + boolToStringConverterProperty.TypeMapping = SqlServerStringTypeMapping.Default.Clone( + comparer: new ValueComparer( + bool (bool v1, bool v2) => v1 == v2, + int (bool v) => ((object)v).GetHashCode(), + bool (bool v) => v), + keyComparer: new ValueComparer( + bool (bool v1, bool v2) => v1 == v2, + int (bool v) => ((object)v).GetHashCode(), + bool (bool v) => v), + providerValueComparer: new ValueComparer( + bool (string v1, string v2) => v1 == v2, + int (string v) => ((object)v).GetHashCode(), + string (string v) => v), + mappingInfo: new RelationalTypeMappingInfo( + storeTypeName: "nvarchar(1)", + size: 1, + unicode: true, + dbType: System.Data.DbType.String), + converter: new ValueConverter( + string (bool v) => ((string)((v ? "B" : "A"))), + bool (string v) => !(string.IsNullOrEmpty(v)) && ((int)(v.ToUpperInvariant()[0])) == ((int)("B".ToUpperInvariant()[0]))), + jsonValueReaderWriter: new JsonConvertedValueReaderWriter( + JsonStringReaderWriter.Instance, + new ValueConverter( + string (bool v) => ((string)((v ? "B" : "A"))), + bool (string v) => !(string.IsNullOrEmpty(v)) && ((int)(v.ToUpperInvariant()[0])) == ((int)("B".ToUpperInvariant()[0]))))); + boolToStringConverterProperty.SetSentinelFromProviderValue("A"); + boolToStringConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var boolToTwoValuesConverterProperty = runtimeEntityType.AddProperty( + "BoolToTwoValuesConverterProperty", + typeof(bool), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BoolToTwoValuesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + boolToTwoValuesConverterProperty.SetValueConverter(new ValueConverter( + byte (bool v) => ((byte)((v ? 1 : 0))), + bool (byte v) => v == 1)); + boolToTwoValuesConverterProperty.SetSentinelFromProviderValue((byte)0); + boolToTwoValuesConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var boolToZeroOneConverterProperty = runtimeEntityType.AddProperty( + "BoolToZeroOneConverterProperty", + typeof(bool), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BoolToZeroOneConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new BoolToZeroOneConverter()); + boolToZeroOneConverterProperty.SetSentinelFromProviderValue((short)0); + boolToZeroOneConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var bytes = runtimeEntityType.AddProperty( + "Bytes", + typeof(byte[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Bytes", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + bytes.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var bytesArray = runtimeEntityType.AddProperty( + "BytesArray", + typeof(byte[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BytesArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + bytesArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var bytesToStringConverterProperty = runtimeEntityType.AddProperty( + "BytesToStringConverterProperty", + typeof(byte[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BytesToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new BytesToStringConverter(), + valueComparer: new ArrayStructuralComparer()); + bytesToStringConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var castingConverterProperty = runtimeEntityType.AddProperty( + "CastingConverterProperty", + typeof(int), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("CastingConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new CastingConverter()); + castingConverterProperty.SetSentinelFromProviderValue(0m); + castingConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var @char = runtimeEntityType.AddProperty( + "Char", + typeof(char), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Char", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + @char.SetSentinelFromProviderValue("\0"); + @char.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var charArray = runtimeEntityType.AddProperty( + "CharArray", + typeof(char[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("CharArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + charArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var charToStringConverterProperty = runtimeEntityType.AddProperty( + "CharToStringConverterProperty", + typeof(char), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("CharToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new CharToStringConverter()); + charToStringConverterProperty.SetSentinelFromProviderValue("\0"); + charToStringConverterProperty.AddAnnotation("Relational:IsFixedLength", true); + charToStringConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var dateOnly = runtimeEntityType.AddProperty( + "DateOnly", + typeof(DateOnly), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateOnly", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: new DateOnly(1, 1, 1)); + dateOnly.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var dateOnlyArray = runtimeEntityType.AddProperty( + "DateOnlyArray", + typeof(DateOnly[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateOnlyArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + dateOnlyArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var dateOnlyToStringConverterProperty = runtimeEntityType.AddProperty( + "DateOnlyToStringConverterProperty", + typeof(DateOnly), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateOnlyToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new DateOnlyToStringConverter()); + dateOnlyToStringConverterProperty.SetSentinelFromProviderValue("0001-01-01"); + dateOnlyToStringConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var dateTime = runtimeEntityType.AddProperty( + "DateTime", + typeof(DateTime), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTime", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + dateTime.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var dateTimeArray = runtimeEntityType.AddProperty( + "DateTimeArray", + typeof(DateTime[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + dateTimeArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var dateTimeOffsetToBinaryConverterProperty = runtimeEntityType.AddProperty( + "DateTimeOffsetToBinaryConverterProperty", + typeof(DateTimeOffset), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeOffsetToBinaryConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new DateTimeOffsetToBinaryConverter()); + dateTimeOffsetToBinaryConverterProperty.SetSentinelFromProviderValue(0L); + dateTimeOffsetToBinaryConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var dateTimeOffsetToBytesConverterProperty = runtimeEntityType.AddProperty( + "DateTimeOffsetToBytesConverterProperty", + typeof(DateTimeOffset), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeOffsetToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new DateTimeOffsetToBytesConverter()); + dateTimeOffsetToBytesConverterProperty.SetSentinelFromProviderValue(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }); + dateTimeOffsetToBytesConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var dateTimeOffsetToStringConverterProperty = runtimeEntityType.AddProperty( + "DateTimeOffsetToStringConverterProperty", + typeof(DateTimeOffset), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeOffsetToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new DateTimeOffsetToStringConverter()); + dateTimeOffsetToStringConverterProperty.SetSentinelFromProviderValue("0001-01-01 00:00:00+00:00"); + dateTimeOffsetToStringConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var dateTimeToBinaryConverterProperty = runtimeEntityType.AddProperty( + "DateTimeToBinaryConverterProperty", + typeof(DateTime), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeToBinaryConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new DateTimeToBinaryConverter()); + dateTimeToBinaryConverterProperty.SetSentinelFromProviderValue(0L); + dateTimeToBinaryConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var dateTimeToStringConverterProperty = runtimeEntityType.AddProperty( + "DateTimeToStringConverterProperty", + typeof(DateTime), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new DateTimeToStringConverter()); + dateTimeToStringConverterProperty.SetSentinelFromProviderValue("0001-01-01 00:00:00"); + dateTimeToStringConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var dateTimeToTicksConverterProperty = runtimeEntityType.AddProperty( + "DateTimeToTicksConverterProperty", + typeof(DateTime), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeToTicksConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + dateTimeToTicksConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var @decimal = runtimeEntityType.AddProperty( + "Decimal", + typeof(decimal), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Decimal", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0m); + @decimal.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var decimalArray = runtimeEntityType.AddProperty( + "DecimalArray", + typeof(decimal[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DecimalArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + decimalArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var decimalNumberToBytesConverterProperty = runtimeEntityType.AddProperty( + "DecimalNumberToBytesConverterProperty", + typeof(decimal), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DecimalNumberToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new NumberToBytesConverter()); + decimalNumberToBytesConverterProperty.SetSentinelFromProviderValue(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }); + decimalNumberToBytesConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var decimalNumberToStringConverterProperty = runtimeEntityType.AddProperty( + "DecimalNumberToStringConverterProperty", + typeof(decimal), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DecimalNumberToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new NumberToStringConverter()); + decimalNumberToStringConverterProperty.SetSentinelFromProviderValue("0"); + decimalNumberToStringConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var @double = runtimeEntityType.AddProperty( + "Double", + typeof(double), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Double", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0.0); + @double.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var doubleArray = runtimeEntityType.AddProperty( + "DoubleArray", + typeof(double[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DoubleArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + doubleArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var doubleNumberToBytesConverterProperty = runtimeEntityType.AddProperty( + "DoubleNumberToBytesConverterProperty", + typeof(double), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DoubleNumberToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new NumberToBytesConverter()); + doubleNumberToBytesConverterProperty.SetSentinelFromProviderValue(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }); + doubleNumberToBytesConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var doubleNumberToStringConverterProperty = runtimeEntityType.AddProperty( + "DoubleNumberToStringConverterProperty", + typeof(double), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DoubleNumberToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new NumberToStringConverter()); + doubleNumberToStringConverterProperty.SetSentinelFromProviderValue("0"); + doubleNumberToStringConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enum16 = runtimeEntityType.AddProperty( + "Enum16", + typeof(CompiledModelTestBase.Enum16), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enum16.SetSentinelFromProviderValue((short)0); + enum16.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enum16Array = runtimeEntityType.AddProperty( + "Enum16Array", + typeof(CompiledModelTestBase.Enum16[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enum16Array.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enum16AsString = runtimeEntityType.AddProperty( + "Enum16AsString", + typeof(CompiledModelTestBase.Enum16), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum16AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enum16AsString.SetSentinelFromProviderValue("Default"); + enum16AsString.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enum16AsStringArray = runtimeEntityType.AddProperty( + "Enum16AsStringArray", + typeof(CompiledModelTestBase.Enum16[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum16AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enum16AsStringArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enum16AsStringCollection = runtimeEntityType.AddProperty( + "Enum16AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum16AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enum16AsStringCollection.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enum16Collection = runtimeEntityType.AddProperty( + "Enum16Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum16Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enum16Collection.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enum32 = runtimeEntityType.AddProperty( + "Enum32", + typeof(CompiledModelTestBase.Enum32), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enum32.SetSentinelFromProviderValue(0); + enum32.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enum32Array = runtimeEntityType.AddProperty( + "Enum32Array", + typeof(CompiledModelTestBase.Enum32[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enum32Array.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enum32AsString = runtimeEntityType.AddProperty( + "Enum32AsString", + typeof(CompiledModelTestBase.Enum32), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum32AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enum32AsString.SetSentinelFromProviderValue("Default"); + enum32AsString.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enum32AsStringArray = runtimeEntityType.AddProperty( + "Enum32AsStringArray", + typeof(CompiledModelTestBase.Enum32[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum32AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enum32AsStringArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enum32AsStringCollection = runtimeEntityType.AddProperty( + "Enum32AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum32AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enum32AsStringCollection.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enum32Collection = runtimeEntityType.AddProperty( + "Enum32Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum32Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enum32Collection.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enum64 = runtimeEntityType.AddProperty( + "Enum64", + typeof(CompiledModelTestBase.Enum64), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enum64.SetSentinelFromProviderValue(0L); + enum64.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enum64Array = runtimeEntityType.AddProperty( + "Enum64Array", + typeof(CompiledModelTestBase.Enum64[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enum64Array.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enum64AsString = runtimeEntityType.AddProperty( + "Enum64AsString", + typeof(CompiledModelTestBase.Enum64), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum64AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enum64AsString.SetSentinelFromProviderValue("Default"); + enum64AsString.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enum64AsStringArray = runtimeEntityType.AddProperty( + "Enum64AsStringArray", + typeof(CompiledModelTestBase.Enum64[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum64AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enum64AsStringArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enum64AsStringCollection = runtimeEntityType.AddProperty( + "Enum64AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum64AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enum64AsStringCollection.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enum64Collection = runtimeEntityType.AddProperty( + "Enum64Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum64Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enum64Collection.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enum8 = runtimeEntityType.AddProperty( + "Enum8", + typeof(CompiledModelTestBase.Enum8), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enum8.SetSentinelFromProviderValue((short)0); + enum8.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enum8Array = runtimeEntityType.AddProperty( + "Enum8Array", + typeof(CompiledModelTestBase.Enum8[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enum8Array.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enum8AsString = runtimeEntityType.AddProperty( + "Enum8AsString", + typeof(CompiledModelTestBase.Enum8), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum8AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enum8AsString.SetSentinelFromProviderValue("Default"); + enum8AsString.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enum8AsStringArray = runtimeEntityType.AddProperty( + "Enum8AsStringArray", + typeof(CompiledModelTestBase.Enum8[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum8AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enum8AsStringArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enum8AsStringCollection = runtimeEntityType.AddProperty( + "Enum8AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum8AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enum8AsStringCollection.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enum8Collection = runtimeEntityType.AddProperty( + "Enum8Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum8Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enum8Collection.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enumToNumberConverterProperty = runtimeEntityType.AddProperty( + "EnumToNumberConverterProperty", + typeof(CompiledModelTestBase.Enum32), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumToNumberConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new EnumToNumberConverter()); + enumToNumberConverterProperty.SetSentinelFromProviderValue(0); + enumToNumberConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enumToStringConverterProperty = runtimeEntityType.AddProperty( + "EnumToStringConverterProperty", + typeof(CompiledModelTestBase.Enum32), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new EnumToStringConverter()); + enumToStringConverterProperty.SetSentinelFromProviderValue("Default"); + enumToStringConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enumU16 = runtimeEntityType.AddProperty( + "EnumU16", + typeof(CompiledModelTestBase.EnumU16), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enumU16.SetSentinelFromProviderValue(0); + enumU16.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enumU16Array = runtimeEntityType.AddProperty( + "EnumU16Array", + typeof(CompiledModelTestBase.EnumU16[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enumU16Array.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enumU16AsString = runtimeEntityType.AddProperty( + "EnumU16AsString", + typeof(CompiledModelTestBase.EnumU16), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU16AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enumU16AsString.SetSentinelFromProviderValue("Min"); + enumU16AsString.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enumU16AsStringArray = runtimeEntityType.AddProperty( + "EnumU16AsStringArray", + typeof(CompiledModelTestBase.EnumU16[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU16AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enumU16AsStringArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enumU16AsStringCollection = runtimeEntityType.AddProperty( + "EnumU16AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU16AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enumU16AsStringCollection.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enumU16Collection = runtimeEntityType.AddProperty( + "EnumU16Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU16Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enumU16Collection.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enumU32 = runtimeEntityType.AddProperty( + "EnumU32", + typeof(CompiledModelTestBase.EnumU32), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enumU32.SetSentinelFromProviderValue(0L); + enumU32.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enumU32Array = runtimeEntityType.AddProperty( + "EnumU32Array", + typeof(CompiledModelTestBase.EnumU32[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enumU32Array.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enumU32AsString = runtimeEntityType.AddProperty( + "EnumU32AsString", + typeof(CompiledModelTestBase.EnumU32), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU32AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enumU32AsString.SetSentinelFromProviderValue("Min"); + enumU32AsString.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enumU32AsStringArray = runtimeEntityType.AddProperty( + "EnumU32AsStringArray", + typeof(CompiledModelTestBase.EnumU32[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU32AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enumU32AsStringArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enumU32AsStringCollection = runtimeEntityType.AddProperty( + "EnumU32AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU32AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enumU32AsStringCollection.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enumU32Collection = runtimeEntityType.AddProperty( + "EnumU32Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU32Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enumU32Collection.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enumU64 = runtimeEntityType.AddProperty( + "EnumU64", + typeof(CompiledModelTestBase.EnumU64), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enumU64.SetSentinelFromProviderValue(0m); + enumU64.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enumU64Array = runtimeEntityType.AddProperty( + "EnumU64Array", + typeof(CompiledModelTestBase.EnumU64[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enumU64Array.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enumU64AsString = runtimeEntityType.AddProperty( + "EnumU64AsString", + typeof(CompiledModelTestBase.EnumU64), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU64AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enumU64AsString.SetSentinelFromProviderValue("Min"); + enumU64AsString.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enumU64AsStringArray = runtimeEntityType.AddProperty( + "EnumU64AsStringArray", + typeof(CompiledModelTestBase.EnumU64[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU64AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enumU64AsStringArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enumU64AsStringCollection = runtimeEntityType.AddProperty( + "EnumU64AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU64AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enumU64AsStringCollection.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enumU64Collection = runtimeEntityType.AddProperty( + "EnumU64Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU64Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enumU64Collection.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enumU8 = runtimeEntityType.AddProperty( + "EnumU8", + typeof(CompiledModelTestBase.EnumU8), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enumU8.SetSentinelFromProviderValue((byte)0); + enumU8.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enumU8Array = runtimeEntityType.AddProperty( + "EnumU8Array", + typeof(CompiledModelTestBase.EnumU8[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enumU8Array.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enumU8AsString = runtimeEntityType.AddProperty( + "EnumU8AsString", + typeof(CompiledModelTestBase.EnumU8), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU8AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enumU8AsString.SetSentinelFromProviderValue("Min"); + enumU8AsString.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enumU8AsStringArray = runtimeEntityType.AddProperty( + "EnumU8AsStringArray", + typeof(CompiledModelTestBase.EnumU8[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU8AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enumU8AsStringArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enumU8AsStringCollection = runtimeEntityType.AddProperty( + "EnumU8AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU8AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enumU8AsStringCollection.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enumU8Collection = runtimeEntityType.AddProperty( + "EnumU8Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU8Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enumU8Collection.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var @float = runtimeEntityType.AddProperty( + "Float", + typeof(float), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Float", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0f); + @float.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var floatArray = runtimeEntityType.AddProperty( + "FloatArray", + typeof(float[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("FloatArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + floatArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var guid = runtimeEntityType.AddProperty( + "Guid", + typeof(Guid), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Guid", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: new Guid("00000000-0000-0000-0000-000000000000")); + guid.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var guidArray = runtimeEntityType.AddProperty( + "GuidArray", + typeof(Guid[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("GuidArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + guidArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var guidToBytesConverterProperty = runtimeEntityType.AddProperty( + "GuidToBytesConverterProperty", + typeof(Guid), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("GuidToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new GuidToBytesConverter()); + guidToBytesConverterProperty.SetSentinelFromProviderValue(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }); + guidToBytesConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var guidToStringConverterProperty = runtimeEntityType.AddProperty( + "GuidToStringConverterProperty", + typeof(Guid), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("GuidToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new GuidToStringConverter()); + guidToStringConverterProperty.SetSentinelFromProviderValue("00000000-0000-0000-0000-000000000000"); + guidToStringConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var iPAddress = runtimeEntityType.AddProperty( + "IPAddress", + typeof(IPAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("IPAddress", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + iPAddress.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var iPAddressArray = runtimeEntityType.AddProperty( + "IPAddressArray", + typeof(IPAddress[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("IPAddressArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + iPAddressArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var iPAddressToBytesConverterProperty = runtimeEntityType.AddProperty( + "IPAddressToBytesConverterProperty", + typeof(IPAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("IPAddressToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new IPAddressToBytesConverter()); + iPAddressToBytesConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var iPAddressToStringConverterProperty = runtimeEntityType.AddProperty( + "IPAddressToStringConverterProperty", + typeof(IPAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("IPAddressToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new IPAddressToStringConverter()); + iPAddressToStringConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var int16 = runtimeEntityType.AddProperty( + "Int16", + typeof(short), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: (short)0); + int16.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var int16Array = runtimeEntityType.AddProperty( + "Int16Array", + typeof(short[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + int16Array.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var int32 = runtimeEntityType.AddProperty( + "Int32", + typeof(int), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0); + int32.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var int32Array = runtimeEntityType.AddProperty( + "Int32Array", + typeof(int[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + int32Array.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var int64 = runtimeEntityType.AddProperty( + "Int64", + typeof(long), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0L); + int64.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var int64Array = runtimeEntityType.AddProperty( + "Int64Array", + typeof(long[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + int64Array.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var int8 = runtimeEntityType.AddProperty( + "Int8", + typeof(sbyte), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + int8.SetSentinelFromProviderValue((short)0); + int8.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var int8Array = runtimeEntityType.AddProperty( + "Int8Array", + typeof(sbyte[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + int8Array.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var intNumberToBytesConverterProperty = runtimeEntityType.AddProperty( + "IntNumberToBytesConverterProperty", + typeof(int), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("IntNumberToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new NumberToBytesConverter()); + intNumberToBytesConverterProperty.SetSentinelFromProviderValue(new byte[] { 0, 0, 0, 0 }); + intNumberToBytesConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var intNumberToStringConverterProperty = runtimeEntityType.AddProperty( + "IntNumberToStringConverterProperty", + typeof(int), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("IntNumberToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new NumberToStringConverter()); + intNumberToStringConverterProperty.SetSentinelFromProviderValue("0"); + intNumberToStringConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullIntToNullStringConverterProperty = runtimeEntityType.AddProperty( + "NullIntToNullStringConverterProperty", + typeof(int?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullIntToNullStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true, + valueConverter: new CompiledModelTestBase.NullIntToNullStringConverter()); + nullIntToNullStringConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableBool = runtimeEntityType.AddProperty( + "NullableBool", + typeof(bool?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableBool", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableBool.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableBoolArray = runtimeEntityType.AddProperty( + "NullableBoolArray", + typeof(bool?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableBoolArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableBoolArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableBytes = runtimeEntityType.AddProperty( + "NullableBytes", + typeof(byte[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableBytes", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableBytes.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableBytesArray = runtimeEntityType.AddProperty( + "NullableBytesArray", + typeof(byte[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableBytesArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableBytesArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableChar = runtimeEntityType.AddProperty( + "NullableChar", + typeof(char?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableChar", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableChar.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableCharArray = runtimeEntityType.AddProperty( + "NullableCharArray", + typeof(char?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableCharArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableCharArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableDateOnly = runtimeEntityType.AddProperty( + "NullableDateOnly", + typeof(DateOnly?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDateOnly", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableDateOnly.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableDateOnlyArray = runtimeEntityType.AddProperty( + "NullableDateOnlyArray", + typeof(DateOnly?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDateOnlyArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableDateOnlyArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableDateTime = runtimeEntityType.AddProperty( + "NullableDateTime", + typeof(DateTime?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDateTime", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableDateTime.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableDateTimeArray = runtimeEntityType.AddProperty( + "NullableDateTimeArray", + typeof(DateTime?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDateTimeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableDateTimeArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableDecimal = runtimeEntityType.AddProperty( + "NullableDecimal", + typeof(decimal?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDecimal", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableDecimal.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableDecimalArray = runtimeEntityType.AddProperty( + "NullableDecimalArray", + typeof(decimal?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDecimalArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableDecimalArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableDouble = runtimeEntityType.AddProperty( + "NullableDouble", + typeof(double?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDouble", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableDouble.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableDoubleArray = runtimeEntityType.AddProperty( + "NullableDoubleArray", + typeof(double?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDoubleArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableDoubleArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnum16 = runtimeEntityType.AddProperty( + "NullableEnum16", + typeof(CompiledModelTestBase.Enum16?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableEnum16.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnum16Array = runtimeEntityType.AddProperty( + "NullableEnum16Array", + typeof(CompiledModelTestBase.Enum16?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableEnum16Array.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnum16AsString = runtimeEntityType.AddProperty( + "NullableEnum16AsString", + typeof(CompiledModelTestBase.Enum16?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum16AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableEnum16AsString.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnum16AsStringArray = runtimeEntityType.AddProperty( + "NullableEnum16AsStringArray", + typeof(CompiledModelTestBase.Enum16?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum16AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableEnum16AsStringArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnum16AsStringCollection = runtimeEntityType.AddProperty( + "NullableEnum16AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum16AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableEnum16AsStringCollection.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnum16Collection = runtimeEntityType.AddProperty( + "NullableEnum16Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum16Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableEnum16Collection.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnum32 = runtimeEntityType.AddProperty( + "NullableEnum32", + typeof(CompiledModelTestBase.Enum32?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableEnum32.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnum32Array = runtimeEntityType.AddProperty( + "NullableEnum32Array", + typeof(CompiledModelTestBase.Enum32?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableEnum32Array.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnum32AsString = runtimeEntityType.AddProperty( + "NullableEnum32AsString", + typeof(CompiledModelTestBase.Enum32?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum32AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableEnum32AsString.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnum32AsStringArray = runtimeEntityType.AddProperty( + "NullableEnum32AsStringArray", + typeof(CompiledModelTestBase.Enum32?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum32AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableEnum32AsStringArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnum32AsStringCollection = runtimeEntityType.AddProperty( + "NullableEnum32AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum32AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableEnum32AsStringCollection.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnum32Collection = runtimeEntityType.AddProperty( + "NullableEnum32Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum32Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableEnum32Collection.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnum64 = runtimeEntityType.AddProperty( + "NullableEnum64", + typeof(CompiledModelTestBase.Enum64?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableEnum64.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnum64Array = runtimeEntityType.AddProperty( + "NullableEnum64Array", + typeof(CompiledModelTestBase.Enum64?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableEnum64Array.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnum64AsString = runtimeEntityType.AddProperty( + "NullableEnum64AsString", + typeof(CompiledModelTestBase.Enum64?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum64AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableEnum64AsString.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnum64AsStringArray = runtimeEntityType.AddProperty( + "NullableEnum64AsStringArray", + typeof(CompiledModelTestBase.Enum64?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum64AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableEnum64AsStringArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnum64AsStringCollection = runtimeEntityType.AddProperty( + "NullableEnum64AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum64AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableEnum64AsStringCollection.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnum64Collection = runtimeEntityType.AddProperty( + "NullableEnum64Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum64Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableEnum64Collection.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnum8 = runtimeEntityType.AddProperty( + "NullableEnum8", + typeof(CompiledModelTestBase.Enum8?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableEnum8.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnum8Array = runtimeEntityType.AddProperty( + "NullableEnum8Array", + typeof(CompiledModelTestBase.Enum8?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableEnum8Array.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnum8AsString = runtimeEntityType.AddProperty( + "NullableEnum8AsString", + typeof(CompiledModelTestBase.Enum8?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum8AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableEnum8AsString.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnum8AsStringArray = runtimeEntityType.AddProperty( + "NullableEnum8AsStringArray", + typeof(CompiledModelTestBase.Enum8?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum8AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableEnum8AsStringArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnum8AsStringCollection = runtimeEntityType.AddProperty( + "NullableEnum8AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum8AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableEnum8AsStringCollection.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnum8Collection = runtimeEntityType.AddProperty( + "NullableEnum8Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum8Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableEnum8Collection.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnumU16 = runtimeEntityType.AddProperty( + "NullableEnumU16", + typeof(CompiledModelTestBase.EnumU16?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableEnumU16.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnumU16Array = runtimeEntityType.AddProperty( + "NullableEnumU16Array", + typeof(CompiledModelTestBase.EnumU16?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableEnumU16Array.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnumU16AsString = runtimeEntityType.AddProperty( + "NullableEnumU16AsString", + typeof(CompiledModelTestBase.EnumU16?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU16AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableEnumU16AsString.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnumU16AsStringArray = runtimeEntityType.AddProperty( + "NullableEnumU16AsStringArray", + typeof(CompiledModelTestBase.EnumU16?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU16AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableEnumU16AsStringArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnumU16AsStringCollection = runtimeEntityType.AddProperty( + "NullableEnumU16AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU16AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableEnumU16AsStringCollection.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnumU16Collection = runtimeEntityType.AddProperty( + "NullableEnumU16Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU16Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableEnumU16Collection.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnumU32 = runtimeEntityType.AddProperty( + "NullableEnumU32", + typeof(CompiledModelTestBase.EnumU32?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableEnumU32.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnumU32Array = runtimeEntityType.AddProperty( + "NullableEnumU32Array", + typeof(CompiledModelTestBase.EnumU32?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableEnumU32Array.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnumU32AsString = runtimeEntityType.AddProperty( + "NullableEnumU32AsString", + typeof(CompiledModelTestBase.EnumU32?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU32AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableEnumU32AsString.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnumU32AsStringArray = runtimeEntityType.AddProperty( + "NullableEnumU32AsStringArray", + typeof(CompiledModelTestBase.EnumU32?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU32AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableEnumU32AsStringArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnumU32AsStringCollection = runtimeEntityType.AddProperty( + "NullableEnumU32AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU32AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableEnumU32AsStringCollection.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnumU32Collection = runtimeEntityType.AddProperty( + "NullableEnumU32Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU32Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableEnumU32Collection.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnumU64 = runtimeEntityType.AddProperty( + "NullableEnumU64", + typeof(CompiledModelTestBase.EnumU64?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableEnumU64.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnumU64Array = runtimeEntityType.AddProperty( + "NullableEnumU64Array", + typeof(CompiledModelTestBase.EnumU64?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableEnumU64Array.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnumU64AsString = runtimeEntityType.AddProperty( + "NullableEnumU64AsString", + typeof(CompiledModelTestBase.EnumU64?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU64AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableEnumU64AsString.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnumU64AsStringArray = runtimeEntityType.AddProperty( + "NullableEnumU64AsStringArray", + typeof(CompiledModelTestBase.EnumU64?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU64AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableEnumU64AsStringArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnumU64AsStringCollection = runtimeEntityType.AddProperty( + "NullableEnumU64AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU64AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableEnumU64AsStringCollection.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnumU64Collection = runtimeEntityType.AddProperty( + "NullableEnumU64Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU64Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableEnumU64Collection.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnumU8 = runtimeEntityType.AddProperty( + "NullableEnumU8", + typeof(CompiledModelTestBase.EnumU8?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableEnumU8.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnumU8Array = runtimeEntityType.AddProperty( + "NullableEnumU8Array", + typeof(CompiledModelTestBase.EnumU8?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableEnumU8Array.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnumU8AsString = runtimeEntityType.AddProperty( + "NullableEnumU8AsString", + typeof(CompiledModelTestBase.EnumU8?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU8AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableEnumU8AsString.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnumU8AsStringArray = runtimeEntityType.AddProperty( + "NullableEnumU8AsStringArray", + typeof(CompiledModelTestBase.EnumU8?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU8AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableEnumU8AsStringArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnumU8AsStringCollection = runtimeEntityType.AddProperty( + "NullableEnumU8AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU8AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableEnumU8AsStringCollection.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableEnumU8Collection = runtimeEntityType.AddProperty( + "NullableEnumU8Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU8Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableEnumU8Collection.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableFloat = runtimeEntityType.AddProperty( + "NullableFloat", + typeof(float?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableFloat", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableFloat.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableFloatArray = runtimeEntityType.AddProperty( + "NullableFloatArray", + typeof(float?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableFloatArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableFloatArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableGuid = runtimeEntityType.AddProperty( + "NullableGuid", + typeof(Guid?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableGuid", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableGuid.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableGuidArray = runtimeEntityType.AddProperty( + "NullableGuidArray", + typeof(Guid?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableGuidArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableGuidArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableIPAddress = runtimeEntityType.AddProperty( + "NullableIPAddress", + typeof(IPAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableIPAddress", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableIPAddress.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableIPAddressArray = runtimeEntityType.AddProperty( + "NullableIPAddressArray", + typeof(IPAddress[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableIPAddressArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableIPAddressArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableInt16 = runtimeEntityType.AddProperty( + "NullableInt16", + typeof(short?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableInt16.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableInt16Array = runtimeEntityType.AddProperty( + "NullableInt16Array", + typeof(short?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableInt16Array.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableInt32 = runtimeEntityType.AddProperty( + "NullableInt32", + typeof(int?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableInt32.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableInt32Array = runtimeEntityType.AddProperty( + "NullableInt32Array", + typeof(int?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableInt32Array.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableInt64 = runtimeEntityType.AddProperty( + "NullableInt64", + typeof(long?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableInt64.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableInt64Array = runtimeEntityType.AddProperty( + "NullableInt64Array", + typeof(long?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableInt64Array.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableInt8 = runtimeEntityType.AddProperty( + "NullableInt8", + typeof(sbyte?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableInt8.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableInt8Array = runtimeEntityType.AddProperty( + "NullableInt8Array", + typeof(sbyte?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableInt8Array.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullablePhysicalAddress = runtimeEntityType.AddProperty( + "NullablePhysicalAddress", + typeof(PhysicalAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullablePhysicalAddress", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullablePhysicalAddress.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullablePhysicalAddressArray = runtimeEntityType.AddProperty( + "NullablePhysicalAddressArray", + typeof(PhysicalAddress[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullablePhysicalAddressArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullablePhysicalAddressArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableString = runtimeEntityType.AddProperty( + "NullableString", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableString.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableStringArray = runtimeEntityType.AddProperty( + "NullableStringArray", + typeof(string[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableStringArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableTimeOnly = runtimeEntityType.AddProperty( + "NullableTimeOnly", + typeof(TimeOnly?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableTimeOnly", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableTimeOnly.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableTimeOnlyArray = runtimeEntityType.AddProperty( + "NullableTimeOnlyArray", + typeof(TimeOnly?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableTimeOnlyArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableTimeOnlyArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableTimeSpan = runtimeEntityType.AddProperty( + "NullableTimeSpan", + typeof(TimeSpan?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableTimeSpan", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableTimeSpan.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableTimeSpanArray = runtimeEntityType.AddProperty( + "NullableTimeSpanArray", + typeof(TimeSpan?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableTimeSpanArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableTimeSpanArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableUInt16 = runtimeEntityType.AddProperty( + "NullableUInt16", + typeof(ushort?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableUInt16.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableUInt16Array = runtimeEntityType.AddProperty( + "NullableUInt16Array", + typeof(ushort?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableUInt16Array.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableUInt32 = runtimeEntityType.AddProperty( + "NullableUInt32", + typeof(uint?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableUInt32.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableUInt32Array = runtimeEntityType.AddProperty( + "NullableUInt32Array", + typeof(uint?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableUInt32Array.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableUInt64 = runtimeEntityType.AddProperty( + "NullableUInt64", + typeof(ulong?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableUInt64.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableUInt64Array = runtimeEntityType.AddProperty( + "NullableUInt64Array", + typeof(ulong?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableUInt64Array.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableUInt8 = runtimeEntityType.AddProperty( + "NullableUInt8", + typeof(byte?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableUInt8.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableUInt8Array = runtimeEntityType.AddProperty( + "NullableUInt8Array", + typeof(byte?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableUInt8Array.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableUri = runtimeEntityType.AddProperty( + "NullableUri", + typeof(Uri), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUri", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + nullableUri.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var nullableUriArray = runtimeEntityType.AddProperty( + "NullableUriArray", + typeof(Uri[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUriArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + nullableUriArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var physicalAddress = runtimeEntityType.AddProperty( + "PhysicalAddress", + typeof(PhysicalAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("PhysicalAddress", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + physicalAddress.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var physicalAddressArray = runtimeEntityType.AddProperty( + "PhysicalAddressArray", + typeof(PhysicalAddress[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("PhysicalAddressArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + physicalAddressArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var physicalAddressToBytesConverterProperty = runtimeEntityType.AddProperty( + "PhysicalAddressToBytesConverterProperty", + typeof(PhysicalAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("PhysicalAddressToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new PhysicalAddressToBytesConverter()); + physicalAddressToBytesConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var physicalAddressToStringConverterProperty = runtimeEntityType.AddProperty( + "PhysicalAddressToStringConverterProperty", + typeof(PhysicalAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("PhysicalAddressToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new PhysicalAddressToStringConverter()); + physicalAddressToStringConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var @string = runtimeEntityType.AddProperty( + "String", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("String", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + @string.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var stringArray = runtimeEntityType.AddProperty( + "StringArray", + typeof(string[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + stringArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var stringToBoolConverterProperty = runtimeEntityType.AddProperty( + "StringToBoolConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToBoolConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToBoolConverter()); + stringToBoolConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var stringToBytesConverterProperty = runtimeEntityType.AddProperty( + "StringToBytesConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + stringToBytesConverterProperty.SetValueConverter(new ValueConverter( + byte[] (string v) => Encoding.GetEncoding(12000).GetBytes(v), + string (byte[] v) => Encoding.GetEncoding(12000).GetString(v))); + stringToBytesConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var stringToCharConverterProperty = runtimeEntityType.AddProperty( + "StringToCharConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToCharConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToCharConverter()); + stringToCharConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var stringToDateOnlyConverterProperty = runtimeEntityType.AddProperty( + "StringToDateOnlyConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToDateOnlyConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToDateOnlyConverter()); + stringToDateOnlyConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var stringToDateTimeConverterProperty = runtimeEntityType.AddProperty( + "StringToDateTimeConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToDateTimeConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToDateTimeConverter()); + stringToDateTimeConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var stringToDateTimeOffsetConverterProperty = runtimeEntityType.AddProperty( + "StringToDateTimeOffsetConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToDateTimeOffsetConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToDateTimeOffsetConverter()); + stringToDateTimeOffsetConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var stringToDecimalNumberConverterProperty = runtimeEntityType.AddProperty( + "StringToDecimalNumberConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToDecimalNumberConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToNumberConverter()); + stringToDecimalNumberConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var stringToDoubleNumberConverterProperty = runtimeEntityType.AddProperty( + "StringToDoubleNumberConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToDoubleNumberConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToNumberConverter()); + stringToDoubleNumberConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var stringToEnumConverterProperty = runtimeEntityType.AddProperty( + "StringToEnumConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToEnumConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToEnumConverter()); + stringToEnumConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var stringToGuidConverterProperty = runtimeEntityType.AddProperty( + "StringToGuidConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToGuidConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + stringToGuidConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var stringToIntNumberConverterProperty = runtimeEntityType.AddProperty( + "StringToIntNumberConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToIntNumberConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToNumberConverter()); + stringToIntNumberConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var stringToTimeOnlyConverterProperty = runtimeEntityType.AddProperty( + "StringToTimeOnlyConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToTimeOnlyConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToTimeOnlyConverter()); + stringToTimeOnlyConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var stringToTimeSpanConverterProperty = runtimeEntityType.AddProperty( + "StringToTimeSpanConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToTimeSpanConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToTimeSpanConverter()); + stringToTimeSpanConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var stringToUriConverterProperty = runtimeEntityType.AddProperty( + "StringToUriConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToUriConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToUriConverter()); + stringToUriConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var timeOnly = runtimeEntityType.AddProperty( + "TimeOnly", + typeof(TimeOnly), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeOnly", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: new TimeOnly(0, 0, 0)); + timeOnly.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var timeOnlyArray = runtimeEntityType.AddProperty( + "TimeOnlyArray", + typeof(TimeOnly[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeOnlyArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + timeOnlyArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var timeOnlyToStringConverterProperty = runtimeEntityType.AddProperty( + "TimeOnlyToStringConverterProperty", + typeof(TimeOnly), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeOnlyToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new TimeOnlyToStringConverter()); + timeOnlyToStringConverterProperty.SetSentinelFromProviderValue("00:00:00"); + timeOnlyToStringConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var timeOnlyToTicksConverterProperty = runtimeEntityType.AddProperty( + "TimeOnlyToTicksConverterProperty", + typeof(TimeOnly), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeOnlyToTicksConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new TimeOnlyToTicksConverter()); + timeOnlyToTicksConverterProperty.SetSentinelFromProviderValue(0L); + timeOnlyToTicksConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var timeSpan = runtimeEntityType.AddProperty( + "TimeSpan", + typeof(TimeSpan), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeSpan", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: new TimeSpan(0, 0, 0, 0, 0)); + timeSpan.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var timeSpanArray = runtimeEntityType.AddProperty( + "TimeSpanArray", + typeof(TimeSpan[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeSpanArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + timeSpanArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var timeSpanToStringConverterProperty = runtimeEntityType.AddProperty( + "TimeSpanToStringConverterProperty", + typeof(TimeSpan), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeSpanToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new TimeSpanToStringConverter()); + timeSpanToStringConverterProperty.SetSentinelFromProviderValue("00:00:00"); + timeSpanToStringConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var timeSpanToTicksConverterProperty = runtimeEntityType.AddProperty( + "TimeSpanToTicksConverterProperty", + typeof(TimeSpan), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeSpanToTicksConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new TimeSpanToTicksConverter()); + timeSpanToTicksConverterProperty.SetSentinelFromProviderValue(0L); + timeSpanToTicksConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var uInt16 = runtimeEntityType.AddProperty( + "UInt16", + typeof(ushort), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + uInt16.SetSentinelFromProviderValue(0); + uInt16.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var uInt16Array = runtimeEntityType.AddProperty( + "UInt16Array", + typeof(ushort[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + uInt16Array.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var uInt32 = runtimeEntityType.AddProperty( + "UInt32", + typeof(uint), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + uInt32.SetSentinelFromProviderValue(0L); + uInt32.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var uInt32Array = runtimeEntityType.AddProperty( + "UInt32Array", + typeof(uint[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + uInt32Array.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var uInt64 = runtimeEntityType.AddProperty( + "UInt64", + typeof(ulong), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + uInt64.SetSentinelFromProviderValue(0m); + uInt64.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var uInt64Array = runtimeEntityType.AddProperty( + "UInt64Array", + typeof(ulong[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + uInt64Array.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var uInt8 = runtimeEntityType.AddProperty( + "UInt8", + typeof(byte), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: (byte)0); + uInt8.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var uInt8Array = runtimeEntityType.AddProperty( + "UInt8Array", + typeof(byte[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + uInt8Array.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var uri = runtimeEntityType.AddProperty( + "Uri", + typeof(Uri), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Uri", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + uri.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var uriArray = runtimeEntityType.AddProperty( + "UriArray", + typeof(Uri[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UriArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + uriArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var uriToStringConverterProperty = runtimeEntityType.AddProperty( + "UriToStringConverterProperty", + typeof(Uri), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UriToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new UriToStringConverter()); + uriToStringConverterProperty.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var key = runtimeEntityType.AddKey( + new[] { id }); + runtimeEntityType.SetPrimaryKey(key); + + return runtimeEntityType; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + runtimeEntityType.AddAnnotation("Relational:FunctionName", null); + runtimeEntityType.AddAnnotation("Relational:Schema", null); + runtimeEntityType.AddAnnotation("Relational:SqlQuery", null); + runtimeEntityType.AddAnnotation("Relational:TableName", "ManyTypes"); + runtimeEntityType.AddAnnotation("Relational:ViewName", null); + runtimeEntityType.AddAnnotation("Relational:ViewSchema", null); + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/OwnedType0EntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/OwnedType0EntityType.cs new file mode 100644 index 00000000000..132e8988c3f --- /dev/null +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/OwnedType0EntityType.cs @@ -0,0 +1,178 @@ +// +using System; +using System.Collections.Generic; +using System.Net; +using System.Reflection; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class OwnedType0EntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalDerived>.ManyOwned#OwnedType", + typeof(CompiledModelTestBase.OwnedType), + baseEntityType, + sharedClrType: true, + propertyCount: 13, + servicePropertyCount: 1, + foreignKeyCount: 1, + keyCount: 1); + + var principalDerivedId = runtimeEntityType.AddProperty( + "PrincipalDerivedId", + typeof(long), + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: 0L); + principalDerivedId.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var principalDerivedAlternateId = runtimeEntityType.AddProperty( + "PrincipalDerivedAlternateId", + typeof(Guid), + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: new Guid("00000000-0000-0000-0000-000000000000")); + principalDerivedAlternateId.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var id = runtimeEntityType.AddProperty( + "Id", + typeof(int), + valueGenerated: ValueGenerated.OnAdd, + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: 0); + id.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + var details = runtimeEntityType.AddProperty( + "Details", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("Details", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_details", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + details.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var number = runtimeEntityType.AddProperty( + "Number", + typeof(int), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("Number", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0); + number.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var refTypeArray = runtimeEntityType.AddProperty( + "RefTypeArray", + typeof(IPAddress[]), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeArray", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + refTypeArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var refTypeEnumerable = runtimeEntityType.AddProperty( + "RefTypeEnumerable", + typeof(IEnumerable), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeEnumerable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeEnumerable", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + refTypeEnumerable.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var refTypeIList = runtimeEntityType.AddProperty( + "RefTypeIList", + typeof(IList), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeIList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeIList", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + refTypeIList.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var refTypeList = runtimeEntityType.AddProperty( + "RefTypeList", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeList", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + refTypeList.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var valueTypeArray = runtimeEntityType.AddProperty( + "ValueTypeArray", + typeof(DateTime[]), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_valueTypeArray", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + valueTypeArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var valueTypeEnumerable = runtimeEntityType.AddProperty( + "ValueTypeEnumerable", + typeof(IEnumerable), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeEnumerable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_valueTypeEnumerable", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + valueTypeEnumerable.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var valueTypeIList = runtimeEntityType.AddProperty( + "ValueTypeIList", + typeof(IList), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeIList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + valueTypeIList.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var valueTypeList = runtimeEntityType.AddProperty( + "ValueTypeList", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_valueTypeList", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + valueTypeList.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var context = runtimeEntityType.AddServiceProperty( + "Context", + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("Context", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + serviceType: typeof(DbContext)); + + var key = runtimeEntityType.AddKey( + new[] { principalDerivedId, principalDerivedAlternateId, id }); + runtimeEntityType.SetPrimaryKey(key); + + return runtimeEntityType; + } + + public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("PrincipalDerivedId"), declaringEntityType.FindProperty("PrincipalDerivedAlternateId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("Id"), principalEntityType.FindProperty("AlternateId") }), + principalEntityType, + deleteBehavior: DeleteBehavior.Cascade, + required: true, + ownership: true); + + var manyOwned = principalEntityType.AddNavigation("ManyOwned", + runtimeForeignKey, + onDependent: false, + typeof(ICollection), + fieldInfo: typeof(CompiledModelTestBase.PrincipalDerived>).GetField("ManyOwned", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + eagerLoaded: true); + + return runtimeForeignKey; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + runtimeEntityType.AddAnnotation("Relational:FunctionName", null); + runtimeEntityType.AddAnnotation("Relational:Schema", null); + runtimeEntityType.AddAnnotation("Relational:SqlQuery", null); + runtimeEntityType.AddAnnotation("Relational:TableName", "ManyOwned"); + runtimeEntityType.AddAnnotation("Relational:ViewName", null); + runtimeEntityType.AddAnnotation("Relational:ViewSchema", null); + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/OwnedTypeEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/OwnedTypeEntityType.cs new file mode 100644 index 00000000000..2e7704f128c --- /dev/null +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/OwnedTypeEntityType.cs @@ -0,0 +1,229 @@ +// +using System; +using System.Collections.Generic; +using System.Net; +using System.Reflection; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class OwnedTypeEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalBase.Owned#OwnedType", + typeof(CompiledModelTestBase.OwnedType), + baseEntityType, + sharedClrType: true, + changeTrackingStrategy: ChangeTrackingStrategy.ChangingAndChangedNotificationsWithOriginalValues, + propertyCount: 12, + servicePropertyCount: 1, + foreignKeyCount: 2, + keyCount: 1); + + var principalBaseId = runtimeEntityType.AddProperty( + "PrincipalBaseId", + typeof(long), + propertyAccessMode: PropertyAccessMode.Field, + valueGenerated: ValueGenerated.OnAdd, + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: 0L); + + var overrides = new StoreObjectDictionary(); + var principalBaseIdPrincipalBase = new RuntimeRelationalPropertyOverrides( + principalBaseId, + StoreObjectIdentifier.Table("PrincipalBase", "mySchema"), + false, + null); + principalBaseIdPrincipalBase.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + overrides.Add(StoreObjectIdentifier.Table("PrincipalBase", "mySchema"), principalBaseIdPrincipalBase); + principalBaseId.AddAnnotation("Relational:RelationalOverrides", overrides); + + principalBaseId.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + var principalBaseAlternateId = runtimeEntityType.AddProperty( + "PrincipalBaseAlternateId", + typeof(Guid), + propertyAccessMode: PropertyAccessMode.Field, + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: new Guid("00000000-0000-0000-0000-000000000000")); + principalBaseAlternateId.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var details = runtimeEntityType.AddProperty( + "Details", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("Details", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_details", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var overrides0 = new StoreObjectDictionary(); + var detailsDetails = new RuntimeRelationalPropertyOverrides( + details, + StoreObjectIdentifier.Table("Details", null), + false, + null); + overrides0.Add(StoreObjectIdentifier.Table("Details", null), detailsDetails); + details.AddAnnotation("Relational:RelationalOverrides", overrides0); + + details.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var number = runtimeEntityType.AddProperty( + "Number", + typeof(int), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("Number", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + sentinel: 0); + number.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var refTypeArray = runtimeEntityType.AddProperty( + "RefTypeArray", + typeof(IPAddress[]), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeArray", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + refTypeArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var refTypeEnumerable = runtimeEntityType.AddProperty( + "RefTypeEnumerable", + typeof(IEnumerable), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeEnumerable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeEnumerable", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + refTypeEnumerable.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var refTypeIList = runtimeEntityType.AddProperty( + "RefTypeIList", + typeof(IList), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeIList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeIList", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + refTypeIList.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var refTypeList = runtimeEntityType.AddProperty( + "RefTypeList", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeList", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + refTypeList.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var valueTypeArray = runtimeEntityType.AddProperty( + "ValueTypeArray", + typeof(DateTime[]), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_valueTypeArray", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + valueTypeArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var valueTypeEnumerable = runtimeEntityType.AddProperty( + "ValueTypeEnumerable", + typeof(IEnumerable), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeEnumerable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_valueTypeEnumerable", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + valueTypeEnumerable.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var valueTypeIList = runtimeEntityType.AddProperty( + "ValueTypeIList", + typeof(IList), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeIList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + valueTypeIList.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var valueTypeList = runtimeEntityType.AddProperty( + "ValueTypeList", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_valueTypeList", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + valueTypeList.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var context = runtimeEntityType.AddServiceProperty( + "Context", + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("Context", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + serviceType: typeof(DbContext)); + + var key = runtimeEntityType.AddKey( + new[] { principalBaseId, principalBaseAlternateId }); + runtimeEntityType.SetPrimaryKey(key); + + return runtimeEntityType; + } + + public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("PrincipalBaseId"), declaringEntityType.FindProperty("PrincipalBaseAlternateId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("Id"), principalEntityType.FindProperty("AlternateId") }), + principalEntityType, + deleteBehavior: DeleteBehavior.Cascade, + unique: true, + required: true, + requiredDependent: true, + ownership: true); + + var owned = principalEntityType.AddNavigation("Owned", + runtimeForeignKey, + onDependent: false, + typeof(CompiledModelTestBase.OwnedType), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("Owned", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("_ownedField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + eagerLoaded: true); + + return runtimeForeignKey; + } + + public static RuntimeForeignKey CreateForeignKey2(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("PrincipalBaseId"), declaringEntityType.FindProperty("PrincipalBaseAlternateId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("PrincipalBaseId"), principalEntityType.FindProperty("PrincipalBaseAlternateId") }), + principalEntityType, + deleteBehavior: DeleteBehavior.Cascade, + unique: true, + required: true, + requiredDependent: true); + + return runtimeForeignKey; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + var fragments = new StoreObjectDictionary(); + var detailsFragment = new RuntimeEntityTypeMappingFragment( + runtimeEntityType, + StoreObjectIdentifier.Table("Details", null), + null); + fragments.Add(StoreObjectIdentifier.Table("Details", null), detailsFragment); + runtimeEntityType.AddAnnotation("Relational:MappingFragments", fragments); + runtimeEntityType.AddAnnotation("Relational:FunctionName", null); + runtimeEntityType.AddAnnotation("Relational:Schema", "mySchema"); + runtimeEntityType.AddAnnotation("Relational:SqlQuery", null); + runtimeEntityType.AddAnnotation("Relational:TableName", "PrincipalBase"); + runtimeEntityType.AddAnnotation("Relational:ViewName", null); + runtimeEntityType.AddAnnotation("Relational:ViewSchema", null); + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalBaseEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalBaseEntityType.cs new file mode 100644 index 00000000000..7a34a9120b7 --- /dev/null +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalBaseEntityType.cs @@ -0,0 +1,214 @@ +// +using System; +using System.Collections.Generic; +using System.Net; +using System.Reflection; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; +using Microsoft.EntityFrameworkCore.Storage.Json; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class PrincipalBaseEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalBase", + typeof(CompiledModelTestBase.PrincipalBase), + baseEntityType, + discriminatorValue: "PrincipalBase", + derivedTypesCount: 1, + propertyCount: 14, + navigationCount: 1, + skipNavigationCount: 1, + unnamedIndexCount: 1, + keyCount: 2); + + var id = runtimeEntityType.AddProperty( + "Id", + typeof(long?), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("Id", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueGenerated: ValueGenerated.OnAdd, + afterSaveBehavior: PropertySaveBehavior.Throw); + + var overrides = new StoreObjectDictionary(); + var idPrincipalDerived = new RuntimeRelationalPropertyOverrides( + id, + StoreObjectIdentifier.Table("PrincipalDerived", null), + true, + "DerivedId"); + overrides.Add(StoreObjectIdentifier.Table("PrincipalDerived", null), idPrincipalDerived); + id.AddAnnotation("Relational:RelationalOverrides", overrides); + + id.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + var alternateId = runtimeEntityType.AddProperty( + "AlternateId", + typeof(Guid), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("AlternateId", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.FieldDuringConstruction, + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: new Guid("00000000-0000-0000-0000-000000000000"), + jsonValueReaderWriter: JsonGuidReaderWriter.Instance); + alternateId.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enum1 = runtimeEntityType.AddProperty( + "Enum1", + typeof(CompiledModelTestBase.AnEnum), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("Enum1", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enum1.SetSentinelFromProviderValue(0); + enum1.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var enum2 = runtimeEntityType.AddProperty( + "Enum2", + typeof(CompiledModelTestBase.AnEnum?), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("Enum2", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + enum2.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var flagsEnum1 = runtimeEntityType.AddProperty( + "FlagsEnum1", + typeof(CompiledModelTestBase.AFlagsEnum), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("FlagsEnum1", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + flagsEnum1.SetSentinelFromProviderValue(0); + flagsEnum1.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var flagsEnum2 = runtimeEntityType.AddProperty( + "FlagsEnum2", + typeof(CompiledModelTestBase.AFlagsEnum), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("FlagsEnum2", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Property); + flagsEnum2.SetSentinelFromProviderValue(6); + flagsEnum2.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var refTypeArray = runtimeEntityType.AddProperty( + "RefTypeArray", + typeof(IPAddress[]), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("RefTypeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + refTypeArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var refTypeEnumerable = runtimeEntityType.AddProperty( + "RefTypeEnumerable", + typeof(IEnumerable), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("RefTypeEnumerable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + refTypeEnumerable.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var refTypeIList = runtimeEntityType.AddProperty( + "RefTypeIList", + typeof(IList), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("RefTypeIList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + refTypeIList.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var refTypeList = runtimeEntityType.AddProperty( + "RefTypeList", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("RefTypeList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + refTypeList.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var valueTypeArray = runtimeEntityType.AddProperty( + "ValueTypeArray", + typeof(DateTime[]), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("ValueTypeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + valueTypeArray.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var valueTypeEnumerable = runtimeEntityType.AddProperty( + "ValueTypeEnumerable", + typeof(IEnumerable), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("ValueTypeEnumerable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + valueTypeEnumerable.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var valueTypeIList = runtimeEntityType.AddProperty( + "ValueTypeIList", + typeof(IList), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("ValueTypeIList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + valueTypeIList.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var valueTypeList = runtimeEntityType.AddProperty( + "ValueTypeList", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("ValueTypeList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + valueTypeList.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var key = runtimeEntityType.AddKey( + new[] { id }); + + var key0 = runtimeEntityType.AddKey( + new[] { id, alternateId }); + runtimeEntityType.SetPrimaryKey(key0); + key0.AddAnnotation("Relational:Name", "PK"); + + var index = runtimeEntityType.AddIndex( + new[] { alternateId, id }); + + return runtimeEntityType; + } + + public static RuntimeSkipNavigation CreateSkipNavigation1(RuntimeEntityType declaringEntityType, RuntimeEntityType targetEntityType, RuntimeEntityType joinEntityType) + { + var skipNavigation = declaringEntityType.AddSkipNavigation( + "Deriveds", + targetEntityType, + joinEntityType.FindForeignKey( + new[] { joinEntityType.FindProperty("PrincipalsId"), joinEntityType.FindProperty("PrincipalsAlternateId") }, + declaringEntityType.FindKey(new[] { declaringEntityType.FindProperty("Id"), declaringEntityType.FindProperty("AlternateId") }), + declaringEntityType), + true, + false, + typeof(ICollection), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("Deriveds", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var inverse = targetEntityType.FindSkipNavigation("Principals"); + if (inverse != null) + { + skipNavigation.Inverse = inverse; + inverse.Inverse = skipNavigation; + } + + return skipNavigation; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + runtimeEntityType.AddAnnotation("Relational:FunctionName", null); + runtimeEntityType.AddAnnotation("Relational:MappingStrategy", "TPT"); + runtimeEntityType.AddAnnotation("Relational:Schema", "mySchema"); + runtimeEntityType.AddAnnotation("Relational:SqlQuery", null); + runtimeEntityType.AddAnnotation("Relational:TableName", "PrincipalBase"); + runtimeEntityType.AddAnnotation("Relational:ViewName", null); + runtimeEntityType.AddAnnotation("Relational:ViewSchema", null); + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs new file mode 100644 index 00000000000..3b4f9aad8fd --- /dev/null +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs @@ -0,0 +1,117 @@ +// +using System; +using System.Collections.Generic; +using System.Reflection; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class PrincipalBasePrincipalDerivedDependentBasebyteEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "PrincipalBasePrincipalDerived>", + typeof(Dictionary), + baseEntityType, + sharedClrType: true, + indexerPropertyInfo: RuntimeEntityType.FindIndexerProperty(typeof(Dictionary)), + propertyBag: true, + propertyCount: 5, + foreignKeyCount: 2, + unnamedIndexCount: 1, + keyCount: 1); + + var derivedsId = runtimeEntityType.AddProperty( + "DerivedsId", + typeof(long), + propertyInfo: runtimeEntityType.FindIndexerPropertyInfo(), + afterSaveBehavior: PropertySaveBehavior.Throw); + derivedsId.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var derivedsAlternateId = runtimeEntityType.AddProperty( + "DerivedsAlternateId", + typeof(Guid), + propertyInfo: runtimeEntityType.FindIndexerPropertyInfo(), + afterSaveBehavior: PropertySaveBehavior.Throw); + derivedsAlternateId.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var principalsId = runtimeEntityType.AddProperty( + "PrincipalsId", + typeof(long), + propertyInfo: runtimeEntityType.FindIndexerPropertyInfo(), + afterSaveBehavior: PropertySaveBehavior.Throw); + principalsId.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var principalsAlternateId = runtimeEntityType.AddProperty( + "PrincipalsAlternateId", + typeof(Guid), + propertyInfo: runtimeEntityType.FindIndexerPropertyInfo(), + afterSaveBehavior: PropertySaveBehavior.Throw); + principalsAlternateId.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var rowid = runtimeEntityType.AddProperty( + "rowid", + typeof(byte[]), + propertyInfo: runtimeEntityType.FindIndexerPropertyInfo(), + nullable: true, + concurrencyToken: true, + valueGenerated: ValueGenerated.OnAddOrUpdate, + beforeSaveBehavior: PropertySaveBehavior.Ignore, + afterSaveBehavior: PropertySaveBehavior.Ignore); + rowid.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); + + var key = runtimeEntityType.AddKey( + new[] { derivedsId, derivedsAlternateId, principalsId, principalsAlternateId }); + runtimeEntityType.SetPrimaryKey(key); + + var index = runtimeEntityType.AddIndex( + new[] { principalsId, principalsAlternateId }); + + return runtimeEntityType; + } + + public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("DerivedsId"), declaringEntityType.FindProperty("DerivedsAlternateId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("Id"), principalEntityType.FindProperty("AlternateId") }), + principalEntityType, + deleteBehavior: DeleteBehavior.Cascade, + required: true); + + return runtimeForeignKey; + } + + public static RuntimeForeignKey CreateForeignKey2(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("PrincipalsId"), declaringEntityType.FindProperty("PrincipalsAlternateId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("Id"), principalEntityType.FindProperty("AlternateId") }), + principalEntityType, + deleteBehavior: DeleteBehavior.ClientCascade, + required: true); + + return runtimeForeignKey; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + runtimeEntityType.AddAnnotation("Relational:FunctionName", null); + runtimeEntityType.AddAnnotation("Relational:Schema", null); + runtimeEntityType.AddAnnotation("Relational:SqlQuery", null); + runtimeEntityType.AddAnnotation("Relational:TableName", "PrincipalBasePrincipalDerived>"); + runtimeEntityType.AddAnnotation("Relational:ViewName", null); + runtimeEntityType.AddAnnotation("Relational:ViewSchema", null); + runtimeEntityType.AddAnnotation("SqlServer:MemoryOptimized", true); + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalDerivedEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalDerivedEntityType.cs new file mode 100644 index 00000000000..757c5ab1800 --- /dev/null +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalDerivedEntityType.cs @@ -0,0 +1,84 @@ +// +using System; +using System.Collections.Generic; +using System.Reflection; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class PrincipalDerivedEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalDerived>", + typeof(CompiledModelTestBase.PrincipalDerived>), + baseEntityType, + discriminatorValue: "PrincipalDerived>", + propertyCount: 0, + navigationCount: 2, + skipNavigationCount: 1, + foreignKeyCount: 1); + + return runtimeEntityType; + } + + public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("Id"), declaringEntityType.FindProperty("AlternateId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("Id"), principalEntityType.FindProperty("AlternateId") }), + principalEntityType, + deleteBehavior: DeleteBehavior.Cascade, + unique: true, + required: true); + + return runtimeForeignKey; + } + + public static RuntimeSkipNavigation CreateSkipNavigation1(RuntimeEntityType declaringEntityType, RuntimeEntityType targetEntityType, RuntimeEntityType joinEntityType) + { + var skipNavigation = declaringEntityType.AddSkipNavigation( + "Principals", + targetEntityType, + joinEntityType.FindForeignKey( + new[] { joinEntityType.FindProperty("DerivedsId"), joinEntityType.FindProperty("DerivedsAlternateId") }, + declaringEntityType.FindKey(new[] { declaringEntityType.FindProperty("Id"), declaringEntityType.FindProperty("AlternateId") }), + declaringEntityType), + true, + false, + typeof(ICollection), + propertyInfo: typeof(CompiledModelTestBase.PrincipalDerived>).GetProperty("Principals", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalDerived>).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var inverse = targetEntityType.FindSkipNavigation("Deriveds"); + if (inverse != null) + { + skipNavigation.Inverse = inverse; + inverse.Inverse = skipNavigation; + } + + return skipNavigation; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + runtimeEntityType.AddAnnotation("Relational:FunctionName", null); + runtimeEntityType.AddAnnotation("Relational:Schema", null); + runtimeEntityType.AddAnnotation("Relational:SqlQuery", null); + runtimeEntityType.AddAnnotation("Relational:TableName", "PrincipalDerived"); + runtimeEntityType.AddAnnotation("Relational:ViewName", null); + runtimeEntityType.AddAnnotation("Relational:ViewSchema", null); + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/SimpleModel/DependentDerivedEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/SimpleModel/DependentDerivedEntityType.cs index fee5ee69e12..3dd7772292f 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/SimpleModel/DependentDerivedEntityType.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/SimpleModel/DependentDerivedEntityType.cs @@ -128,8 +128,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var data = runtimeEntityType.FindProperty("Data")!; + var id = runtimeEntityType.FindProperty("Id"); + var data = runtimeEntityType.FindProperty("Data"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/SpatialTypesTest/SpatialTypesEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/SpatialTypesTest/SpatialTypesEntityType.cs index 56eb331cd5d..dce89096f24 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/SpatialTypesTest/SpatialTypesEntityType.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/SpatialTypesTest/SpatialTypesEntityType.cs @@ -108,8 +108,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var point = runtimeEntityType.FindProperty("Point")!; + var id = runtimeEntityType.FindProperty("Id"); + var point = runtimeEntityType.FindProperty("Point"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Tpc_Sprocs/DependentBaseEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Tpc_Sprocs/DependentBaseEntityType.cs index 323cb549360..7bc1c1ecf06 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Tpc_Sprocs/DependentBaseEntityType.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Tpc_Sprocs/DependentBaseEntityType.cs @@ -72,9 +72,9 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (byte v1, byte v2) => v1 == v2, int (byte v) => ((int)(v)), byte (byte v) => v)); - id.SetValueComparer(new NullableValueComparer(id.TypeMapping.Comparer)); - id.SetKeyValueComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); id.SetCurrentValueComparer(new EntryCurrentValueComparer(id)); + id.SetComparer(new NullableValueComparer(id.TypeMapping.Comparer)); + id.SetKeyComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); id.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var principalId = runtimeEntityType.AddProperty( @@ -106,9 +106,9 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (long v1, long v2) => v1 == v2, int (long v) => ((object)v).GetHashCode(), long (long v) => v)); - principalId.SetValueComparer(new NullableValueComparer(principalId.TypeMapping.Comparer)); - principalId.SetKeyValueComparer(new NullableValueComparer(principalId.TypeMapping.KeyComparer)); principalId.SetCurrentValueComparer(new EntryCurrentValueComparer(principalId)); + principalId.SetComparer(new NullableValueComparer(principalId.TypeMapping.Comparer)); + principalId.SetKeyComparer(new NullableValueComparer(principalId.TypeMapping.KeyComparer)); principalId.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var key = runtimeEntityType.AddKey( @@ -193,12 +193,12 @@ public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEnt public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var principalId = runtimeEntityType.FindProperty("PrincipalId")!; + var id = runtimeEntityType.FindProperty("Id"); + var principalId = runtimeEntityType.FindProperty("PrincipalId"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); - var principal = runtimeEntityType.FindNavigation("Principal")!; + var principal = runtimeEntityType.FindNavigation("Principal"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Tpc_Sprocs/PrincipalBaseEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Tpc_Sprocs/PrincipalBaseEntityType.cs index 9ee49be5a27..0cfa13e849e 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Tpc_Sprocs/PrincipalBaseEntityType.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Tpc_Sprocs/PrincipalBaseEntityType.cs @@ -77,9 +77,9 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (long v1, long v2) => v1 == v2, int (long v) => ((object)v).GetHashCode(), long (long v) => v)); - id.SetValueComparer(new NullableValueComparer(id.TypeMapping.Comparer)); - id.SetKeyValueComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); id.SetCurrentValueComparer(new EntryCurrentValueComparer(id)); + id.SetComparer(new NullableValueComparer(id.TypeMapping.Comparer)); + id.SetKeyComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); var overrides = new StoreObjectDictionary(); var idPrincipalBaseView = new RuntimeRelationalPropertyOverrides( @@ -203,8 +203,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( int (CompiledModelTestBase.AnEnum value) => ((int)(value)), CompiledModelTestBase.AnEnum (int value) => ((CompiledModelTestBase.AnEnum)(value))))); - enum2.SetValueComparer(new NullableValueComparer(enum2.TypeMapping.Comparer)); - enum2.SetKeyValueComparer(new NullableValueComparer(enum2.TypeMapping.KeyComparer)); + enum2.SetComparer(new NullableValueComparer(enum2.TypeMapping.Comparer)); + enum2.SetKeyComparer(new NullableValueComparer(enum2.TypeMapping.KeyComparer)); enum2.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var flagsEnum1 = runtimeEntityType.AddProperty( @@ -336,9 +336,9 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (long v1, long v2) => v1 == v2, int (long v) => ((object)v).GetHashCode(), long (long v) => v)); - principalBaseId.SetValueComparer(new NullableValueComparer(principalBaseId.TypeMapping.Comparer)); - principalBaseId.SetKeyValueComparer(new NullableValueComparer(principalBaseId.TypeMapping.KeyComparer)); principalBaseId.SetCurrentValueComparer(new EntryCurrentValueComparer(principalBaseId)); + principalBaseId.SetComparer(new NullableValueComparer(principalBaseId.TypeMapping.Comparer)); + principalBaseId.SetKeyComparer(new NullableValueComparer(principalBaseId.TypeMapping.KeyComparer)); principalBaseId.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var principalDerivedId = runtimeEntityType.AddProperty( @@ -370,9 +370,9 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (long v1, long v2) => v1 == v2, int (long v) => ((object)v).GetHashCode(), long (long v) => v)); - principalDerivedId.SetValueComparer(new NullableValueComparer(principalDerivedId.TypeMapping.Comparer)); - principalDerivedId.SetKeyValueComparer(new NullableValueComparer(principalDerivedId.TypeMapping.KeyComparer)); principalDerivedId.SetCurrentValueComparer(new EntryCurrentValueComparer(principalDerivedId)); + principalDerivedId.SetComparer(new NullableValueComparer(principalDerivedId.TypeMapping.Comparer)); + principalDerivedId.SetKeyComparer(new NullableValueComparer(principalDerivedId.TypeMapping.KeyComparer)); principalDerivedId.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var refTypeArray = runtimeEntityType.AddProperty( @@ -1044,25 +1044,25 @@ public static RuntimeForeignKey CreateForeignKey2(RuntimeEntityType declaringEnt public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var enum1 = runtimeEntityType.FindProperty("Enum1")!; - var enum2 = runtimeEntityType.FindProperty("Enum2")!; - var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1")!; - var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2")!; - var principalBaseId = runtimeEntityType.FindProperty("PrincipalBaseId")!; - var principalDerivedId = runtimeEntityType.FindProperty("PrincipalDerivedId")!; - var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray")!; - var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable")!; - var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList")!; - var refTypeList = runtimeEntityType.FindProperty("RefTypeList")!; - var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList")!; - var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList")!; + var id = runtimeEntityType.FindProperty("Id"); + var enum1 = runtimeEntityType.FindProperty("Enum1"); + var enum2 = runtimeEntityType.FindProperty("Enum2"); + var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1"); + var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2"); + var principalBaseId = runtimeEntityType.FindProperty("PrincipalBaseId"); + var principalDerivedId = runtimeEntityType.FindProperty("PrincipalDerivedId"); + var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray"); + var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable"); + var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList"); + var refTypeList = runtimeEntityType.FindProperty("RefTypeList"); + var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList"); + var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); - var deriveds = runtimeEntityType.FindNavigation("Deriveds")!; + var deriveds = runtimeEntityType.FindNavigation("Deriveds"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Tpc_Sprocs/PrincipalDerivedEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Tpc_Sprocs/PrincipalDerivedEntityType.cs index fd2f469da95..5de45d533f9 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Tpc_Sprocs/PrincipalDerivedEntityType.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Tpc_Sprocs/PrincipalDerivedEntityType.cs @@ -33,24 +33,24 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var enum1 = runtimeEntityType.FindProperty("Enum1")!; - var enum2 = runtimeEntityType.FindProperty("Enum2")!; - var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1")!; - var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2")!; - var principalBaseId = runtimeEntityType.FindProperty("PrincipalBaseId")!; - var principalDerivedId = runtimeEntityType.FindProperty("PrincipalDerivedId")!; - var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray")!; - var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable")!; - var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList")!; - var refTypeList = runtimeEntityType.FindProperty("RefTypeList")!; - var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList")!; - var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList")!; - var deriveds = runtimeEntityType.FindNavigation("Deriveds")!; - var dependent = runtimeEntityType.FindNavigation("Dependent")!; - var principals = runtimeEntityType.FindNavigation("Principals")!; + var id = runtimeEntityType.FindProperty("Id"); + var enum1 = runtimeEntityType.FindProperty("Enum1"); + var enum2 = runtimeEntityType.FindProperty("Enum2"); + var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1"); + var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2"); + var principalBaseId = runtimeEntityType.FindProperty("PrincipalBaseId"); + var principalDerivedId = runtimeEntityType.FindProperty("PrincipalDerivedId"); + var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray"); + var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable"); + var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList"); + var refTypeList = runtimeEntityType.FindProperty("RefTypeList"); + var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList"); + var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList"); + var deriveds = runtimeEntityType.FindNavigation("Deriveds"); + var dependent = runtimeEntityType.FindNavigation("Dependent"); + var principals = runtimeEntityType.FindNavigation("Principals"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Triggers/DataEntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Triggers/DataEntityType.cs index c0be980d397..9500d7a5799 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Triggers/DataEntityType.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/Triggers/DataEntityType.cs @@ -125,8 +125,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var blob = runtimeEntityType.FindProperty("Blob")!; + var id = runtimeEntityType.FindProperty("Id"); + var blob = runtimeEntityType.FindProperty("Blob"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/CompiledModelSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/CompiledModelSqlServerTest.cs index 375a111d1bf..2503b3bacdb 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/CompiledModelSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/CompiledModelSqlServerTest.cs @@ -5,10 +5,10 @@ using System.Runtime.CompilerServices; using Microsoft.EntityFrameworkCore.Metadata.Internal; -using Microsoft.EntityFrameworkCore.SqlServer.Metadata.Internal; using Microsoft.EntityFrameworkCore.SqlServer.Design.Internal; -using NetTopologySuite.Geometries; +using Microsoft.EntityFrameworkCore.SqlServer.Metadata.Internal; using NetTopologySuite; +using NetTopologySuite.Geometries; namespace Microsoft.EntityFrameworkCore.Scaffolding; @@ -64,7 +64,7 @@ protected override void BuildBigModel(ModelBuilder modelBuilder, bool jsonColumn eb => { eb.Property(m => m.CharToStringConverterProperty) - .IsFixedLength(true); + .IsFixedLength(); }); } @@ -104,6 +104,7 @@ protected override void AssertBigModel(IModel model, bool jsonColumns) principalId.GetAnnotations().Select(a => a.Name)); Assert.Equal(SqlServerValueGenerationStrategy.IdentityColumn, principalId.GetValueGenerationStrategy()); } + Assert.Null(principalId[SqlServerAnnotationNames.IdentitySeed]); Assert.Equal( CoreStrings.RuntimeModelMissingData, @@ -181,7 +182,7 @@ protected override void AssertBigModel(IModel model, bool jsonColumns) var dependentMoney = dependentDerived.GetDeclaredProperties().Last(); Assert.Equal("decimal(9,3)", dependentMoney.GetColumnType()); Assert.Equal( - new[] + new[] { dependentBase, dependentDerived, @@ -195,7 +196,8 @@ protected override void AssertBigModel(IModel model, bool jsonColumns) model.GetEntityTypes()); } - protected override bool UseSprocReturnValue => true; + protected override bool UseSprocReturnValue + => true; protected override void BuildTpcSprocsModel(ModelBuilder modelBuilder) { @@ -341,7 +343,8 @@ protected override void AssertComplexTypes(IModel model) [ConditionalFact] public virtual Task Key_HiLo_sequence() => Test( - modelBuilder => { + modelBuilder => + { modelBuilder.Entity( eb => { @@ -428,10 +431,13 @@ public virtual Task SpatialTypesTest() Assert.Equal(SqlServerValueGenerationStrategy.None, pointProperty.GetValueGenerationStrategy()); Assert.Null(pointProperty[CoreAnnotationNames.PropertyAccessMode]); }, - options: new CompiledModelCodeGenerationOptions { UseNullableReferenceTypes = true }); + options: new CompiledModelCodeGenerationOptions { UseNullableReferenceTypes = true, ForNativeAot = true }); + + protected override TestHelpers TestHelpers + => SqlServerTestHelpers.Instance; - protected override TestHelpers TestHelpers => SqlServerTestHelpers.Instance; - protected override ITestStoreFactory TestStoreFactory => SqlServerTestStoreFactory.Instance; + protected override ITestStoreFactory TestStoreFactory + => SqlServerTestStoreFactory.Instance; protected override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) { diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/SqlServerDatabaseModelFactoryTest.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/SqlServerDatabaseModelFactoryTest.cs index e3d56a4901f..b3f55ea9ea8 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/SqlServerDatabaseModelFactoryTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/SqlServerDatabaseModelFactoryTest.cs @@ -60,10 +60,11 @@ MAXVALUE 8 Assert.Equal(-3, customSequence.MinValue); Assert.Equal(8, customSequence.MaxValue); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Empty(model.GetEntityTypes()); - Assert.Collection(model.GetSequences(), + Assert.Collection( + model.GetSequences(), s => { Assert.Equal("db2", s.Schema); @@ -116,10 +117,11 @@ public void Sequence_min_max_start_values_are_null_if_default() Assert.Null(s.MaxValue); }); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Empty(model.GetEntityTypes()); - Assert.Collection(model.GetSequences(), + Assert.Collection( + model.GetSequences(), s => { Assert.Equal("dbo", s.Schema); @@ -194,10 +196,11 @@ public void Sequence_min_max_start_values_are_not_null_if_decimal() Assert.NotNull(s.MaxValue); }); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Empty(model.GetEntityTypes()); - Assert.Collection(model.GetSequences(), + Assert.Collection( + model.GetSequences(), s => { Assert.Equal("dbo", s.Schema); @@ -253,10 +256,11 @@ MAXVALUE 99999999999999999999999999999999999999 Assert.Equal(long.MaxValue, s.MaxValue); }); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Empty(model.GetEntityTypes()); - Assert.Collection(model.GetSequences(), + Assert.Collection( + model.GetSequences(), s => { Assert.Equal("dbo", s.Schema); @@ -297,10 +301,11 @@ public void Sequence_using_type_alias() Assert.Null(sequence.MinValue); Assert.Null(sequence.MaxValue); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Empty(model.GetEntityTypes()); - Assert.Collection(model.GetSequences(), + Assert.Collection( + model.GetSequences(), s => { Assert.Equal("dbo", s.Schema); @@ -335,10 +340,11 @@ public void Sequence_using_type_with_facets() Assert.False(sequence.IsCyclic); Assert.Equal(1, sequence.IncrementBy); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Empty(model.GetEntityTypes()); - Assert.Collection(model.GetSequences(), + Assert.Collection( + model.GetSequences(), s => { Assert.Equal("dbo", s.Schema); @@ -373,10 +379,11 @@ public void Filter_sequences_based_on_schema() Assert.False(sequence.IsCyclic); Assert.Equal(1, sequence.IncrementBy); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Empty(model.GetEntityTypes()); - Assert.Collection(model.GetSequences(), + Assert.Collection( + model.GetSequences(), s => { Assert.Equal("db2", s.Schema); @@ -409,7 +416,7 @@ public void Set_default_schema() var defaultSchema = Fixture.TestStore.ExecuteScalar("SELECT SCHEMA_NAME()"); Assert.Equal(defaultSchema, dbModel.DefaultSchema); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal("dbo", model.GetDefaultSchema()); }, @@ -439,7 +446,7 @@ public void Create_tables() Assert.Equal("Everest", e.Name); }); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), @@ -564,10 +571,12 @@ ALTER TABLE [dbo].[Properties] CHECK CONSTRAINT [FK_Properties_Listings] { Assert.Equal("dbo", t.Schema); Assert.Equal("AttributesByCategory", t.Name); - Assert.Collection(t.Columns, + Assert.Collection( + t.Columns, c => Assert.Equal("IdB", c.Name), c => Assert.Equal("IdC", c.Name)); - Assert.Collection(t.PrimaryKey!.Columns, + Assert.Collection( + t.PrimaryKey!.Columns, c => Assert.Equal("IdB", c.Name), c => Assert.Equal("IdC", c.Name)); Assert.Collection( @@ -591,17 +600,21 @@ ALTER TABLE [dbo].[Properties] CHECK CONSTRAINT [FK_Properties_Listings] { Assert.Equal("dbo", t.Schema); Assert.Equal("Properties", t.Name); - Assert.Collection(t.Columns, + Assert.Collection( + t.Columns, c => Assert.Equal("IdA", c.Name), c => Assert.Equal("IdB", c.Name), c => Assert.Equal("IdC", c.Name)); - Assert.Collection(t.PrimaryKey!.Columns, + Assert.Collection( + t.PrimaryKey!.Columns, c => Assert.Equal("IdA", c.Name), c => Assert.Equal("IdB", c.Name), c => Assert.Equal("IdC", c.Name)); - Assert.Collection(t.UniqueConstraints, u => Assert.Collection(u.Columns, - c => Assert.Equal("IdA", c.Name), - c => Assert.Equal("IdC", c.Name))); + Assert.Collection( + t.UniqueConstraints, u => Assert.Collection( + u.Columns, + c => Assert.Equal("IdA", c.Name), + c => Assert.Equal("IdC", c.Name))); Assert.Collection( t.ForeignKeys, k => @@ -622,19 +635,23 @@ ALTER TABLE [dbo].[Properties] CHECK CONSTRAINT [FK_Properties_Listings] { Assert.Equal("dbo", t.Schema); Assert.Equal("TableAB", t.Name); - Assert.Collection(t.Columns, + Assert.Collection( + t.Columns, c => Assert.Equal("IdA", c.Name), c => Assert.Equal("IdB", c.Name)); Assert.Collection(t.PrimaryKey!.Columns, c => Assert.Equal("IdA", c.Name)); - Assert.Collection(t.UniqueConstraints, u => Assert.Collection(u.Columns, - c => Assert.Equal("IdA", c.Name), - c => Assert.Equal("IdB", c.Name))); - Assert.Collection(t.ForeignKeys, k => - { - Assert.Equal("TableB", k.PrincipalTable.Name); - Assert.Collection(k.Columns, c => Assert.Equal("IdB", c.Name)); - Assert.Collection(k.PrincipalColumns, c => Assert.Equal("IdB", c.Name)); - }); + Assert.Collection( + t.UniqueConstraints, u => Assert.Collection( + u.Columns, + c => Assert.Equal("IdA", c.Name), + c => Assert.Equal("IdB", c.Name))); + Assert.Collection( + t.ForeignKeys, k => + { + Assert.Equal("TableB", k.PrincipalTable.Name); + Assert.Collection(k.Columns, c => Assert.Equal("IdB", c.Name)); + Assert.Collection(k.PrincipalColumns, c => Assert.Equal("IdB", c.Name)); + }); Assert.Empty(t.Indexes); }, t => @@ -658,18 +675,21 @@ ALTER TABLE [dbo].[Properties] CHECK CONSTRAINT [FK_Properties_Listings] Assert.Empty(t.Indexes); }); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), e => { Assert.Equal("AttributesByCategory", e.Name); - Assert.Collection(e.GetProperties(), + Assert.Collection( + e.GetProperties(), p => Assert.Equal("IdB", p.Name), p => Assert.Equal("IdC", p.Name)); - Assert.Collection(e.GetKeys(), - c => Assert.Collection(c.Properties, + Assert.Collection( + e.GetKeys(), + c => Assert.Collection( + c.Properties, p => Assert.Equal("IdB", p.Name), p => Assert.Equal("IdC", p.Name))); Assert.Collection( @@ -690,7 +710,8 @@ ALTER TABLE [dbo].[Properties] CHECK CONSTRAINT [FK_Properties_Listings] }); Assert.Empty(e.GetIndexes()); Assert.Empty(e.GetSkipNavigations()); - Assert.Collection(e.GetNavigations(), + Assert.Collection( + e.GetNavigations(), n => { Assert.Equal("TableB", n.TargetEntityType.Name); @@ -714,11 +735,13 @@ ALTER TABLE [dbo].[Properties] CHECK CONSTRAINT [FK_Properties_Listings] e => { Assert.Equal("Property", e.Name); - Assert.Collection(e.GetProperties(), + Assert.Collection( + e.GetProperties(), p => Assert.Equal("IdA", p.Name), p => Assert.Equal("IdB", p.Name), p => Assert.Equal("IdC", p.Name)); - Assert.Collection(e.GetKeys(), + Assert.Collection( + e.GetKeys(), k => { Assert.Collection( @@ -733,10 +756,12 @@ ALTER TABLE [dbo].[Properties] CHECK CONSTRAINT [FK_Properties_Listings] k => { Assert.Equal("TableAb", k.PrincipalEntityType.Name); - Assert.Collection(k.Properties, + Assert.Collection( + k.Properties, p => Assert.Equal("IdA", p.Name), p => Assert.Equal("IdB", p.Name)); - Assert.Collection(k.PrincipalKey.Properties, + Assert.Collection( + k.PrincipalKey.Properties, p => Assert.Equal("IdA", p.Name), p => Assert.Equal("IdB", p.Name)); Assert.False(k.IsUnique); @@ -744,15 +769,18 @@ ALTER TABLE [dbo].[Properties] CHECK CONSTRAINT [FK_Properties_Listings] k => { Assert.Equal("AttributesByCategory", k.PrincipalEntityType.Name); - Assert.Collection(k.Properties, + Assert.Collection( + k.Properties, p => Assert.Equal("IdB", p.Name), p => Assert.Equal("IdC", p.Name)); - Assert.Collection(k.PrincipalKey.Properties, + Assert.Collection( + k.PrincipalKey.Properties, p => Assert.Equal("IdB", p.Name), p => Assert.Equal("IdC", p.Name)); Assert.False(k.IsUnique); }); - Assert.Collection(e.GetIndexes(), + Assert.Collection( + e.GetIndexes(), i => { Assert.Collection( @@ -761,7 +789,8 @@ ALTER TABLE [dbo].[Properties] CHECK CONSTRAINT [FK_Properties_Listings] p => Assert.Equal("IdC", p.Name)); Assert.True(i.IsUnique); }); - Assert.Collection(e.GetNavigations(), + Assert.Collection( + e.GetNavigations(), n => { Assert.Equal("AttributesByCategory", n.TargetEntityType.Name); @@ -779,10 +808,12 @@ ALTER TABLE [dbo].[Properties] CHECK CONSTRAINT [FK_Properties_Listings] e => { Assert.Equal("TableAb", e.Name); - Assert.Collection(e.GetProperties(), + Assert.Collection( + e.GetProperties(), p => Assert.Equal("IdA", p.Name), p => Assert.Equal("IdB", p.Name)); - Assert.Collection(e.GetKeys(), + Assert.Collection( + e.GetKeys(), k => { Assert.Collection(k.Properties, p => Assert.Equal("IdA", p.Name)); @@ -793,20 +824,23 @@ ALTER TABLE [dbo].[Properties] CHECK CONSTRAINT [FK_Properties_Listings] Assert.Collection(k.Properties, p => Assert.Equal("IdA", p.Name), p => Assert.Equal("IdB", p.Name)); Assert.False(k.IsPrimaryKey()); }); - Assert.Collection(e.GetForeignKeys(), k => - { - Assert.Equal("TableB", k.PrincipalEntityType.Name); - Assert.Collection(k.Properties, p => Assert.Equal("IdB", p.Name)); - Assert.Collection(k.PrincipalKey.Properties, p => Assert.Equal("IdB", p.Name)); - Assert.False(k.IsUnique); - }); - Assert.Collection(e.GetIndexes(), + Assert.Collection( + e.GetForeignKeys(), k => + { + Assert.Equal("TableB", k.PrincipalEntityType.Name); + Assert.Collection(k.Properties, p => Assert.Equal("IdB", p.Name)); + Assert.Collection(k.PrincipalKey.Properties, p => Assert.Equal("IdB", p.Name)); + Assert.False(k.IsUnique); + }); + Assert.Collection( + e.GetIndexes(), i => { Assert.Collection(i.Properties, p => Assert.Equal("IdA", p.Name), p => Assert.Equal("IdB", p.Name)); Assert.True(i.IsUnique); }); - Assert.Collection(e.GetNavigations(), + Assert.Collection( + e.GetNavigations(), n => { Assert.Equal("TableB", n.TargetEntityType.Name); @@ -828,7 +862,8 @@ ALTER TABLE [dbo].[Properties] CHECK CONSTRAINT [FK_Properties_Listings] Assert.Collection(e.GetKeys(), k => Assert.Collection(k.Properties, p => Assert.Equal("IdB", p.Name))); Assert.Empty(e.GetForeignKeys()); Assert.Empty(e.GetIndexes()); - Assert.Collection(e.GetNavigations(), + Assert.Collection( + e.GetNavigations(), n => { Assert.Equal("AttributesByCategory", n.TargetEntityType.Name); @@ -850,7 +885,8 @@ ALTER TABLE [dbo].[Properties] CHECK CONSTRAINT [FK_Properties_Listings] Assert.Collection(e.GetKeys(), k => Assert.Collection(k.Properties, p => Assert.Equal("IdC", p.Name))); Assert.Empty(e.GetForeignKeys()); Assert.Empty(e.GetIndexes()); - Assert.Collection(e.GetNavigations(), + Assert.Collection( + e.GetNavigations(), n => { Assert.Equal("AttributesByCategory", n.TargetEntityType.Name); @@ -895,10 +931,12 @@ CONSTRAINT [PK_LinkToBBlogPPosts] PRIMARY KEY (LinkId1, LinkId2), { Assert.Equal("dbo", t.Schema); Assert.Equal("BBlogPPosts", t.Name); - Assert.Collection(t.Columns, + Assert.Collection( + t.Columns, c => Assert.Equal("BBlogId", c.Name), c => Assert.Equal("PPostId", c.Name)); - Assert.Collection(t.ForeignKeys, + Assert.Collection( + t.ForeignKeys, c => { Assert.Equal("BBlogs", c.PrincipalTable.Name); @@ -922,10 +960,12 @@ CONSTRAINT [PK_LinkToBBlogPPosts] PRIMARY KEY (LinkId1, LinkId2), { Assert.Equal("dbo", t.Schema); Assert.Equal("LinkToBBlogPPosts", t.Name); - Assert.Collection(t.Columns, + Assert.Collection( + t.Columns, c => Assert.Equal("LinkId1", c.Name), c => Assert.Equal("LinkId2", c.Name)); - Assert.Collection(t.ForeignKeys, + Assert.Collection( + t.ForeignKeys, c => { Assert.Equal("BBlogPPosts", c.PrincipalTable.Name); @@ -958,10 +998,12 @@ CONSTRAINT [PK_LinkToBBlogPPosts] PRIMARY KEY (LinkId1, LinkId2), e => { Assert.Equal("BblogPpost", e.Name); - Assert.Collection(e.GetProperties(), + Assert.Collection( + e.GetProperties(), p => Assert.Equal("BblogId", p.Name), p => Assert.Equal("PpostId", p.Name)); - Assert.Collection(e.GetForeignKeys(), + Assert.Collection( + e.GetForeignKeys(), k => { Assert.Equal("Bblog", k.PrincipalEntityType.Name); @@ -977,7 +1019,8 @@ CONSTRAINT [PK_LinkToBBlogPPosts] PRIMARY KEY (LinkId1, LinkId2), Assert.False(k.IsUnique); }); Assert.Empty(e.GetSkipNavigations()); - Assert.Collection(e.GetNavigations(), + Assert.Collection( + e.GetNavigations(), p => Assert.Equal("Bblog", p.Name), p => Assert.Equal("LinkToBblogPpost", p.Name), p => Assert.Equal("Ppost", p.Name)); @@ -985,18 +1028,22 @@ CONSTRAINT [PK_LinkToBBlogPPosts] PRIMARY KEY (LinkId1, LinkId2), e => { Assert.Equal("LinkToBblogPpost", e.Name); - Assert.Collection(e.GetProperties(), + Assert.Collection( + e.GetProperties(), p => Assert.Equal("LinkId1", p.Name), p => Assert.Equal("LinkId2", p.Name)); - Assert.Collection(e.GetForeignKeys(), + Assert.Collection( + e.GetForeignKeys(), k => { Assert.Equal("BblogPpost", k.PrincipalEntityType.Name); Assert.Equal("LinkToBblogPpost", k.DeclaringEntityType.Name); - Assert.Collection(k.Properties, + Assert.Collection( + k.Properties, p => Assert.Equal("LinkId1", p.Name), p => Assert.Equal("LinkId2", p.Name)); - Assert.Collection(k.PrincipalKey.Properties, + Assert.Collection( + k.PrincipalKey.Properties, p => Assert.Equal("BblogId", p.Name), p => Assert.Equal("PpostId", p.Name)); Assert.True(k.IsUnique); @@ -1050,7 +1097,7 @@ public void Filter_schemas() Assert.Equal(1, table.UniqueConstraints.Count); Assert.Empty(table.ForeignKeys); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, @@ -1077,7 +1124,7 @@ public void Filter_tables() Assert.Equal(1, table.UniqueConstraints.Count); Assert.Empty(table.ForeignKeys); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, @@ -1104,7 +1151,7 @@ public void Filter_tables_with_quote_in_name() Assert.Equal(1, table.UniqueConstraints.Count); Assert.Empty(table.ForeignKeys); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, @@ -1131,7 +1178,7 @@ public void Filter_tables_with_qualified_name() Assert.Equal(1, table.UniqueConstraints.Count); Assert.Empty(table.ForeignKeys); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, @@ -1160,7 +1207,7 @@ public void Filter_tables_with_schema_qualified_name1() Assert.Equal(1, table.UniqueConstraints.Count); Assert.Empty(table.ForeignKeys); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, @@ -1191,7 +1238,7 @@ public void Filter_tables_with_schema_qualified_name2() Assert.Equal(1, table.UniqueConstraints.Count); Assert.Empty(table.ForeignKeys); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, @@ -1222,7 +1269,7 @@ public void Filter_tables_with_schema_qualified_name3() Assert.Equal(1, table.UniqueConstraints.Count); Assert.Empty(table.ForeignKeys); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, @@ -1253,7 +1300,7 @@ public void Filter_tables_with_schema_qualified_name4() Assert.Equal(1, table.UniqueConstraints.Count); Assert.Empty(table.ForeignKeys); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, @@ -1337,7 +1384,7 @@ FOREIGN KEY (ForeignKeyId1, ForeignKeyId2) REFERENCES [db2].[PrincipalTable](UC1 // ReSharper disable once PossibleNullReferenceException Assert.Single(dependentTable.ForeignKeys); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetSequences(), @@ -1369,15 +1416,18 @@ FOREIGN KEY (ForeignKeyId1, ForeignKeyId2) REFERENCES [db2].[PrincipalTable](UC1 Assert.Equal("PrincipalTable", n.Name); Assert.False(n.IsCollection); }); - Assert.Collection(e.GetForeignKeys(), + Assert.Collection( + e.GetForeignKeys(), k => { Assert.Equal("PrincipalTable", k.PrincipalEntityType.Name); Assert.Equal("DependentTable", k.DeclaringEntityType.Name); - Assert.Collection(k.Properties, + Assert.Collection( + k.Properties, p => Assert.Equal("ForeignKeyId1", p.Name), p => Assert.Equal("ForeignKeyId2", p.Name)); - Assert.Collection(k.PrincipalKey.Properties, + Assert.Collection( + k.PrincipalKey.Properties, p => Assert.Equal("Uc1", p.Name), p => Assert.Equal("Uc2", p.Name)); Assert.False(k.IsUnique); @@ -1423,14 +1473,16 @@ FOREIGN KEY (ForeignKeyId1, ForeignKeyId2) REFERENCES [db2].[PrincipalTable](UC1 e.GetIndexes(), i => { - Assert.Collection(i.Properties, + Assert.Collection( + i.Properties, p => Assert.Equal("Index2", p.Name), p => Assert.Equal("Index1", p.Name)); Assert.False(i.IsUnique); }, i => { - Assert.Collection(i.Properties, + Assert.Collection( + i.Properties, p => Assert.Equal("Uc1", p.Name), p => Assert.Equal("Uc2", p.Name)); Assert.True(i.IsUnique); @@ -1576,7 +1628,7 @@ CONSTRAINT [PK_Blogs] PRIMARY KEY NONCLUSTERED ([Id]) // ReSharper disable once PossibleNullReferenceException Assert.True((bool)table[SqlServerAnnotationNames.MemoryOptimized]!); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, "DROP TABLE [Blogs]"); @@ -1594,7 +1646,8 @@ [UiText] NVARCHAR(1000) NOT NULL Enumerable.Empty(), (dbModel, scaffoldingFactory) => { - Assert.Collection(dbModel.Tables, + Assert.Collection( + dbModel.Tables, t => { Assert.Equal("UIText", t.Name); @@ -1604,9 +1657,10 @@ [UiText] NVARCHAR(1000) NOT NULL c => Assert.Equal("UiText", c.Name)); }); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); - Assert.Collection(model.GetEntityTypes(), + Assert.Collection( + model.GetEntityTypes(), e => { Assert.Equal("Uitext", e.Name); @@ -1657,7 +1711,7 @@ Name nvarchar(100) NOT NULL, Assert.Single(table.Columns.Where(c => c.Comment == "Blog.Id column comment.")); Assert.Single(table.Columns.Where(c => c.Comment != null)); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), @@ -1666,7 +1720,8 @@ Name nvarchar(100) NOT NULL, Assert.Equal("dbo", e.GetSchema()); Assert.Equal("Blog", e.Name); Assert.Equal("Blogs", e.GetTableName()); - Assert.Collection(e.GetProperties(), + Assert.Collection( + e.GetProperties(), p => Assert.Equal("Id", p.Name), p => Assert.Equal("Name", p.Name)); Assert.Empty(e.GetIndexes()); @@ -1704,7 +1759,7 @@ CREATE VIEW [dbo].[BlogsView] Assert.Single(table.Columns.Where(c => c.Name == "Id")); Assert.Single(table.Columns.Where(c => c.Name == "Name")); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), @@ -1713,7 +1768,8 @@ CREATE VIEW [dbo].[BlogsView] Assert.Equal("dbo", e.GetViewSchema()); Assert.Equal("BlogsView", e.Name); Assert.Equal("BlogsView", e.GetViewName()); - Assert.Collection(e.GetProperties(), + Assert.Collection( + e.GetProperties(), p => Assert.Equal("Id", p.Name), p => Assert.Equal("Name", p.Name)); Assert.Empty(e.GetIndexes()); @@ -1743,18 +1799,19 @@ Id int PRIMARY KEY Assert.Null(pk[SqlServerAnnotationNames.Clustered]); Assert.Equal(["Id"], pk.Columns.Select(ic => ic.Name).ToList()); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), e => { Assert.Equal("PrimaryKeyTable", e.Name); - Assert.Collection(e.GetProperties(), p => - { - Assert.Equal("Id", p.Name); - Assert.Equal(ValueGenerated.Never, p.ValueGenerated); - }); + Assert.Collection( + e.GetProperties(), p => + { + Assert.Equal("Id", p.Name); + Assert.Equal(ValueGenerated.Never, p.ValueGenerated); + }); Assert.Collection(e.GetKeys(), k => Assert.Equal("Id", k.Properties.Single().Name)); Assert.Empty(e.GetIndexes()); Assert.Empty(e.GetForeignKeys()); @@ -1788,14 +1845,15 @@ CREATE TABLE UniqueConstraint ( Assert.Null(uniqueConstraint[SqlServerAnnotationNames.Clustered]); Assert.Equal(["Name"], uniqueConstraint.Columns.Select(ic => ic.Name).ToList()); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), e => { Assert.Equal("UniqueConstraint", e.Name); - Assert.Collection(e.GetProperties(), + Assert.Collection( + e.GetProperties(), p => Assert.Equal("Id", p.Name), p => Assert.Equal("IndexProperty", p.Name), p => Assert.Equal("Name", p.Name)); @@ -1848,14 +1906,15 @@ CREATE TABLE IndexTable ( Assert.Single(table.Indexes.Where(c => c.Name == "IX_NAME")); Assert.Single(table.Indexes.Where(c => c.Name == "IX_INDEX")); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), e => { Assert.Equal("IndexTable", e.Name); - Assert.Collection(e.GetProperties(), + Assert.Collection( + e.GetProperties(), p => Assert.Equal("Id", p.Name), p => Assert.Equal("IndexProperty", p.Name), p => Assert.Equal("Name", p.Name)); @@ -1917,14 +1976,15 @@ IndexProperty int Assert.Equal(50, index[SqlServerAnnotationNames.FillFactor]); }); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), e => { Assert.Equal("IndexTable", e.Name); - Assert.Collection(e.GetProperties(), + Assert.Collection( + e.GetProperties(), p => Assert.Equal("Id", p.Name), p => Assert.Equal("IndexProperty", p.Name)); Assert.Empty(e.GetKeys()); @@ -1995,17 +2055,19 @@ FOREIGN KEY (Id) REFERENCES PrincipalTable(Id) ON DELETE NO ACTION, Assert.Equal(["Id"], secondFk.PrincipalColumns.Select(ic => ic.Name).ToList()); Assert.Equal(ReferentialAction.NoAction, secondFk.OnDelete); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), e => { Assert.Equal("FirstDependent", e.Name); - Assert.Collection(e.GetProperties(), + Assert.Collection( + e.GetProperties(), p => Assert.Equal("Id", p.Name), p => Assert.Equal("ForeignKeyId", p.Name)); - Assert.Collection(e.GetForeignKeys(), + Assert.Collection( + e.GetForeignKeys(), k => { Assert.Equal("PrincipalTable", k.PrincipalEntityType.Name); @@ -2023,7 +2085,8 @@ FOREIGN KEY (Id) REFERENCES PrincipalTable(Id) ON DELETE NO ACTION, Assert.Collection(e.GetProperties(), p => Assert.Equal("Id", p.Name)); Assert.Empty(e.GetForeignKeys()); Assert.Empty(e.GetSkipNavigations()); - Assert.Collection(e.GetNavigations(), + Assert.Collection( + e.GetNavigations(), n => { Assert.Equal("FirstDependents", n.Name); @@ -2039,7 +2102,8 @@ FOREIGN KEY (Id) REFERENCES PrincipalTable(Id) ON DELETE NO ACTION, { Assert.Equal("SecondDependent", e.Name); Assert.Collection(e.GetProperties(), p => Assert.Equal("Id", p.Name)); - Assert.Collection(e.GetForeignKeys(), + Assert.Collection( + e.GetForeignKeys(), k => { Assert.Equal("PrincipalTable", k.PrincipalEntityType.Name); @@ -2095,14 +2159,15 @@ AFTER INSERT AS t => Assert.Equal("Trigger1", t.Name), t => Assert.Equal("Trigger2", t.Name)); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), e => { Assert.Equal("SomeTable", e.Name); - Assert.Collection(e.GetProperties(), + Assert.Collection( + e.GetProperties(), p => Assert.Equal("Id", p.Name), p => Assert.Equal("Bar", p.Name), p => Assert.Equal("Baz", p.Name), @@ -2110,7 +2175,8 @@ AFTER INSERT AS Assert.Empty(e.GetForeignKeys()); Assert.Empty(e.GetSkipNavigations()); Assert.Empty(e.GetNavigations()); - Assert.Collection(e.GetDeclaredTriggers(), + Assert.Collection( + e.GetDeclaredTriggers(), t => Assert.Equal("Trigger1", t.ModelName), t => Assert.Equal("Trigger2", t.ModelName)); }); @@ -2128,8 +2194,14 @@ AFTER INSERT AS [InlineData("event", true, true, "_event", "Id", "_class", "strings", "_", "_1")] public void Table_name_with_pluralized_keywords( string tableName, - bool useDatabaseNames, bool singularize, - string entityTypeName, string idName, string className, string stringsName, string oneName, string plusName) + bool useDatabaseNames, + bool singularize, + string entityTypeName, + string idName, + string className, + string stringsName, + string oneName, + string plusName) => Test( @$" CREATE TABLE [{tableName}] ( @@ -2143,11 +2215,13 @@ public void Table_name_with_pluralized_keywords( Enumerable.Empty(), (dbModel, scaffoldingFactory) => { - Assert.Collection(dbModel.Tables, + Assert.Collection( + dbModel.Tables, t => { Assert.Equal(tableName, t.Name); - Assert.Collection(t.Columns, + Assert.Collection( + t.Columns, c => Assert.Equal("Id", c.Name), c => Assert.Equal("class", c.Name), c => Assert.Equal("strings", c.Name), @@ -2155,9 +2229,11 @@ public void Table_name_with_pluralized_keywords( c => Assert.Equal("+", c.Name)); }); - var model = scaffoldingFactory.Create(dbModel, new() { UseDatabaseNames = useDatabaseNames, NoPluralize = !singularize }); + var model = scaffoldingFactory.Create( + dbModel, new ModelReverseEngineerOptions { UseDatabaseNames = useDatabaseNames, NoPluralize = !singularize }); - Assert.Collection(model.GetEntityTypes(), + Assert.Collection( + model.GetEntityTypes(), e => { Assert.Equal(entityTypeName, e.Name); @@ -2199,14 +2275,15 @@ typeAliasColumn dbo.TestTypeAlias NULL // ReSharper disable once PossibleNullReferenceException Assert.Equal("nvarchar(max)", column.StoreType); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), e => { Assert.Equal("TypeAlias", e.Name); - Assert.Collection(e.GetProperties(), + Assert.Collection( + e.GetProperties(), p => Assert.Equal("Id", p.Name), p => { @@ -2242,14 +2319,15 @@ typeAliasColumn sysname Assert.Equal("nvarchar(128)", column.StoreType); Assert.False(column.IsNullable); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), e => { Assert.Equal("TypeAlias", e.Name); - Assert.Collection(e.GetProperties(), + Assert.Collection( + e.GetProperties(), p => Assert.Equal("Id", p.Name), p => { @@ -2292,7 +2370,7 @@ numericDefaultPrecisionColumn numeric(38, 5) NOT NULL, Assert.Equal("numeric(18, 2)", columns.Single(c => c.Name == "numericDefaultColumn").StoreType); Assert.Equal("numeric(38, 5)", columns.Single(c => c.Name == "numericDefaultPrecisionColumn").StoreType); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), @@ -2388,7 +2466,7 @@ nationalCharacterVaryingMaxColumn national char varying(max) NULL Assert.Equal("nvarchar(max)", columns.Single(c => c.Name == "nationalCharVaryingMaxColumn").StoreType); Assert.Equal("nvarchar(max)", columns.Single(c => c.Name == "nationalCharacterVaryingMaxColumn").StoreType); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), @@ -2453,6 +2531,46 @@ nationalCharacterVaryingMaxColumn national char varying(max) NULL }, "DROP TABLE MaxColumns;"); + [SqlServerCondition(SqlServerCondition.SupportsJsonType)] + [ConditionalFact] + public void Handles_native_JSON_type() + => Test( + @" +CREATE TABLE JsonColumns ( + Id int, + jsonTypeColumn json NULL +);", + Enumerable.Empty(), + Enumerable.Empty(), + (dbModel, scaffoldingFactory) => + { + var columns = dbModel.Tables.Single().Columns; + + Assert.Equal("json", columns.Single(c => c.Name == "jsonTypeColumn").StoreType); + + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); + + Assert.Collection( + model.GetEntityTypes(), + e => + { + Assert.Equal("JsonColumn", e.Name); + Assert.Collection( + e.GetProperties(), + p => Assert.Equal("Id", p.Name), + p => + { + Assert.Equal("JsonTypeColumn", p.Name); + Assert.Same(typeof(string), p.ClrType); + Assert.Null(p.GetMaxLength()); + }); + Assert.Empty(e.GetForeignKeys()); + Assert.Empty(e.GetSkipNavigations()); + Assert.Empty(e.GetNavigations()); + }); + }, + "DROP TABLE JsonColumns;"); + [ConditionalFact] public void Specific_max_length_are_add_to_store_type() => Test( @@ -2493,7 +2611,7 @@ nationalCharacterVarying188Column national char varying(188) NULL, Assert.Equal("nvarchar(177)", columns.Single(c => c.Name == "nationalCharVarying177Column").StoreType); Assert.Equal("nvarchar(188)", columns.Single(c => c.Name == "nationalCharacterVarying188Column").StoreType); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), @@ -2631,7 +2749,7 @@ varbinaryColumn varbinary(8000) Assert.Equal("varbinary(8000)", columns.Single(c => c.Name == "binaryVaryingColumn").StoreType); Assert.Equal("varbinary(8000)", columns.Single(c => c.Name == "varbinaryColumn").StoreType); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), @@ -2686,7 +2804,7 @@ charColumn char(8000) Assert.Equal("char(8000)", columns.Single(c => c.Name == "charColumn").StoreType); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), @@ -2727,7 +2845,7 @@ characterColumn character(8000) Assert.Equal("char(8000)", columns.Single(c => c.Name == "characterColumn").StoreType); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), @@ -2772,7 +2890,7 @@ varcharColumn varchar(8000) Assert.Equal("varchar(8000)", columns.Single(c => c.Name == "characterVaryingColumn").StoreType); Assert.Equal("varchar(8000)", columns.Single(c => c.Name == "varcharColumn").StoreType); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), @@ -2829,7 +2947,7 @@ nationalCharColumn national char(4000), Assert.Equal("nchar(4000)", columns.Single(c => c.Name == "nationalCharColumn").StoreType); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), @@ -2870,7 +2988,7 @@ nationalCharacterColumn national character(4000), Assert.Equal("nchar(4000)", columns.Single(c => c.Name == "nationalCharacterColumn").StoreType); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), @@ -2911,7 +3029,7 @@ ncharColumn nchar(4000), Assert.Equal("nchar(4000)", columns.Single(c => c.Name == "ncharColumn").StoreType); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), @@ -2956,7 +3074,7 @@ nvarcharColumn nvarchar(4000) Assert.Equal("nvarchar(4000)", columns.Single(c => c.Name == "nationalCharacterVaryingColumn").StoreType); Assert.Equal("nvarchar(4000)", columns.Single(c => c.Name == "nvarcharColumn").StoreType); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), @@ -3017,7 +3135,7 @@ datetimeoffset5Column datetimeoffset(5) NULL, Assert.Equal("datetime2(4)", columns.Single(c => c.Name == "datetime24Column").StoreType); Assert.Equal("datetimeoffset(5)", columns.Single(c => c.Name == "datetimeoffset5Column").StoreType); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), @@ -3097,7 +3215,7 @@ CREATE TABLE OneLengthColumns ( Assert.Equal("varbinary(1)", columns.Single(c => c.Name == "varbinaryColumn").StoreType); Assert.Equal("varchar(1)", columns.Single(c => c.Name == "varcharColumn").StoreType); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), @@ -3270,7 +3388,7 @@ CREATE TABLE RowversionType ( "rowversion", dbModel.Tables.Single(t => t.Name == "RowversionType").Columns.Single(c => c.Name == "rowversionColumn").StoreType); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), @@ -3453,7 +3571,7 @@ ComputedValue AS GETDATE(), Assert.Equal("([A]+[B])", sumOfAAndBPersisted.ComputedColumnSql); Assert.True(sumOfAAndBPersisted.IsStored); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), @@ -3535,7 +3653,7 @@ B bit DEFAULT ((CONVERT([bit],(CHOOSE(1, 0, 1, 2))))), Assert.Equal("(CONVERT([bit],choose((1),(0),(1),(2))))", column.DefaultValueSql); Assert.Null(column.FindAnnotation(RelationalAnnotationNames.DefaultValue)); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, "DROP TABLE MyTable;"); @@ -3603,9 +3721,8 @@ J int DEFAULT ( ( CONVERT([int],((-8))))), Assert.Equal("(CONVERT([int],(-8)))", column.DefaultValueSql); Assert.Equal(-8, column.DefaultValue); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); - }, "DROP TABLE MyTable;"); @@ -3637,7 +3754,7 @@ C smallint DEFAULT ((CONVERT ( ""smallint"", ( (-7) ) ))), Assert.Equal("(CONVERT([smallint],(-7)))", column.DefaultValueSql); Assert.Equal((short)-7, column.DefaultValue); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, "DROP TABLE MyTable;"); @@ -3670,9 +3787,8 @@ C bigint DEFAULT ((CONVERT ( ""bigint"", ( (-7) ) ))), Assert.Equal("(CONVERT([bigint],(-7)))", column.DefaultValueSql); Assert.Equal((long)-7, column.DefaultValue); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); - }, "DROP TABLE MyTable;"); @@ -3704,7 +3820,7 @@ C tinyint DEFAULT ((CONVERT ( ""tinyint"", ( (7) ) ))), Assert.Equal("(CONVERT([tinyint],(7)))", column.DefaultValueSql); Assert.Equal((byte)7, column.DefaultValue); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, "DROP TABLE MyTable;"); @@ -3732,7 +3848,7 @@ B int DEFAULT ((CONVERT([int],(CHOOSE(1, 0, 1, 2))))), Assert.Equal("(CONVERT([int],choose((1),(0),(1),(2))))", column.DefaultValueSql); Assert.Null(column.FindAnnotation(RelationalAnnotationNames.DefaultValue)); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, "DROP TABLE MyTable;"); @@ -3770,7 +3886,7 @@ D float DEFAULT ((CONVERT ( ""float"", ( (1.1234) ) ))), Assert.Equal("(CONVERT([float],(1.1234)))", column.DefaultValueSql); Assert.Equal(1.1234, column.DefaultValue); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, "DROP TABLE MyTable;"); @@ -3808,7 +3924,7 @@ D real DEFAULT ((CONVERT ( ""real"", ( (1.1234) ) ))), Assert.Equal("(CONVERT([real],(1.1234)))", column.DefaultValueSql); Assert.Equal((float)1.1234, column.DefaultValue); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, "DROP TABLE MyTable;"); @@ -3846,7 +3962,7 @@ D decimal DEFAULT ((CONVERT ( ""decimal"", ( (1.1234) ) ))), Assert.Equal("(CONVERT([decimal],(1.1234)))", column.DefaultValueSql); Assert.Equal((decimal)1.1234, column.DefaultValue); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, "DROP TABLE MyTable;"); @@ -3899,7 +4015,7 @@ G bit DEFAULT ((CONVERT ( ""bit"", ( ('tRUE') ) ))), Assert.Equal("(CONVERT([bit],'tRUE'))", column.DefaultValueSql); Assert.Equal(true, column.DefaultValue); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, "DROP TABLE MyTable;"); @@ -3939,7 +4055,7 @@ D datetime DEFAULT (CONVERT(datetime,'12:12:12')), Assert.Equal(12, ((DateTime)column.DefaultValue!).Minute); Assert.Equal(12, ((DateTime)column.DefaultValue!).Second); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, "DROP TABLE MyTable;"); @@ -3972,7 +4088,7 @@ C datetime2 DEFAULT ((CONVERT([datetime2],('12-01-16 12:32')))), Assert.Equal("(CONVERT([datetime2],'12-01-16 12:32'))", column.DefaultValueSql); Assert.Null(column.FindAnnotation(RelationalAnnotationNames.DefaultValue)); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, "DROP TABLE MyTable;"); @@ -4000,7 +4116,7 @@ B date DEFAULT (CONVERT([date],('1973-09-03T01:02:03'))), Assert.Equal("(CONVERT([date],'1973-09-03T01:02:03'))", column.DefaultValueSql); Assert.Equal(new DateOnly(1973, 9, 3), column.DefaultValue); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, "DROP TABLE MyTable;"); @@ -4028,7 +4144,7 @@ B time DEFAULT (CONVERT([time],('1973-09-03T01:02:03'))), Assert.Equal("(CONVERT([time],'1973-09-03T01:02:03'))", column.DefaultValueSql); Assert.Equal(new TimeOnly(1, 2, 3), column.DefaultValue); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, "DROP TABLE MyTable;"); @@ -4060,7 +4176,7 @@ B datetimeoffset DEFAULT (CONVERT([datetimeoffset],('1973-09-03T01:02:03'))), new DateTime(1973, 9, 3, 1, 2, 3, 0, DateTimeKind.Unspecified), ((DateTimeOffset)column.DefaultValue!).DateTime); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, "DROP TABLE MyTable;"); @@ -4088,7 +4204,7 @@ B uniqueidentifier DEFAULT (CONVERT([uniqueidentifier],('0E984725-C51C-4BF4-9960 Assert.Equal("(CONVERT([uniqueidentifier],'0E984725-C51C-4BF4-9960-E1C80E27ABA0'))", column.DefaultValueSql); Assert.Equal(new Guid("0E984725-C51C-4BF4-9960-E1C80E27ABA0"), column.DefaultValue); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, "DROP TABLE MyTable;"); @@ -4116,7 +4232,7 @@ B uniqueidentifier DEFAULT NEWSEQUENTIALID(), Assert.Equal("(newsequentialid())", column.DefaultValueSql); Assert.Null(column.FindAnnotation(RelationalAnnotationNames.DefaultValue)); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, "DROP TABLE MyTable;"); @@ -4169,7 +4285,7 @@ G varchar(max) DEFAULT (CONVERT(character varying(max),('Toasted teacakes'))), Assert.Equal("(CONVERT([varchar](max),'Toasted teacakes'))", column.DefaultValueSql); Assert.Equal("Toasted teacakes", column.DefaultValue); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, "DROP TABLE MyTable;"); @@ -4197,7 +4313,7 @@ ComputedValue AS GETDATE(), Assert.Null(columns.Single(c => c.Name == "ComputedValue").ValueGenerated); Assert.Equal(ValueGenerated.OnAddOrUpdate, columns.Single(c => c.Name == "rowversionColumn").ValueGenerated); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), @@ -4257,7 +4373,7 @@ CREATE TABLE RowVersionTable ( Assert.True((bool)columns.Single(c => c.Name == "rowversionColumn")[ScaffoldingAnnotationNames.ConcurrencyToken]!); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), @@ -4282,7 +4398,6 @@ CREATE TABLE RowVersionTable ( Assert.Empty(e.GetNavigations()); Assert.Empty(e.GetSkipNavigations()); }); - }, "DROP TABLE RowVersionTable;"); @@ -4304,7 +4419,7 @@ NonNullString nvarchar(max) NOT NULL, Assert.True(columns.Single(c => c.Name == "NullableInt").IsNullable); Assert.False(columns.Single(c => c.Name == "NonNullString").IsNullable); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), @@ -4355,7 +4470,7 @@ NonDefaultCollation nvarchar(max) COLLATE German_PhoneBook_CI_AS, Assert.Null(columns.Single(c => c.Name == "DefaultCollation").Collation); Assert.Equal("German_PhoneBook_CI_AS", columns.Single(c => c.Name == "NonDefaultCollation").Collation); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), @@ -4406,7 +4521,7 @@ NonSparse nvarchar(max) NULL Assert.True((bool)columns.Single(c => c.Name == "Sparse")[SqlServerAnnotationNames.Sparse]!); Assert.Null(columns.Single(c => c.Name == "NonSparse")[SqlServerAnnotationNames.Sparse]); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), @@ -4468,7 +4583,7 @@ PERIOD FOR SYSTEM_TIME(SysStartTime, SysEndTime) Assert.DoesNotContain(columns, c => c.Name == "SysEndTime"); Assert.Equal("IX_HiddenColumnsTable_3", dbModel.Tables.Single().Indexes.Single().Name); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), @@ -4533,7 +4648,7 @@ PERIOD FOR SYSTEM_TIME(SysStartTime, SysEndTime) Assert.DoesNotContain(columns, c => c.Name == "SysEndTime"); Assert.Equal("IX_HiddenColumnsTable_3", dbModel.Tables.Single().Indexes.Single().Name); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), @@ -4593,7 +4708,7 @@ PRIMARY KEY (Id2, Id1) Assert.StartsWith("PK__Composit", pk.Name); Assert.Equal(["Id2", "Id1"], pk.Columns.Select(ic => ic.Name).ToList()); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), @@ -4601,9 +4716,11 @@ PRIMARY KEY (Id2, Id1) { Assert.Equal("dbo", e.GetSchema()); Assert.Equal("CompositePrimaryKeyTable", e.Name); - Assert.Collection(e.GetKeys(), k => Assert.Collection(k.Properties, - p => Assert.Equal("Id2", p.Name), - p => Assert.Equal("Id1", p.Name))); + Assert.Collection( + e.GetKeys(), k => Assert.Collection( + k.Properties, + p => Assert.Equal("Id2", p.Name), + p => Assert.Equal("Id1", p.Name))); Assert.Collection( e.GetProperties(), p => @@ -4646,7 +4763,7 @@ CREATE TABLE NonClusteredPrimaryKeyTable ( Assert.False((bool)pk[SqlServerAnnotationNames.Clustered]!); Assert.Equal(["Id1"], pk.Columns.Select(ic => ic.Name).ToList()); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), @@ -4654,11 +4771,12 @@ CREATE TABLE NonClusteredPrimaryKeyTable ( { Assert.Equal("dbo", e.GetSchema()); Assert.Equal("NonClusteredPrimaryKeyTable", e.Name); - Assert.Collection(e.GetKeys(), k => - { - Assert.False(k.IsClustered()); - Assert.Collection(k.Properties, p => Assert.Equal("Id1", p.Name)); - }); + Assert.Collection( + e.GetKeys(), k => + { + Assert.False(k.IsClustered()); + Assert.Collection(k.Properties, p => Assert.Equal("Id1", p.Name)); + }); Assert.Collection(e.GetProperties(), p => Assert.Equal("Id1", p.Name), p => Assert.Equal("Id2", p.Name)); Assert.Empty(e.GetForeignKeys()); Assert.Empty(e.GetIndexes()); @@ -4690,7 +4808,7 @@ CREATE TABLE NonClusteredPrimaryKeyTableWithClusteredIndex ( Assert.False((bool)pk[SqlServerAnnotationNames.Clustered]!); Assert.Equal(["Id1"], pk.Columns.Select(ic => ic.Name).ToList()); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, "DROP TABLE NonClusteredPrimaryKeyTableWithClusteredIndex;"); @@ -4716,7 +4834,7 @@ CONSTRAINT UK_Clustered UNIQUE CLUSTERED ( Id2 ), Assert.False((bool)pk[SqlServerAnnotationNames.Clustered]!); Assert.Equal(["Id1"], pk.Columns.Select(ic => ic.Name).ToList()); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, "DROP TABLE NonClusteredPrimaryKeyTableWithClusteredConstraint;"); @@ -4742,7 +4860,7 @@ CONSTRAINT MyPK PRIMARY KEY ( Id2 ), Assert.Null(pk[SqlServerAnnotationNames.Clustered]); Assert.Equal(["Id2"], pk.Columns.Select(ic => ic.Name).ToList()); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, "DROP TABLE PrimaryKeyName;"); @@ -4769,7 +4887,7 @@ [Id] ASC Assert.Equal(["Id"], pk!.Columns.Select(kc => kc.Name).ToList()); Assert.Equal(80, pk[SqlServerAnnotationNames.FillFactor]); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, "DROP TABLE PrimaryKeyFillFactor;"); @@ -4799,7 +4917,7 @@ CONSTRAINT UX UNIQUE (Id2, Id1) Assert.Equal("UX", uniqueConstraint.Name); Assert.Equal(["Id2", "Id1"], uniqueConstraint.Columns.Select(ic => ic.Name).ToList()); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, "DROP TABLE CompositeUniqueConstraintTable;"); @@ -4825,7 +4943,7 @@ CREATE TABLE ClusteredUniqueConstraintTable ( Assert.True((bool)uniqueConstraint[SqlServerAnnotationNames.Clustered]!); Assert.Equal(["Id2"], uniqueConstraint.Columns.Select(ic => ic.Name).ToList()); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, "DROP TABLE ClusteredUniqueConstraintTable;"); @@ -4851,7 +4969,7 @@ CONSTRAINT MyUC UNIQUE ( Id2 ), Assert.Equal("MyUC", uniqueConstraint.Name); Assert.Equal(["Id2"], uniqueConstraint.Columns.Select(ic => ic.Name).ToList()); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, "DROP TABLE UniqueConstraintName;"); @@ -4879,7 +4997,7 @@ [SomethingElse] ASC Assert.Equal(["Something", "SomethingElse"], uniqueConstraint!.Columns.Select(kc => kc.Name).ToList()); Assert.Equal(80, uniqueConstraint[SqlServerAnnotationNames.FillFactor]); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, "DROP TABLE UniqueConstraintFillFactor;"); @@ -4910,7 +5028,7 @@ CREATE TABLE CompositeIndexTable ( Assert.Equal("IX_COMPOSITE", index.Name); Assert.Equal(["Id2", "Id1"], index.Columns.Select(ic => ic.Name).ToList()); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), @@ -4921,14 +5039,15 @@ CREATE TABLE CompositeIndexTable ( Assert.Empty(e.GetKeys()); Assert.Collection(e.GetProperties(), p => Assert.Equal("Id1", p.Name), p => Assert.Equal("Id2", p.Name)); Assert.Empty(e.GetForeignKeys()); - Assert.Collection(e.GetIndexes(), k => - { - Assert.Collection( - k.Properties, - p => Assert.Equal("Id2", p.Name), - p => Assert.Equal("Id1", p.Name)); - Assert.False(k.IsUnique); - }); + Assert.Collection( + e.GetIndexes(), k => + { + Assert.Collection( + k.Properties, + p => Assert.Equal("Id2", p.Name), + p => Assert.Equal("Id1", p.Name)); + Assert.False(k.IsUnique); + }); Assert.Empty(e.GetNavigations()); Assert.Empty(e.GetSkipNavigations()); }); @@ -4958,7 +5077,7 @@ CREATE TABLE ClusteredIndexTable ( Assert.True((bool)index[SqlServerAnnotationNames.Clustered]!); Assert.Equal(["Id2"], index.Columns.Select(ic => ic.Name).ToList()); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, "DROP TABLE ClusteredIndexTable;"); @@ -4987,7 +5106,7 @@ CREATE TABLE UniqueIndexTable ( Assert.Null(index.Filter); Assert.Equal(["Id2"], index.Columns.Select(ic => ic.Name).ToList()); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, "DROP TABLE UniqueIndexTable;"); @@ -5015,7 +5134,7 @@ CREATE TABLE FilteredIndexTable ( Assert.Equal("([Id2]>(10))", index.Filter); Assert.Equal(["Id2"], index.Columns.Select(ic => ic.Name).ToList()); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, "DROP TABLE FilteredIndexTable;"); @@ -5036,12 +5155,13 @@ CREATE TABLE HypotheticalIndexTable ( { Assert.Empty(dbModel.Tables.Single().Indexes); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, "DROP TABLE HypotheticalIndexTable;"); [ConditionalFact] + [SqlServerCondition(SqlServerCondition.IsNotAzureSql)] public void Ignore_columnstore_index() => Test( @" @@ -5057,7 +5177,7 @@ CREATE NONCLUSTERED COLUMNSTORE INDEX ixColumnStore ON ColumnStoreIndexTable ( I { Assert.Empty(dbModel.Tables.Single().Indexes); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, "DROP TABLE ColumnStoreIndexTable;"); @@ -5081,7 +5201,7 @@ IncludeProperty int Assert.Equal(new[] { "IndexProperty" }, index.Columns.Select(ic => ic.Name).ToList()); Assert.Null(index[SqlServerAnnotationNames.Include]); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, "DROP TABLE IncludeIndexTable;"); @@ -5109,7 +5229,7 @@ [Name] ASC Assert.Equal(new[] { "Name" }, index.Columns.Select(ic => ic.Name).ToList()); Assert.Equal(80, index[SqlServerAnnotationNames.FillFactor]); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, "DROP TABLE IndexFillFactor;"); @@ -5149,54 +5269,63 @@ FOREIGN KEY (ForeignKeyId1, ForeignKeyId2) REFERENCES PrincipalTable(Id1, Id2) O Assert.Equal(["Id1", "Id2"], fk.PrincipalColumns.Select(ic => ic.Name).ToList()); Assert.Equal(ReferentialAction.Cascade, fk.OnDelete); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), e => { Assert.Equal("DependentTable", e.Name); - Assert.Collection(e.GetProperties(), + Assert.Collection( + e.GetProperties(), p => Assert.Equal("Id", p.Name), p => Assert.Equal("ForeignKeyId1", p.Name), p => Assert.Equal("ForeignKeyId2", p.Name)); Assert.Collection(e.GetKeys(), k => Assert.Equal("Id", k.Properties.Single().Name)); - Assert.Collection(e.GetForeignKeys(), + Assert.Collection( + e.GetForeignKeys(), k => { Assert.Equal("PrincipalTable", k.PrincipalEntityType.Name); Assert.Equal("DependentTable", k.DeclaringEntityType.Name); - Assert.Collection(k.Properties, + Assert.Collection( + k.Properties, p => Assert.Equal("ForeignKeyId1", p.Name), p => Assert.Equal("ForeignKeyId2", p.Name)); - Assert.Collection(k.PrincipalKey.Properties, + Assert.Collection( + k.PrincipalKey.Properties, p => Assert.Equal("Id1", p.Name), p => Assert.Equal("Id2", p.Name)); Assert.False(k.IsUnique); }); Assert.Empty(e.GetSkipNavigations()); - Assert.Collection(e.GetNavigations(), n => - { - Assert.Equal("PrincipalTable", n.Name); - Assert.False(n.IsCollection); - }); + Assert.Collection( + e.GetNavigations(), n => + { + Assert.Equal("PrincipalTable", n.Name); + Assert.False(n.IsCollection); + }); }, e => { Assert.Equal("PrincipalTable", e.Name); - Assert.Collection(e.GetProperties(), + Assert.Collection( + e.GetProperties(), p => Assert.Equal("Id1", p.Name), p => Assert.Equal("Id2", p.Name)); - Assert.Collection(e.GetKeys(), k => Assert.Collection(k.Properties, - p => Assert.Equal("Id1", p.Name), - p => Assert.Equal("Id2", p.Name))); + Assert.Collection( + e.GetKeys(), k => Assert.Collection( + k.Properties, + p => Assert.Equal("Id1", p.Name), + p => Assert.Equal("Id2", p.Name))); Assert.Empty(e.GetForeignKeys()); Assert.Empty(e.GetSkipNavigations()); - Assert.Collection(e.GetNavigations(), n => - { - Assert.Equal("DependentTables", n.Name); - Assert.True(n.IsCollection); - }); + Assert.Collection( + e.GetNavigations(), n => + { + Assert.Equal("DependentTables", n.Name); + Assert.True(n.IsCollection); + }); }); }, @" @@ -5252,7 +5381,7 @@ FOREIGN KEY (ForeignKeyId2) REFERENCES AnotherPrincipalTable(Id) ON DELETE CASCA Assert.Equal(["Id"], anotherPrincipalFk.PrincipalColumns.Select(ic => ic.Name).ToList()); Assert.Equal(ReferentialAction.Cascade, anotherPrincipalFk.OnDelete); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), @@ -5263,21 +5392,24 @@ FOREIGN KEY (ForeignKeyId2) REFERENCES AnotherPrincipalTable(Id) ON DELETE CASCA Assert.Collection(e.GetKeys(), k => Assert.Collection(k.Properties, p => Assert.Equal("Id", p.Name))); Assert.Empty(e.GetForeignKeys()); Assert.Empty(e.GetSkipNavigations()); - Assert.Collection(e.GetNavigations(), n => - { - Assert.Equal("DependentTables", n.Name); - Assert.True(n.IsCollection); - }); + Assert.Collection( + e.GetNavigations(), n => + { + Assert.Equal("DependentTables", n.Name); + Assert.True(n.IsCollection); + }); }, e => { Assert.Equal("DependentTable", e.Name); - Assert.Collection(e.GetProperties(), + Assert.Collection( + e.GetProperties(), p => Assert.Equal("Id", p.Name), p => Assert.Equal("ForeignKeyId1", p.Name), p => Assert.Equal("ForeignKeyId2", p.Name)); Assert.Collection(e.GetKeys(), k => Assert.Equal("Id", k.Properties.Single().Name)); - Assert.Collection(e.GetForeignKeys(), + Assert.Collection( + e.GetForeignKeys(), k => { Assert.Equal("PrincipalTable", k.PrincipalEntityType.Name); @@ -5295,15 +5427,16 @@ FOREIGN KEY (ForeignKeyId2) REFERENCES AnotherPrincipalTable(Id) ON DELETE CASCA Assert.False(k.IsUnique); }); Assert.Empty(e.GetSkipNavigations()); - Assert.Collection(e.GetNavigations(), n => - { - Assert.Equal("ForeignKeyId1Navigation", n.Name); - Assert.False(n.IsCollection); - }, n => - { - Assert.Equal("ForeignKeyId2Navigation", n.Name); - Assert.False(n.IsCollection); - }); + Assert.Collection( + e.GetNavigations(), n => + { + Assert.Equal("ForeignKeyId1Navigation", n.Name); + Assert.False(n.IsCollection); + }, n => + { + Assert.Equal("ForeignKeyId2Navigation", n.Name); + Assert.False(n.IsCollection); + }); }, e => { @@ -5312,11 +5445,12 @@ FOREIGN KEY (ForeignKeyId2) REFERENCES AnotherPrincipalTable(Id) ON DELETE CASCA Assert.Collection(e.GetKeys(), k => Assert.Collection(k.Properties, p => Assert.Equal("Id", p.Name))); Assert.Empty(e.GetForeignKeys()); Assert.Empty(e.GetSkipNavigations()); - Assert.Collection(e.GetNavigations(), n => - { - Assert.Equal("DependentTables", n.Name); - Assert.True(n.IsCollection); - }); + Assert.Collection( + e.GetNavigations(), n => + { + Assert.Equal("DependentTables", n.Name); + Assert.True(n.IsCollection); + }); }); }, @" @@ -5353,18 +5487,20 @@ FOREIGN KEY (ForeignKeyId) REFERENCES PrincipalTable(Id2) ON DELETE CASCADE, Assert.Equal(["Id2"], fk.PrincipalColumns.Select(ic => ic.Name).ToList()); Assert.Equal(ReferentialAction.Cascade, fk.OnDelete); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), e => { Assert.Equal("DependentTable", e.Name); - Assert.Collection(e.GetProperties(), + Assert.Collection( + e.GetProperties(), p => Assert.Equal("Id", p.Name), p => Assert.Equal("ForeignKeyId", p.Name)); Assert.Collection(e.GetKeys(), k => Assert.Equal("Id", k.Properties.Single().Name)); - Assert.Collection(e.GetForeignKeys(), + Assert.Collection( + e.GetForeignKeys(), k => { Assert.Equal("PrincipalTable", k.PrincipalEntityType.Name); @@ -5374,34 +5510,39 @@ FOREIGN KEY (ForeignKeyId) REFERENCES PrincipalTable(Id2) ON DELETE CASCADE, Assert.False(k.IsUnique); }); Assert.Empty(e.GetSkipNavigations()); - Assert.Collection(e.GetNavigations(), n => - { - Assert.Equal("ForeignKey", n.Name); - Assert.False(n.IsCollection); - }); + Assert.Collection( + e.GetNavigations(), n => + { + Assert.Equal("ForeignKey", n.Name); + Assert.False(n.IsCollection); + }); }, e => { Assert.Equal("PrincipalTable", e.Name); Assert.Collection(e.GetProperties(), p => Assert.Equal("Id1", p.Name), p => Assert.Equal("Id2", p.Name)); - Assert.Collection(e.GetKeys(), - k => Assert.Collection(k.Properties, p => - { - Assert.Equal("Id1", p.Name); - Assert.True(p.IsPrimaryKey()); - }), - k => Assert.Collection(k.Properties, p => - { - Assert.Equal("Id2", p.Name); - Assert.False(p.IsPrimaryKey()); - })); + Assert.Collection( + e.GetKeys(), + k => Assert.Collection( + k.Properties, p => + { + Assert.Equal("Id1", p.Name); + Assert.True(p.IsPrimaryKey()); + }), + k => Assert.Collection( + k.Properties, p => + { + Assert.Equal("Id2", p.Name); + Assert.False(p.IsPrimaryKey()); + })); Assert.Empty(e.GetForeignKeys()); Assert.Empty(e.GetSkipNavigations()); - Assert.Collection(e.GetNavigations(), n => - { - Assert.Equal("DependentTables", n.Name); - Assert.True(n.IsCollection); - }); + Assert.Collection( + e.GetNavigations(), n => + { + Assert.Equal("DependentTables", n.Name); + Assert.True(n.IsCollection); + }); }); }, @" @@ -5437,7 +5578,7 @@ CONSTRAINT MYFK FOREIGN KEY (ForeignKeyId) REFERENCES PrincipalTable(Id) ON DELE Assert.Equal(ReferentialAction.Cascade, fk.OnDelete); Assert.Equal("MYFK", fk.Name); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(2, model.GetEntityTypes().Count()); }, @" @@ -5472,18 +5613,20 @@ FOREIGN KEY (ForeignKeyId) REFERENCES PrincipalTable(Id) ON DELETE SET NULL, Assert.Equal(["Id"], fk.PrincipalColumns.Select(ic => ic.Name).ToList()); Assert.Equal(ReferentialAction.SetNull, fk.OnDelete); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Collection( model.GetEntityTypes(), e => { Assert.Equal("DependentTable", e.Name); - Assert.Collection(e.GetProperties(), + Assert.Collection( + e.GetProperties(), p => Assert.Equal("Id", p.Name), p => Assert.Equal("ForeignKeyId", p.Name)); Assert.Collection(e.GetKeys(), k => Assert.Equal("Id", k.Properties.Single().Name)); - Assert.Collection(e.GetForeignKeys(), + Assert.Collection( + e.GetForeignKeys(), k => { Assert.Equal("PrincipalTable", k.PrincipalEntityType.Name); @@ -5494,11 +5637,12 @@ FOREIGN KEY (ForeignKeyId) REFERENCES PrincipalTable(Id) ON DELETE SET NULL, Assert.False(k.IsUnique); }); Assert.Empty(e.GetSkipNavigations()); - Assert.Collection(e.GetNavigations(), n => - { - Assert.Equal("ForeignKey", n.Name); - Assert.False(n.IsCollection); - }); + Assert.Collection( + e.GetNavigations(), n => + { + Assert.Equal("ForeignKey", n.Name); + Assert.False(n.IsCollection); + }); }, e => { @@ -5507,11 +5651,12 @@ FOREIGN KEY (ForeignKeyId) REFERENCES PrincipalTable(Id) ON DELETE SET NULL, Assert.Collection(e.GetKeys(), k => Assert.Collection(k.Properties, p => Assert.Equal("Id", p.Name))); Assert.Empty(e.GetForeignKeys()); Assert.Empty(e.GetSkipNavigations()); - Assert.Collection(e.GetNavigations(), n => - { - Assert.Equal("DependentTables", n.Name); - Assert.True(n.IsCollection); - }); + Assert.Collection( + e.GetNavigations(), n => + { + Assert.Equal("DependentTables", n.Name); + Assert.True(n.IsCollection); + }); }); }, @" @@ -5541,7 +5686,7 @@ CREATE TABLE Blank ( SqlServerResources.LogMissingSchema(new TestLogger()).GenerateMessage("MySchema"), message); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Empty(model.GetEntityTypes()); }, "DROP TABLE Blank;"); @@ -5565,7 +5710,7 @@ CREATE TABLE Blank ( SqlServerResources.LogMissingTable(new TestLogger()).GenerateMessage("MyTable"), message); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Empty(model.GetEntityTypes()); }, "DROP TABLE Blank;"); @@ -5594,7 +5739,7 @@ CONSTRAINT MYFK FOREIGN KEY (ForeignKeyId) REFERENCES PrincipalTable(Id) ON DELE .GenerateMessage( "MYFK", "dbo.DependentTable", "dbo.PrincipalTable"), message); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, @" @@ -5624,7 +5769,7 @@ CONSTRAINT MYFK FOREIGN KEY (Id) REFERENCES PrincipalTable(Id) var table = Assert.Single(dbModel.Tables); Assert.Empty(table.ForeignKeys); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, @" @@ -5670,7 +5815,7 @@ CONSTRAINT MYFK5 FOREIGN KEY (ValueKey) REFERENCES PrincipalTable(Value2), var table = dbModel.Tables.Single(t => t.Name == "DependentTable"); Assert.Equal(4, table.ForeignKeys.Count); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(3, model.GetEntityTypes().Count()); }, @" @@ -5696,7 +5841,7 @@ public void No_warning_missing_view_definition() Assert.Null(message); - var model = scaffoldingFactory.Create(dbModel, new()); + var model = scaffoldingFactory.Create(dbModel, new ModelReverseEngineerOptions()); Assert.Equal(1, model.GetEntityTypes().Count()); }, @" diff --git a/test/EFCore.SqlServer.FunctionalTests/SequenceEndToEndTest.cs b/test/EFCore.SqlServer.FunctionalTests/SequenceEndToEndTest.cs index c27a01857bc..a04349cb6d8 100644 --- a/test/EFCore.SqlServer.FunctionalTests/SequenceEndToEndTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/SequenceEndToEndTest.cs @@ -408,9 +408,6 @@ private class Unicon public async Task InitializeAsync() => TestStore = await SqlServerTestStore.CreateInitializedAsync("SequenceEndToEndTest"); - public Task DisposeAsync() - { - TestStore.Dispose(); - return Task.CompletedTask; - } + public async Task DisposeAsync() + => await TestStore.DisposeAsync(); } diff --git a/test/EFCore.SqlServer.FunctionalTests/SequentialGuidEndToEndTest.cs b/test/EFCore.SqlServer.FunctionalTests/SequentialGuidEndToEndTest.cs index ab5b04f98ce..5fd9caec040 100644 --- a/test/EFCore.SqlServer.FunctionalTests/SequentialGuidEndToEndTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/SequentialGuidEndToEndTest.cs @@ -106,9 +106,6 @@ private class Pegasus public async Task InitializeAsync() => TestStore = await SqlServerTestStore.CreateInitializedAsync("SequentialGuidEndToEndTest"); - public Task DisposeAsync() - { - TestStore.Dispose(); - return Task.CompletedTask; - } + public async Task DisposeAsync() + => await TestStore.DisposeAsync(); } diff --git a/test/EFCore.SqlServer.FunctionalTests/SqlAzure/Model/Address.cs b/test/EFCore.SqlServer.FunctionalTests/SqlAzure/Model/Address.cs index b0cd79f9d65..f5ec2817c57 100644 --- a/test/EFCore.SqlServer.FunctionalTests/SqlAzure/Model/Address.cs +++ b/test/EFCore.SqlServer.FunctionalTests/SqlAzure/Model/Address.cs @@ -12,9 +12,7 @@ namespace Microsoft.EntityFrameworkCore.SqlAzure.Model; public class Address { public Address() - { - CustomerAddress = new HashSet(); - } + => CustomerAddress = new HashSet(); public int AddressID { get; set; } diff --git a/test/EFCore.SqlServer.FunctionalTests/SqlAzure/Model/Product.cs b/test/EFCore.SqlServer.FunctionalTests/SqlAzure/Model/Product.cs index 3feded7114f..80eeaf22467 100644 --- a/test/EFCore.SqlServer.FunctionalTests/SqlAzure/Model/Product.cs +++ b/test/EFCore.SqlServer.FunctionalTests/SqlAzure/Model/Product.cs @@ -12,9 +12,7 @@ namespace Microsoft.EntityFrameworkCore.SqlAzure.Model; public class Product { public Product() - { - OrderDetails = new HashSet(); - } + => OrderDetails = new HashSet(); public int ProductID { get; set; } diff --git a/test/EFCore.SqlServer.FunctionalTests/SqlAzure/Model/ProductCategory.cs b/test/EFCore.SqlServer.FunctionalTests/SqlAzure/Model/ProductCategory.cs index 7ac2e80f3a9..5761f6d3840 100644 --- a/test/EFCore.SqlServer.FunctionalTests/SqlAzure/Model/ProductCategory.cs +++ b/test/EFCore.SqlServer.FunctionalTests/SqlAzure/Model/ProductCategory.cs @@ -11,9 +11,7 @@ namespace Microsoft.EntityFrameworkCore.SqlAzure.Model; public class ProductCategory { public ProductCategory() - { - Product = new HashSet(); - } + => Product = new HashSet(); public int ProductCategoryID { get; set; } public string Name { get; set; } diff --git a/test/EFCore.SqlServer.FunctionalTests/SqlAzure/Model/ProductDescription.cs b/test/EFCore.SqlServer.FunctionalTests/SqlAzure/Model/ProductDescription.cs index cd07683389b..81845509c61 100644 --- a/test/EFCore.SqlServer.FunctionalTests/SqlAzure/Model/ProductDescription.cs +++ b/test/EFCore.SqlServer.FunctionalTests/SqlAzure/Model/ProductDescription.cs @@ -12,9 +12,7 @@ namespace Microsoft.EntityFrameworkCore.SqlAzure.Model; public class ProductDescription { public ProductDescription() - { - ProductModelProductDescription = new HashSet(); - } + => ProductModelProductDescription = new HashSet(); public int ProductDescriptionID { get; set; } diff --git a/test/EFCore.SqlServer.FunctionalTests/SqlAzure/Model/SalesOrder.cs b/test/EFCore.SqlServer.FunctionalTests/SqlAzure/Model/SalesOrder.cs index 405c690f1f0..f2d4b8a35c1 100644 --- a/test/EFCore.SqlServer.FunctionalTests/SqlAzure/Model/SalesOrder.cs +++ b/test/EFCore.SqlServer.FunctionalTests/SqlAzure/Model/SalesOrder.cs @@ -12,9 +12,7 @@ namespace Microsoft.EntityFrameworkCore.SqlAzure.Model; public class SalesOrder { public SalesOrder() - { - Details = new HashSet(); - } + => Details = new HashSet(); public int SalesOrderID { get; set; } public string AccountNumber { get; set; } diff --git a/test/EFCore.SqlServer.FunctionalTests/SqlAzure/SqlAzureBatchingTest.cs b/test/EFCore.SqlServer.FunctionalTests/SqlAzure/SqlAzureBatchingTest.cs index cce8c30a600..43ef3e3d393 100644 --- a/test/EFCore.SqlServer.FunctionalTests/SqlAzure/SqlAzureBatchingTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/SqlAzure/SqlAzureBatchingTest.cs @@ -7,7 +7,7 @@ namespace Microsoft.EntityFrameworkCore.SqlAzure; #nullable disable -[SqlServerCondition(SqlServerCondition.IsSqlAzure)] +[SqlServerCondition(SqlServerCondition.IsAzureSql)] public class SqlAzureBatchingTest(BatchingSqlAzureFixture fixture) : IClassFixture { public BatchingSqlAzureFixture Fixture { get; } = fixture; diff --git a/test/EFCore.SqlServer.FunctionalTests/SqlAzure/SqlAzureConnectionTest.cs b/test/EFCore.SqlServer.FunctionalTests/SqlAzure/SqlAzureConnectionTest.cs index 32e1507573c..5bc962c5c1e 100644 --- a/test/EFCore.SqlServer.FunctionalTests/SqlAzure/SqlAzureConnectionTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/SqlAzure/SqlAzureConnectionTest.cs @@ -10,7 +10,7 @@ namespace Microsoft.EntityFrameworkCore.SqlAzure; #nullable disable -[SqlServerCondition(SqlServerCondition.IsSqlAzure)] +[SqlServerCondition(SqlServerCondition.IsAzureSql)] #pragma warning disable CS9113 // Parameter is unread. public class SqlAzureConnectionTest(SqlAzureFixture fixture) : IClassFixture #pragma warning restore CS9113 // Parameter is unread. diff --git a/test/EFCore.SqlServer.FunctionalTests/SqlAzure/SqlAzureDatabaseCreationTest.cs b/test/EFCore.SqlServer.FunctionalTests/SqlAzure/SqlAzureDatabaseCreationTest.cs index 762ac3dd74f..447deed2602 100644 --- a/test/EFCore.SqlServer.FunctionalTests/SqlAzure/SqlAzureDatabaseCreationTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/SqlAzure/SqlAzureDatabaseCreationTest.cs @@ -8,7 +8,7 @@ namespace Microsoft.EntityFrameworkCore.SqlAzure; #nullable disable -[SqlServerCondition(SqlServerCondition.IsSqlAzure)] +[SqlServerCondition(SqlServerCondition.IsAzureSql)] public class SqlAzureDatabaseCreationTest { protected string StoreName { get; } = "SqlAzureDatabaseCreationTest"; @@ -16,12 +16,12 @@ public class SqlAzureDatabaseCreationTest [ConditionalFact] public async Task Creates_database_in_elastic_pool() { - using var testDatabase = SqlServerTestStore.Create(StoreName + "Elastic"); - using var context = new ElasticPoolContext(testDatabase); + await using var testDatabase = SqlServerTestStore.Create(StoreName + "Elastic"); + await using var context = new ElasticPoolContext(testDatabase); await context.Database.EnsureDeletedAsync(); await context.Database.EnsureCreatedAsync(); - await AssertOptionsAsync(context.Database.GetDbConnection(), 1000 * (1L << 28), "Standard", "ElasticPool"); + await AssertOptionsAsync(context.Database.GetDbConnection(), 1L << 35, "GeneralPurpose", "ElasticPool"); } private class ElasticPoolContext(SqlServerTestStore testStore) : DbContext @@ -41,12 +41,12 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalFact] public async Task Creates_basic_database() { - using var testDatabase = SqlServerTestStore.Create(StoreName + "Basic"); - using var context = new BasicContext(testDatabase); + await using var testDatabase = SqlServerTestStore.Create(StoreName + "Basic"); + await using var context = new BasicContext(testDatabase); await context.Database.EnsureDeletedAsync(); await context.Database.EnsureCreatedAsync(); - await AssertOptionsAsync(context.Database.GetDbConnection(), 1L << 30, "Basic", "Basic"); + await AssertOptionsAsync(context.Database.GetDbConnection(), 1L << 35, "GeneralPurpose", "GP_Gen5_2"); } private class BasicContext(SqlServerTestStore testStore) : DbContext @@ -61,20 +61,21 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) protected override void OnModelCreating(ModelBuilder modelBuilder) { - modelBuilder.HasDatabaseMaxSize("1 GB"); - modelBuilder.HasServiceTier("'basic'"); + modelBuilder.HasDatabaseMaxSize("32 GB"); + modelBuilder.HasServiceTier("'GeneralPurpose'"); + modelBuilder.HasPerformanceLevel("GP_Gen5_2"); } } [ConditionalFact] public async Task Creates_business_critical_database() { - using var testDatabase = SqlServerTestStore.Create(StoreName + "BusinessCritical"); - using var context = new BusinessCriticalContext(testDatabase); + await using var testDatabase = SqlServerTestStore.Create(StoreName + "BusinessCritical"); + await using var context = new BusinessCriticalContext(testDatabase); await context.Database.EnsureDeletedAsync(); await context.Database.EnsureCreatedAsync(); - await AssertOptionsAsync(context.Database.GetDbConnection(), 1L << 31, "BusinessCritical", "BC_Gen4_1"); + await AssertOptionsAsync(context.Database.GetDbConnection(), 1L << 33, "BusinessCritical", "BC_Gen5_2"); } private class BusinessCriticalContext(SqlServerTestStore testStore) : DbContext @@ -89,9 +90,9 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) protected override void OnModelCreating(ModelBuilder modelBuilder) { - modelBuilder.HasDatabaseMaxSize("2 GB"); + modelBuilder.HasDatabaseMaxSize("8 GB"); modelBuilder.HasServiceTier("BusinessCritical"); - modelBuilder.HasPerformanceLevel("BC_Gen4_1"); + modelBuilder.HasPerformanceLevel("BC_Gen5_2"); } } diff --git a/test/EFCore.SqlServer.FunctionalTests/SqlAzure/SqlAzureFundamentalsTest.cs b/test/EFCore.SqlServer.FunctionalTests/SqlAzure/SqlAzureFundamentalsTest.cs index f88b40ad500..ac1881c2c55 100644 --- a/test/EFCore.SqlServer.FunctionalTests/SqlAzure/SqlAzureFundamentalsTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/SqlAzure/SqlAzureFundamentalsTest.cs @@ -8,7 +8,7 @@ namespace Microsoft.EntityFrameworkCore.SqlAzure; #nullable disable -[SqlServerCondition(SqlServerCondition.IsSqlAzure)] +[SqlServerCondition(SqlServerCondition.IsAzureSql)] public class SqlAzureFundamentalsTest(SqlAzureFixture fixture) : IClassFixture { public SqlAzureFixture Fixture { get; } = fixture; diff --git a/test/EFCore.SqlServer.FunctionalTests/SqlAzure/adventureworks.sql b/test/EFCore.SqlServer.FunctionalTests/SqlAzure/adventureworks.sql index 04acd43fb65..bcf69db0ee1 100644 Binary files a/test/EFCore.SqlServer.FunctionalTests/SqlAzure/adventureworks.sql and b/test/EFCore.SqlServer.FunctionalTests/SqlAzure/adventureworks.sql differ diff --git a/test/EFCore.SqlServer.FunctionalTests/SqlServerApiConsistencyTest.cs b/test/EFCore.SqlServer.FunctionalTests/SqlServerApiConsistencyTest.cs index 1519bc85790..79cfc3d2d42 100644 --- a/test/EFCore.SqlServer.FunctionalTests/SqlServerApiConsistencyTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/SqlServerApiConsistencyTest.cs @@ -7,7 +7,8 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class SqlServerApiConsistencyTest(SqlServerApiConsistencyTest.SqlServerApiConsistencyFixture fixture) : ApiConsistencyTestBase(fixture) +public class SqlServerApiConsistencyTest(SqlServerApiConsistencyTest.SqlServerApiConsistencyFixture fixture) + : ApiConsistencyTestBase(fixture) { protected override void AddServices(ServiceCollection serviceCollection) => serviceCollection.AddEntityFrameworkSqlServer(); @@ -31,6 +32,7 @@ public class SqlServerApiConsistencyFixture : ApiConsistencyFixtureBase typeof(SqlServerEntityTypeBuilderExtensions), typeof(SqlServerServiceCollectionExtensions), typeof(SqlServerDbFunctionsExtensions), + typeof(SqlServerTableBuilderExtensions), typeof(OwnedNavigationTemporalPeriodPropertyBuilder), typeof(OwnedNavigationTemporalTableBuilder), typeof(OwnedNavigationTemporalTableBuilder<,>), diff --git a/test/EFCore.SqlServer.FunctionalTests/SqlServerConfigPatternsTest.cs b/test/EFCore.SqlServer.FunctionalTests/SqlServerConfigPatternsTest.cs index 7b21c1e444d..4f18610337b 100644 --- a/test/EFCore.SqlServer.FunctionalTests/SqlServerConfigPatternsTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/SqlServerConfigPatternsTest.cs @@ -18,7 +18,7 @@ public class ImplicitServicesAndConfig [ConditionalFact] public async Task Can_query_with_implicit_services_and_OnConfiguring() { - using (await SqlServerTestStore.GetNorthwindStoreAsync()) + await using (await SqlServerTestStore.GetNorthwindStoreAsync()) { using var context = new NorthwindContext(); Assert.Equal(91, await context.Customers.CountAsync()); @@ -46,7 +46,7 @@ public class ImplicitServicesExplicitConfig [ConditionalFact] public async Task Can_query_with_implicit_services_and_explicit_config() { - using (await SqlServerTestStore.GetNorthwindStoreAsync()) + await using (await SqlServerTestStore.GetNorthwindStoreAsync()) { using var context = new NorthwindContext( new DbContextOptionsBuilder() @@ -71,7 +71,7 @@ public class ExplicitServicesImplicitConfig [ConditionalFact] public async Task Can_query_with_explicit_services_and_OnConfiguring() { - using (await SqlServerTestStore.GetNorthwindStoreAsync()) + await using (await SqlServerTestStore.GetNorthwindStoreAsync()) { using var context = new NorthwindContext( new DbContextOptionsBuilder().UseInternalServiceProvider( @@ -100,7 +100,7 @@ public class ExplicitServicesAndConfig [ConditionalFact] public async Task Can_query_with_explicit_services_and_explicit_config() { - using (await SqlServerTestStore.GetNorthwindStoreAsync()) + await using (await SqlServerTestStore.GetNorthwindStoreAsync()) { using var context = new NorthwindContext( new DbContextOptionsBuilder() @@ -127,7 +127,7 @@ public class ExplicitServicesAndNoConfig [ConditionalFact] public async Task Throws_on_attempt_to_use_SQL_Server_without_providing_connection_string() { - using (await SqlServerTestStore.GetNorthwindStoreAsync()) + await using (await SqlServerTestStore.GetNorthwindStoreAsync()) { Assert.Equal( CoreStrings.NoProviderConfigured, @@ -158,7 +158,7 @@ public class NoServicesAndNoConfig [ConditionalFact] public async Task Throws_on_attempt_to_use_context_with_no_store() { - using (await SqlServerTestStore.GetNorthwindStoreAsync()) + await using (await SqlServerTestStore.GetNorthwindStoreAsync()) { Assert.Equal( CoreStrings.NoProviderConfigured, @@ -192,7 +192,7 @@ public async Task Throws_on_attempt_to_use_store_with_no_store_services() new EntityFrameworkServicesBuilder(serviceCollection).TryAddCoreServices(); var serviceProvider = serviceCollection.BuildServiceProvider(validateScopes: true); - using (await SqlServerTestStore.GetNorthwindStoreAsync()) + await using (await SqlServerTestStore.GetNorthwindStoreAsync()) { Assert.Equal( CoreStrings.NoProviderConfigured, @@ -232,7 +232,7 @@ public async Task Can_register_context_with_DI_container_and_have_it_injected() .AddSingleton(p => new DbContextOptionsBuilder().UseInternalServiceProvider(p).Options) .BuildServiceProvider(validateScopes: true); - using (await SqlServerTestStore.GetNorthwindStoreAsync()) + await using (await SqlServerTestStore.GetNorthwindStoreAsync()) { await serviceProvider.GetRequiredService().TestAsync(); } @@ -257,9 +257,7 @@ private class NorthwindContext : DbContext { public NorthwindContext(DbContextOptions options) : base(options) - { - Assert.NotNull(options); - } + => Assert.NotNull(options); public DbSet Customers { get; set; } @@ -286,7 +284,7 @@ public async Task Can_register_context_and_configuration_with_DI_container_and_h .UseSqlServer(SqlServerNorthwindTestStoreFactory.NorthwindConnectionString, b => b.ApplyConfiguration()) .Options).BuildServiceProvider(validateScopes: true); - using (await SqlServerTestStore.GetNorthwindStoreAsync()) + await using (await SqlServerTestStore.GetNorthwindStoreAsync()) { await serviceProvider.GetRequiredService().TestAsync(); } @@ -311,9 +309,7 @@ private class NorthwindContext : DbContext { public NorthwindContext(DbContextOptions options) : base(options) - { - Assert.NotNull(options); - } + => Assert.NotNull(options); public DbSet Customers { get; set; } @@ -327,7 +323,7 @@ public class ConstructorArgsToBuilder [ConditionalFact] public async Task Can_pass_context_options_to_constructor_and_use_in_builder() { - using (await SqlServerTestStore.GetNorthwindStoreAsync()) + await using (await SqlServerTestStore.GetNorthwindStoreAsync()) { using var context = new NorthwindContext( new DbContextOptionsBuilder() @@ -352,7 +348,7 @@ public class ConstructorArgsToOnConfiguring [ConditionalFact] public async Task Can_pass_connection_string_to_constructor_and_use_in_OnConfiguring() { - using (await SqlServerTestStore.GetNorthwindStoreAsync()) + await using (await SqlServerTestStore.GetNorthwindStoreAsync()) { using var context = new NorthwindContext(SqlServerNorthwindTestStoreFactory.NorthwindConnectionString); Assert.Equal(91, await context.Customers.CountAsync()); @@ -380,7 +376,7 @@ public class NestedContext [ConditionalFact] public async Task Can_use_one_context_nested_inside_another_of_the_same_type() { - using (await SqlServerTestStore.GetNorthwindStoreAsync()) + await using (await SqlServerTestStore.GetNorthwindStoreAsync()) { var serviceProvider = new ServiceCollection() .AddEntityFrameworkSqlServer() @@ -522,28 +518,29 @@ private class NorthwindContext(bool before) : DbContext public DbSet Customers { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - { - optionsBuilder + => optionsBuilder .EnableServiceProviderCaching(false) - .UseSqlServer(SqlServerNorthwindTestStoreFactory.NorthwindConnectionString, + .UseSqlServer( + SqlServerNorthwindTestStoreFactory.NorthwindConnectionString, b => { if (before) { b.ExecutionStrategy(_ => new DummyExecutionStrategy()); } + b.EnableRetryOnFailure(); if (!before) { b.ExecutionStrategy(_ => new DummyExecutionStrategy()); } }); - } protected override void OnModelCreating(ModelBuilder modelBuilder) => ConfigureModel(modelBuilder); } } + public class ExplicitExecutionStrategies_AzureSql { [InlineData(true)] @@ -567,28 +564,29 @@ private class NorthwindContext(bool before) : DbContext public DbSet Customers { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - { - optionsBuilder + => optionsBuilder .EnableServiceProviderCaching(false) - .UseAzureSql(SqlServerNorthwindTestStoreFactory.NorthwindConnectionString, + .UseAzureSql( + SqlServerNorthwindTestStoreFactory.NorthwindConnectionString, b => { if (before) { b.ExecutionStrategy(_ => new DummyExecutionStrategy()); } + b.EnableRetryOnFailure(); if (!before) { b.ExecutionStrategy(_ => new DummyExecutionStrategy()); } }); - } protected override void OnModelCreating(ModelBuilder modelBuilder) => ConfigureModel(modelBuilder); } } + public class ExplicitExecutionStrategies_AzureSynapse { [InlineData(true)] @@ -612,28 +610,29 @@ private class NorthwindContext(bool before) : DbContext public DbSet Customers { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - { - optionsBuilder + => optionsBuilder .EnableServiceProviderCaching(false) - .UseAzureSynapse(SqlServerNorthwindTestStoreFactory.NorthwindConnectionString, + .UseAzureSynapse( + SqlServerNorthwindTestStoreFactory.NorthwindConnectionString, b => { if (before) { b.ExecutionStrategy(_ => new DummyExecutionStrategy()); } + b.EnableRetryOnFailure(); if (!before) { b.ExecutionStrategy(_ => new DummyExecutionStrategy()); } }); - } protected override void OnModelCreating(ModelBuilder modelBuilder) => ConfigureModel(modelBuilder); } } + public class ExplicitExecutionStrategies_ConfigureSqlEngine_AzureSql { [InlineData(true)] @@ -657,8 +656,7 @@ private class NorthwindContext(bool before) : DbContext public DbSet Customers { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - { - optionsBuilder + => optionsBuilder .EnableServiceProviderCaching(false) .ConfigureSqlEngine( b => @@ -667,6 +665,7 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { b.ExecutionStrategy(_ => new DummyExecutionStrategy()); } + b.EnableRetryOnFailure(); if (!before) { @@ -674,7 +673,6 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) } }) .UseAzureSql(); - } protected override void OnModelCreating(ModelBuilder modelBuilder) => ConfigureModel(modelBuilder); @@ -695,12 +693,10 @@ private class NorthwindContext : DbContext public DbSet Customers { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - { - optionsBuilder + => optionsBuilder .EnableServiceProviderCaching(false) .UseSqlServer() .UseAzureSql(); - } protected override void OnModelCreating(ModelBuilder modelBuilder) => ConfigureModel(modelBuilder); @@ -721,11 +717,9 @@ private class NorthwindContext : DbContext public DbSet Customers { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - { - optionsBuilder + => optionsBuilder .EnableServiceProviderCaching(false) .ConfigureSqlEngine(); - } protected override void OnModelCreating(ModelBuilder modelBuilder) => ConfigureModel(modelBuilder); @@ -855,9 +849,20 @@ private static void ConfigureModel(ModelBuilder builder) private class DummyExecutionStrategy : IExecutionStrategy { - public bool RetriesOnFailure => true; - - public TResult Execute(TState state, Func operation, Func> verifySucceeded) => throw new NotImplementedException(); - public Task ExecuteAsync(TState state, Func> operation, Func>> verifySucceeded, CancellationToken cancellationToken = default) => throw new NotImplementedException(); + public bool RetriesOnFailure + => true; + + public TResult Execute( + TState state, + Func operation, + Func> verifySucceeded) + => throw new NotImplementedException(); + + public Task ExecuteAsync( + TState state, + Func> operation, + Func>> verifySucceeded, + CancellationToken cancellationToken = default) + => throw new NotImplementedException(); } } diff --git a/test/EFCore.SqlServer.FunctionalTests/SqlServerDatabaseCreatorTest.cs b/test/EFCore.SqlServer.FunctionalTests/SqlServerDatabaseCreatorTest.cs index f67fe7903b8..a202161b6de 100644 --- a/test/EFCore.SqlServer.FunctionalTests/SqlServerDatabaseCreatorTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/SqlServerDatabaseCreatorTest.cs @@ -14,7 +14,7 @@ namespace Microsoft.EntityFrameworkCore; // Tests are split into classes to enable parallel execution // Some combinations are skipped to reduce run time [SqlServerCondition(SqlServerCondition.IsNotCI)] -public class SqlServerDatabaseCreatorExistsTest : SqlServerDatabaseCreatorTest +public class SqlServerDatabaseCreatorExistsTest : SqlServerDatabaseCreatorTestBase { [ConditionalTheory] [InlineData(true, true, false)] @@ -39,8 +39,8 @@ private static async Task Returns_false_when_database_does_not_exist_test( bool useCanConnect, bool file) { - using var testDatabase = SqlServerTestStore.Create("NonExisting", file); - using var context = new BloggingContext(testDatabase); + await using var testDatabase = SqlServerTestStore.Create("NonExisting", file); + await using var context = new BloggingContext(testDatabase); var creator = GetDatabaseCreator(context); await context.Database.CreateExecutionStrategy().ExecuteAsync( @@ -81,10 +81,10 @@ public Task Returns_true_when_database_with_filename_exists(bool async, bool amb private static async Task Returns_true_when_database_exists_test(bool async, bool ambientTransaction, bool useCanConnect, bool file) { - using var testDatabase = file + await using var testDatabase = file ? await SqlServerTestStore.CreateInitializedAsync("ExistingBloggingFile", useFileName: true) : await SqlServerTestStore.GetOrCreateInitializedAsync("ExistingBlogging"); - using var context = new BloggingContext(testDatabase); + await using var context = new BloggingContext(testDatabase); var creator = GetDatabaseCreator(context); await context.Database.CreateExecutionStrategy().ExecuteAsync( @@ -108,7 +108,7 @@ await context.Database.CreateExecutionStrategy().ExecuteAsync( } [SqlServerCondition(SqlServerCondition.IsNotCI)] -public class SqlServerDatabaseCreatorEnsureDeletedTest : SqlServerDatabaseCreatorTest +public class SqlServerDatabaseCreatorEnsureDeletedTest : SqlServerDatabaseCreatorTestBase { [ConditionalTheory] [InlineData(true, true, true)] @@ -129,7 +129,7 @@ public Task Deletes_database_with_filename(bool async, bool open, bool ambientTr private static async Task Delete_database_test(bool async, bool open, bool ambientTransaction, bool file) { - using var testDatabase = await SqlServerTestStore.CreateInitializedAsync("EnsureDeleteBlogging" + (file ? "File" : ""), file); + await using var testDatabase = await SqlServerTestStore.CreateInitializedAsync("EnsureDeleteBlogging" + (file ? "File" : ""), file); if (!open) { testDatabase.CloseConnection(); @@ -178,8 +178,8 @@ public Task Noop_when_database_with_filename_does_not_exist(bool async) private static async Task Noop_when_database_does_not_exist_test(bool async, bool file) { - using var testDatabase = SqlServerTestStore.Create("NonExisting", file); - using var context = new BloggingContext(testDatabase); + await using var testDatabase = SqlServerTestStore.Create("NonExisting", file); + await using var context = new BloggingContext(testDatabase); var creator = GetDatabaseCreator(context); Assert.False(async ? await creator.ExistsAsync() : creator.Exists()); @@ -202,9 +202,10 @@ private static async Task Noop_when_database_does_not_exist_test(bool async, boo } [SqlServerCondition(SqlServerCondition.IsNotCI)] -public class SqlServerDatabaseCreatorEnsureCreatedTest : SqlServerDatabaseCreatorTest +public class SqlServerDatabaseCreatorEnsureCreatedTest : SqlServerDatabaseCreatorTestBase { [ConditionalTheory] + [SqlServerCondition(SqlServerCondition.IsNotAzureSql)] [InlineData(true, true)] [InlineData(false, false)] public Task Creates_schema_in_existing_database(bool async, bool ambientTransaction) @@ -226,7 +227,7 @@ private static Task Creates_schema_in_existing_database_test(bool async, bool am [ConditionalTheory] [InlineData(true, false)] [InlineData(false, true)] - [SqlServerCondition(SqlServerCondition.IsNotSqlAzure)] + [SqlServerCondition(SqlServerCondition.IsNotAzureSql)] public Task Creates_physical_database_and_schema(bool async, bool ambientTransaction) => Creates_new_physical_database_and_schema_test(async, ambientTransaction, file: false); @@ -247,15 +248,15 @@ private static async Task Creates_physical_database_and_schema_test( (bool CreateDatabase, bool Async, bool ambientTransaction, bool File) options) { var (createDatabase, async, ambientTransaction, file) = options; - using var testDatabase = SqlServerTestStore.Create("EnsureCreatedTest" + (file ? "File" : ""), file); - using var context = new BloggingContext(testDatabase); + await using var testDatabase = SqlServerTestStore.Create("EnsureCreatedTest" + (file ? "File" : ""), file); + await using var context = new BloggingContext(testDatabase); if (createDatabase) { await testDatabase.InitializeAsync(null, (Func)null); } else { - testDatabase.DeleteDatabase(); + await testDatabase.DeleteDatabaseAsync(); } var creator = GetDatabaseCreator(context); @@ -327,8 +328,8 @@ public Task Noop_when_database_with_filename_exists_and_has_schema(bool async) private static async Task Noop_when_database_exists_and_has_schema_test(bool async, bool file) { - using var testDatabase = await SqlServerTestStore.CreateInitializedAsync("InitializedBlogging" + (file ? "File" : ""), file); - using var context = new BloggingContext(testDatabase); + await using var testDatabase = await SqlServerTestStore.CreateInitializedAsync("InitializedBlogging" + (file ? "File" : ""), file); + await using var context = new BloggingContext(testDatabase); context.Database.EnsureCreatedResiliently(); if (async) @@ -342,17 +343,39 @@ private static async Task Noop_when_database_exists_and_has_schema_test(bool asy Assert.Equal(ConnectionState.Closed, context.Database.GetDbConnection().State); } + + [ConditionalFact] + public async Task Throws_for_missing_seed() + { + await using var testDatabase = await SqlServerTestStore.CreateInitializedAsync("EnsureCreatedSeedTest"); + await using var context = new BloggingContext(testDatabase.ConnectionString, asyncSeed: true); + + Assert.Equal( + CoreStrings.MissingSeeder, + Assert.Throws(() => context.Database.EnsureCreated()).Message); + } + + [ConditionalFact] + public async Task Throws_for_missing_seed_async() + { + await using var testDatabase = await SqlServerTestStore.CreateInitializedAsync("EnsureCreatedSeedTest"); + await using var context = new BloggingContext(testDatabase.ConnectionString, seed: true); + + Assert.Equal( + CoreStrings.MissingSeeder, + (await Assert.ThrowsAsync(() => context.Database.EnsureCreatedAsync())).Message); + } } [SqlServerCondition(SqlServerCondition.IsNotCI)] -public class SqlServerDatabaseCreatorHasTablesTest : SqlServerDatabaseCreatorTest +public class SqlServerDatabaseCreatorHasTablesTest : SqlServerDatabaseCreatorTestBase { [ConditionalTheory] [InlineData(true)] [InlineData(false)] public async Task Throws_when_database_does_not_exist(bool async) { - using var testDatabase = SqlServerTestStore.GetOrCreate("NonExisting"); + await using var testDatabase = SqlServerTestStore.GetOrCreate("NonExisting"); var databaseCreator = GetDatabaseCreator(testDatabase); await databaseCreator.ExecutionStrategy.ExecuteAsync( databaseCreator, @@ -376,7 +399,7 @@ await databaseCreator.ExecutionStrategy.ExecuteAsync( [InlineData(false, true)] public async Task Returns_false_when_database_exists_but_has_no_tables(bool async, bool ambientTransaction) { - using var testDatabase = await SqlServerTestStore.GetOrCreateInitializedAsync("Empty"); + await using var testDatabase = await SqlServerTestStore.GetOrCreateInitializedAsync("Empty"); var creator = GetDatabaseCreator(testDatabase); await GetExecutionStrategy(testDatabase).ExecuteAsync( @@ -394,7 +417,7 @@ await GetExecutionStrategy(testDatabase).ExecuteAsync( [InlineData(false, false)] public async Task Returns_true_when_database_exists_and_has_any_tables(bool async, bool ambientTransaction) { - using var testDatabase = await SqlServerTestStore.GetOrCreate("ExistingTables") + await using var testDatabase = await SqlServerTestStore.GetOrCreate("ExistingTables") .InitializeSqlServerAsync(null, t => new BloggingContext(t), null); var creator = GetDatabaseCreator(testDatabase); @@ -410,14 +433,14 @@ await GetExecutionStrategy(testDatabase).ExecuteAsync( } [SqlServerCondition(SqlServerCondition.IsNotCI)] -public class SqlServerDatabaseCreatorDeleteTest : SqlServerDatabaseCreatorTest +public class SqlServerDatabaseCreatorDeleteTest : SqlServerDatabaseCreatorTestBase { [ConditionalTheory] [InlineData(true, true)] [InlineData(false, false)] public static async Task Deletes_database(bool async, bool ambientTransaction) { - using var testDatabase = await SqlServerTestStore.CreateInitializedAsync("DeleteBlogging"); + await using var testDatabase = await SqlServerTestStore.CreateInitializedAsync("DeleteBlogging"); testDatabase.CloseConnection(); var creator = GetDatabaseCreator(testDatabase); @@ -444,7 +467,7 @@ public static async Task Deletes_database(bool async, bool ambientTransaction) [InlineData(false)] public async Task Throws_when_database_does_not_exist(bool async) { - using var testDatabase = SqlServerTestStore.GetOrCreate("NonExistingBlogging"); + await using var testDatabase = SqlServerTestStore.GetOrCreate("NonExistingBlogging"); var creator = GetDatabaseCreator(testDatabase); if (async) @@ -453,7 +476,7 @@ public async Task Throws_when_database_does_not_exist(bool async) } else { - Assert.Throws(() => creator.Delete()); + Assert.Throws(creator.Delete); } } @@ -465,22 +488,22 @@ public void Throws_when_no_initial_catalog() var creator = GetDatabaseCreator(connectionStringBuilder.ToString()); - var ex = Assert.Throws(() => creator.Delete()); + var ex = Assert.Throws(creator.Delete); Assert.Equal(SqlServerStrings.NoInitialCatalog, ex.Message); } } [SqlServerCondition(SqlServerCondition.IsNotCI)] -public class SqlServerDatabaseCreatorCreateTablesTest : SqlServerDatabaseCreatorTest +public class SqlServerDatabaseCreatorCreateTablesTest : SqlServerDatabaseCreatorTestBase { [ConditionalTheory] [InlineData(true, true)] [InlineData(false, false)] public async Task Creates_schema_in_existing_database_test(bool async, bool ambientTransaction) { - using var testDatabase = await SqlServerTestStore.GetOrCreateInitializedAsync("ExistingBlogging" + (async ? "Async" : "")); - using var context = new BloggingContext(testDatabase); + await using var testDatabase = await SqlServerTestStore.GetOrCreateInitializedAsync("ExistingBlogging" + (async ? "Async" : "")); + await using var context = new BloggingContext(testDatabase); var creator = GetDatabaseCreator(context); using (CreateTransactionScope(ambientTransaction)) @@ -529,12 +552,12 @@ public async Task Creates_schema_in_existing_database_test(bool async, bool ambi [InlineData(false)] public async Task Throws_if_database_does_not_exist(bool async) { - using var testDatabase = SqlServerTestStore.GetOrCreate("NonExisting"); + await using var testDatabase = SqlServerTestStore.GetOrCreate("NonExisting"); var creator = GetDatabaseCreator(testDatabase); var exception = async ? (await Assert.ThrowsAsync(() => creator.CreateTablesAsync())) - : Assert.Throws(() => creator.CreateTables()); + : Assert.Throws(creator.CreateTables); Assert.Equal(CoreStrings.RetryLimitExceeded(6, "TestSqlServerRetryingExecutionStrategy"), exception.Message); @@ -599,14 +622,14 @@ public void GenerateCreateScript_works() } [SqlServerCondition(SqlServerCondition.IsNotCI)] -public class SqlServerDatabaseCreatorCreateTest : SqlServerDatabaseCreatorTest +public class SqlServerDatabaseCreatorCreateTest : SqlServerDatabaseCreatorTestBase { [ConditionalTheory] [InlineData(true, false)] [InlineData(false, true)] public async Task Creates_physical_database_but_not_tables(bool async, bool ambientTransaction) { - using var testDatabase = SqlServerTestStore.GetOrCreate("CreateTest"); + await using var testDatabase = SqlServerTestStore.GetOrCreate("CreateTest"); var creator = GetDatabaseCreator(testDatabase); creator.EnsureDeleted(); @@ -651,12 +674,12 @@ await testDatabase.ExecuteScalarAsync( [InlineData(false)] public async Task Throws_if_database_already_exists(bool async) { - using var testDatabase = await SqlServerTestStore.GetOrCreateInitializedAsync("ExistingBlogging"); + await using var testDatabase = await SqlServerTestStore.GetOrCreateInitializedAsync("ExistingBlogging"); var creator = GetDatabaseCreator(testDatabase); var ex = async ? await Assert.ThrowsAsync(() => creator.CreateAsync()) - : Assert.Throws(() => creator.Create()); + : Assert.Throws(creator.Create); Assert.Equal( 1801, // Database with given name already exists ex.Number); @@ -664,8 +687,8 @@ public async Task Throws_if_database_already_exists(bool async) } #pragma warning disable RCS1102 // Make class static. -[SqlServerCondition(SqlServerCondition.IsNotSqlAzure | SqlServerCondition.IsNotCI)] -public class SqlServerDatabaseCreatorTest +[SqlServerCondition(SqlServerCondition.IsNotAzureSql | SqlServerCondition.IsNotCI)] +public abstract class SqlServerDatabaseCreatorTestBase { protected static IDisposable CreateTransactionScope(bool useTransaction) => TestStore.CreateTransactionScope(useTransaction); @@ -697,7 +720,11 @@ private static IServiceProvider CreateServiceProvider() .AddScoped() .BuildServiceProvider(validateScopes: true); - protected class BloggingContext(string connectionString) : DbContext + protected class BloggingContext( + string connectionString, + bool seed = false, + bool asyncSeed = false) + : DbContext { private readonly string _connectionString = connectionString; @@ -707,9 +734,20 @@ public BloggingContext(SqlServerTestStore testStore) } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - => optionsBuilder + { + optionsBuilder .UseSqlServer(_connectionString, b => b.ApplyConfiguration()) .UseInternalServiceProvider(CreateServiceProvider()); + if (seed) + { + optionsBuilder.UseSeeding((_, __) => { }); + } + + if (asyncSeed) + { + optionsBuilder.UseAsyncSeeding((_, __, ___) => Task.CompletedTask); + } + } protected override void OnModelCreating(ModelBuilder modelBuilder) => modelBuilder.Entity( diff --git a/test/EFCore.SqlServer.FunctionalTests/SqlServerEndToEndTest.cs b/test/EFCore.SqlServer.FunctionalTests/SqlServerEndToEndTest.cs index b97e8543014..84a860c1079 100644 --- a/test/EFCore.SqlServer.FunctionalTests/SqlServerEndToEndTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/SqlServerEndToEndTest.cs @@ -30,7 +30,7 @@ public SqlServerEndToEndTest(SqlServerFixture fixture) [ConditionalFact] public async Task Can_use_decimal_and_byte_as_identity_columns() { - using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); var nownNum1 = new NownNum { Id = 77.0m, TheWalrus = "Crying" }; var nownNum2 = new NownNum { Id = 78.0m, TheWalrus = "Walrus" }; @@ -217,9 +217,9 @@ private class ByteAdNum [ConditionalFact] // Issue #29931 public async Task Can_use_SqlQuery_when_context_has_DbFunction() { - using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); var options = Fixture.CreateOptions(testDatabase); - using (var context = new DbFunctionContext(options)) + await using (var context = new DbFunctionContext(options)) { var result = context.Database .SqlQueryRaw("SELECT Name from sys.databases") @@ -257,7 +257,7 @@ private class RawResult [ConditionalFact] public async Task Can_use_string_enum_or_byte_array_as_key() { - using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); var sNum1 = new SNum { TheWalrus = "I" }; var sNum2 = new SNum { TheWalrus = "Am" }; @@ -268,7 +268,7 @@ public async Task Can_use_string_enum_or_byte_array_as_key() var bNum2 = new BNum { TheWalrus = "Eggmen" }; var options = Fixture.CreateOptions(testDatabase); - using (var context = new ENumContext(options)) + await using (var context = new ENumContext(options)) { context.Database.EnsureCreatedResiliently(); @@ -277,7 +277,7 @@ public async Task Can_use_string_enum_or_byte_array_as_key() context.SaveChanges(); } - using (var context = new ENumContext(options)) + await using (var context = new ENumContext(options)) { Assert.Equal(sNum1.Id, context.SNums.Single(e => e.TheWalrus == "I").Id); Assert.Equal(sNum2.Id, context.SNums.Single(e => e.TheWalrus == "Am").Id); @@ -293,12 +293,12 @@ public async Task Can_use_string_enum_or_byte_array_as_key() [ConditionalFact] public async Task Can_remove_multiple_byte_array_as_key() { - using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); var bNum1 = new BNum { TheWalrus = "Eggman" }; var bNum2 = new BNum { TheWalrus = "Eggmen" }; var options = Fixture.CreateOptions(testDatabase); - using (var context = new ENumContext(options)) + await using (var context = new ENumContext(options)) { context.Database.EnsureCreatedResiliently(); @@ -307,7 +307,7 @@ public async Task Can_remove_multiple_byte_array_as_key() context.SaveChanges(); } - using (var context = new ENumContext(options)) + await using (var context = new ENumContext(options)) { Assert.Equal(bNum1.Id, context.BNums.Single(e => e.TheWalrus == "Eggman").Id); Assert.Equal(bNum2.Id, context.BNums.Single(e => e.TheWalrus == "Eggmen").Id); @@ -328,11 +328,11 @@ private class ENumContext(DbContextOptions options) : DbContext(options) [ConditionalFact] public async Task Can_add_table_splitting_dependent_after_principal() { - using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); var options = Fixture.CreateOptions(testDatabase); EvaluationAction evaluationAction = null; - using (var context = new ProjectContext(options)) + await using (var context = new ProjectContext(options)) { context.Database.EnsureCreatedResiliently(); @@ -346,7 +346,7 @@ public async Task Can_add_table_splitting_dependent_after_principal() context.SaveChanges(); } - using (var context = new ProjectContext(options)) + await using (var context = new ProjectContext(options)) { context.Database.EnsureCreatedResiliently(); @@ -361,7 +361,7 @@ public async Task Can_add_table_splitting_dependent_after_principal() context.SaveChanges(); } - using (var context = new ProjectContext(options)) + await using (var context = new ProjectContext(options)) { Assert.NotNull(context.ProjectActions.Single()); Assert.NotNull(context.EvaluationActions.Single()); @@ -371,10 +371,10 @@ public async Task Can_add_table_splitting_dependent_after_principal() [ConditionalFact] public async Task Throws_when_adding_table_splitting_dependent_without_principal() { - using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); var options = Fixture.CreateOptions(testDatabase); - using (var context = new ProjectContext(options)) + await using (var context = new ProjectContext(options)) { context.Database.EnsureCreatedResiliently(); @@ -463,10 +463,10 @@ private class BNum [ConditionalFact] public async Task Can_add_and_remove_entities_with_keys_of_different_type() { - using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); var options = Fixture.CreateOptions(testDatabase); - using (var context = new CompositeKeysDbContext(options)) + await using (var context = new CompositeKeysDbContext(options)) { context.Database.EnsureCreatedResiliently(); var first = new Int32CompositeKeys { Id1 = 1, Id2 = 2 }; @@ -479,7 +479,7 @@ public async Task Can_add_and_remove_entities_with_keys_of_different_type() await context.SaveChangesAsync(); } - using (var context = new CompositeKeysDbContext(options)) + await using (var context = new CompositeKeysDbContext(options)) { var first = context.Set().Single(); context.Remove(first); @@ -515,10 +515,10 @@ private class Int64CompositeKeys [ConditionalFact] public async Task Can_insert_non_owner_principal_for_owned() { - using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); var options = Fixture.CreateOptions(testDatabase); - using (var context = new FileContext(options)) + await using (var context = new FileContext(options)) { context.Database.EnsureCreatedResiliently(); @@ -577,10 +577,10 @@ private sealed class FileSource [ConditionalFact] public async Task Can_insert_TPT_dependents_with_identity() { - using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); var options = Fixture.CreateOptions(testDatabase); - using (var context = new CarContext(options)) + await using (var context = new CarContext(options)) { context.Database.EnsureCreatedResiliently(); @@ -615,8 +615,8 @@ private class Ferrari : Car [ConditionalFact] public async Task Can_run_linq_query_on_entity_set() { - using var testStore = await SqlServerTestStore.GetNorthwindStoreAsync(); - using var db = new NorthwindContext(Fixture.CreateOptions(testStore)); + await using var testStore = await SqlServerTestStore.GetNorthwindStoreAsync(); + await using var db = new NorthwindContext(Fixture.CreateOptions(testStore)); var results = db.Customers .Where(c => c.CompanyName.StartsWith("A")) .OrderByDescending(c => c.CustomerID) @@ -637,8 +637,8 @@ public async Task Can_run_linq_query_on_entity_set() [ConditionalFact] public async Task Can_run_linq_query_on_entity_set_with_value_buffer_reader() { - using var testStore = await SqlServerTestStore.GetNorthwindStoreAsync(); - using var db = new NorthwindContext(Fixture.CreateOptions(testStore)); + await using var testStore = await SqlServerTestStore.GetNorthwindStoreAsync(); + await using var db = new NorthwindContext(Fixture.CreateOptions(testStore)); var results = db.Customers .Where(c => c.CompanyName.StartsWith("A")) .OrderByDescending(c => c.CustomerID) @@ -659,8 +659,8 @@ public async Task Can_run_linq_query_on_entity_set_with_value_buffer_reader() [ConditionalFact] public async Task Can_enumerate_entity_set() { - using var testStore = await SqlServerTestStore.GetNorthwindStoreAsync(); - using var db = new NorthwindContext(Fixture.CreateOptions(testStore)); + await using var testStore = await SqlServerTestStore.GetNorthwindStoreAsync(); + await using var db = new NorthwindContext(Fixture.CreateOptions(testStore)); var results = new List(); foreach (var item in db.Customers) { @@ -675,16 +675,16 @@ public async Task Can_enumerate_entity_set() [ConditionalFact] public async Task Can_save_changes() { - using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); var options = Fixture.CreateOptions(testDatabase); - using (var db = new BloggingContext(options)) + await using (var db = new BloggingContext(options)) { await CreateBlogDatabaseAsync(db); } Fixture.TestSqlLoggerFactory.Clear(); - using (var db = new BloggingContext(options)) + await using (var db = new BloggingContext(options)) { var toUpdate = db.Blogs.Single(b => b.Name == "Blog1"); toUpdate.Name = "Blog is Updated"; @@ -748,12 +748,12 @@ public async Task Can_save_changes() [ConditionalFact] public async Task Can_save_changes_in_tracked_entities() { - using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); int updatedId; int deletedId; int addedId; var options = Fixture.CreateOptions(testDatabase); - using (var db = new BloggingContext(options)) + await using (var db = new BloggingContext(options)) { var blogs = await CreateBlogDatabaseAsync(db); @@ -793,7 +793,7 @@ public async Task Can_save_changes_in_tracked_entities() Assert.DoesNotContain(toDelete, db.ChangeTracker.Entries().Select(e => e.Entity)); } - using (var db = new BloggingContext(options)) + await using (var db = new BloggingContext(options)) { var toUpdate = db.Blogs.Single(b => b.Id == updatedId); Assert.Equal("Blog is Updated", toUpdate.Name); @@ -805,9 +805,9 @@ public async Task Can_save_changes_in_tracked_entities() [ConditionalFact] public async Task Can_track_an_entity_with_more_than_10_properties() { - using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); var options = Fixture.CreateOptions(testDatabase); - using (var context = new GameDbContext(options)) + await using (var context = new GameDbContext(options)) { context.Database.EnsureCreatedResiliently(); @@ -818,7 +818,7 @@ public async Task Can_track_an_entity_with_more_than_10_properties() context.SaveChanges(); } - using (var context = new GameDbContext(options)) + await using (var context = new GameDbContext(options)) { var character = context.Characters .Include(c => c.Level.Game) @@ -834,10 +834,10 @@ public async Task Can_track_an_entity_with_more_than_10_properties() [ConditionalFact] public async Task Can_replace_identifying_FK_entity_with_many_to_many() { - using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); var options = Fixture.CreateOptions(testDatabase); - using (var context = new SomeDbContext(options)) + await using (var context = new SomeDbContext(options)) { context.Database.EnsureCreatedResiliently(); @@ -937,11 +937,11 @@ public async Task Can_insert_entities_with_generated_PKs(int studentCount, int c new() { Title = "Literature", Credits = 4 } }; - using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); var options = Fixture.CreateOptions(testDatabase); var nextCourse = 0; - using (var context = new UniversityContext(options)) + await using (var context = new UniversityContext(options)) { context.Database.EnsureCreatedResiliently(); for (var i = 0; i < studentCount; i++) @@ -1000,7 +1000,7 @@ public async Task Can_insert_entities_with_generated_PKs(int studentCount, int c }); } - using (var context = new UniversityContext(options)) + await using (var context = new UniversityContext(options)) { Assert.Equal(studentCount, context.Students.ToList().Count()); Assert.Equal(courseCount, context.Courses.ToList().Count()); @@ -1190,10 +1190,10 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalFact] public async Task Adding_an_item_to_a_collection_marks_it_as_modified() { - using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); var options = Fixture.CreateOptions(testDatabase); - using var context = new GameDbContext(options); + await using var context = new GameDbContext(options); context.Database.EnsureCreatedResiliently(); var player = new PlayerCharacter( @@ -1215,10 +1215,10 @@ public async Task Adding_an_item_to_a_collection_marks_it_as_modified() [ConditionalFact] public async Task Can_set_reference_twice() { - using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); var options = Fixture.CreateOptions(testDatabase); - using (var context = new GameDbContext(options)) + await using (var context = new GameDbContext(options)) { context.Database.EnsureCreatedResiliently(); @@ -1255,10 +1255,10 @@ public async Task Can_set_reference_twice() [ConditionalFact] public async Task Can_include_on_loaded_entity() { - using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); var options = Fixture.CreateOptions(testDatabase); - using (var context = new GameDbContext(options)) + await using (var context = new GameDbContext(options)) { context.Database.EnsureCreatedResiliently(); @@ -1281,7 +1281,7 @@ public async Task Can_include_on_loaded_entity() context.SaveChanges(); } - using (var context = new GameDbContext(options)) + await using (var context = new GameDbContext(options)) { var player = context.Characters .Include(p => p.CurrentWeapon) @@ -1301,7 +1301,7 @@ public async Task Can_include_on_loaded_entity() Assert.Equal(2, player.Items.Count); } - using (var context = new GameDbContext(options)) + await using (var context = new GameDbContext(options)) { var player = context.Characters .Include(p => p.CurrentWeapon) @@ -1483,8 +1483,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalFact] public async Task Tracking_entities_asynchronously_returns_tracked_entities_back() { - using var testStore = await SqlServerTestStore.GetNorthwindStoreAsync(); - using var db = new NorthwindContext(Fixture.CreateOptions(testStore)); + await using var testStore = await SqlServerTestStore.GetNorthwindStoreAsync(); + await using var db = new NorthwindContext(Fixture.CreateOptions(testStore)); var customer = await db.Customers.OrderBy(c => c.CustomerID).FirstOrDefaultAsync(); var trackedCustomerEntry = db.ChangeTracker.Entries().Single(); @@ -1497,14 +1497,14 @@ public async Task Tracking_entities_asynchronously_returns_tracked_entities_back [ConditionalFact] // Issue #931 public async Task Can_save_and_query_with_schema() { - using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); var options = Fixture.CreateOptions(testStore); await testStore.ExecuteNonQueryAsync("CREATE SCHEMA Apple"); await testStore.ExecuteNonQueryAsync("CREATE TABLE Apple.Jack (MyKey int)"); await testStore.ExecuteNonQueryAsync("CREATE TABLE Apple.Black (MyKey int)"); - using (var context = new SchemaContext(options)) + await using (var context = new SchemaContext(options)) { await context.AddAsync( new Jack { MyKey = 1 }); @@ -1513,7 +1513,7 @@ await context.AddAsync( context.SaveChanges(); } - using (var context = new SchemaContext(options)) + await using (var context = new SchemaContext(options)) { Assert.Equal(1, context.Jacks.Count()); Assert.Equal(1, context.Blacks.Count()); @@ -1564,14 +1564,14 @@ public Task Can_round_trip_changes_with_changed_only_notification_entities() private async Task RoundTripChanges() where TBlog : class, IBlog, new() { - using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using var testDatabase = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); var options = Fixture.CreateOptions(testDatabase); int blog1Id; int blog2Id; int blog3Id; - using (var context = new BloggingContext(options)) + await using (var context = new BloggingContext(options)) { var blogs = await CreateBlogDatabaseAsync(context); blog1Id = blogs[0].Id; @@ -1582,7 +1582,7 @@ private async Task RoundTripChanges() Assert.NotEqual(blog1Id, blog2Id); } - using (var context = new BloggingContext(options)) + await using (var context = new BloggingContext(options)) { var blogs = context.Blogs.ToList(); Assert.Equal(2, blogs.Count); @@ -1618,7 +1618,7 @@ private async Task RoundTripChanges() Assert.NotEqual(0, blog3Id); } - using (var context = new BloggingContext(options)) + await using (var context = new BloggingContext(options)) { var blogs = context.Blogs.ToList(); Assert.Equal(3, blogs.Count); diff --git a/test/EFCore.SqlServer.FunctionalTests/SqlServerFixture.cs b/test/EFCore.SqlServer.FunctionalTests/SqlServerFixture.cs index 57f63ac3a54..27015232920 100644 --- a/test/EFCore.SqlServer.FunctionalTests/SqlServerFixture.cs +++ b/test/EFCore.SqlServer.FunctionalTests/SqlServerFixture.cs @@ -21,6 +21,7 @@ public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder build w => { w.Log(SqlServerEventId.ByteIdentityColumnWarning); + w.Log(SqlServerEventId.JsonTypeExperimental); w.Log(SqlServerEventId.DecimalTypeKeyWarning); }); } diff --git a/test/EFCore.SqlServer.FunctionalTests/SqlServerTypeAliasTest.cs b/test/EFCore.SqlServer.FunctionalTests/SqlServerTypeAliasTest.cs index 132022c41c4..37edba51415 100644 --- a/test/EFCore.SqlServer.FunctionalTests/SqlServerTypeAliasTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/SqlServerTypeAliasTest.cs @@ -14,7 +14,7 @@ public class SqlServerTypeAliasTest(SqlServerFixture fixture) : IClassFixture model [ConditionalFact] public async Task Insert_with_sequence_HiLo() { - using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); - using (var context = new BlogContextHiLo(testStore.Name, OnModelCreating)) + await using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using (var context = new BlogContextHiLo(testStore.Name, OnModelCreating)) { context.Database.EnsureCreatedResiliently(); @@ -68,7 +68,7 @@ public async Task Insert_with_sequence_HiLo() context.SaveChanges(); } - using (var context = new BlogContextHiLo(testStore.Name, OnModelCreating)) + await using (var context = new BlogContextHiLo(testStore.Name, OnModelCreating)) { var blogs = context.Blogs.OrderBy(e => e.Id).ToList(); @@ -100,8 +100,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalFact] public async Task Insert_with_key_sequence() { - using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); - using (var context = new BlogContextKeySequence(testStore.Name, OnModelCreating)) + await using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using (var context = new BlogContextKeySequence(testStore.Name, OnModelCreating)) { context.Database.EnsureCreatedResiliently(); @@ -110,7 +110,7 @@ public async Task Insert_with_key_sequence() context.SaveChanges(); } - using (var context = new BlogContextKeySequence(testStore.Name, OnModelCreating)) + await using (var context = new BlogContextKeySequence(testStore.Name, OnModelCreating)) { var blogs = context.Blogs.OrderBy(e => e.Id).ToList(); @@ -142,8 +142,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalFact] public async Task Insert_with_non_key_sequence() { - using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); - using (var context = new BlogContextNonKeySequence(testStore.Name, OnModelCreating)) + await using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using (var context = new BlogContextNonKeySequence(testStore.Name, OnModelCreating)) { context.Database.EnsureCreatedResiliently(); @@ -152,7 +152,7 @@ public async Task Insert_with_non_key_sequence() context.SaveChanges(); } - using (var context = new BlogContextNonKeySequence(testStore.Name, OnModelCreating)) + await using (var context = new BlogContextNonKeySequence(testStore.Name, OnModelCreating)) { var blogs = context.Blogs.OrderBy(e => e.Id).ToList(); @@ -181,8 +181,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalFact] public async Task Insert_with_default_value_from_sequence() { - using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); - using (var context = new BlogContextDefaultValue(testStore.Name, OnModelCreating)) + await using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using (var context = new BlogContextDefaultValue(testStore.Name, OnModelCreating)) { context.Database.EnsureCreatedResiliently(); @@ -191,7 +191,7 @@ public async Task Insert_with_default_value_from_sequence() context.SaveChanges(); } - using (var context = new BlogContextDefaultValue(testStore.Name, OnModelCreating)) + await using (var context = new BlogContextDefaultValue(testStore.Name, OnModelCreating)) { var blogs = context.Blogs.OrderBy(e => e.Id).ToList(); @@ -199,14 +199,14 @@ public async Task Insert_with_default_value_from_sequence() Assert.Equal(1, blogs[1].Id); } - using (var context = new BlogContextDefaultValueNoMigrations(testStore.Name, OnModelCreating)) + await using (var context = new BlogContextDefaultValueNoMigrations(testStore.Name, OnModelCreating)) { context.AddRange(CreateBlog("One Unicorn"), CreateBlog("Two Unicorns")); context.SaveChanges(); } - using (var context = new BlogContextDefaultValueNoMigrations(testStore.Name, OnModelCreating)) + await using (var context = new BlogContextDefaultValueNoMigrations(testStore.Name, OnModelCreating)) { var blogs = context.Blogs.OrderBy(e => e.Id).ToList(); @@ -251,8 +251,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalFact] public async Task Insert_with_default_string_value_from_sequence() { - using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); - using (var context = new BlogContextStringDefaultValue(testStore.Name, OnModelCreating, StringSentinel)) + await using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using (var context = new BlogContextStringDefaultValue(testStore.Name, OnModelCreating, StringSentinel)) { context.Database.EnsureCreatedResiliently(); @@ -263,7 +263,7 @@ public async Task Insert_with_default_string_value_from_sequence() context.SaveChanges(); } - using (var context = new BlogContextStringDefaultValue(testStore.Name, OnModelCreating, StringSentinel)) + await using (var context = new BlogContextStringDefaultValue(testStore.Name, OnModelCreating, StringSentinel)) { var blogs = context.StringyBlogs.OrderBy(e => e.Id).ToList(); @@ -304,8 +304,8 @@ public class BlogWithStringKey [ConditionalFact] public async Task Insert_with_key_default_value_from_sequence() { - using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); - using (var context = new BlogContextKeyColumnWithDefaultValue(testStore.Name, OnModelCreating)) + await using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using (var context = new BlogContextKeyColumnWithDefaultValue(testStore.Name, OnModelCreating)) { context.Database.EnsureCreatedResiliently(); @@ -314,7 +314,7 @@ public async Task Insert_with_key_default_value_from_sequence() context.SaveChanges(); } - using (var context = new BlogContextKeyColumnWithDefaultValue(testStore.Name, OnModelCreating)) + await using (var context = new BlogContextKeyColumnWithDefaultValue(testStore.Name, OnModelCreating)) { var blogs = context.Blogs.OrderBy(e => e.Id).ToList(); @@ -345,8 +345,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalFact] public async Task Insert_uint_to_Identity_column_using_value_converter() { - using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); - using (var context = new BlogContextUIntToIdentityUsingValueConverter(testStore.Name, OnModelCreating, UIntSentinel)) + await using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using (var context = new BlogContextUIntToIdentityUsingValueConverter(testStore.Name, OnModelCreating, UIntSentinel)) { context.Database.EnsureCreatedResiliently(); @@ -357,7 +357,7 @@ public async Task Insert_uint_to_Identity_column_using_value_converter() context.SaveChanges(); } - using (var context = new BlogContextUIntToIdentityUsingValueConverter(testStore.Name, OnModelCreating, UIntSentinel)) + await using (var context = new BlogContextUIntToIdentityUsingValueConverter(testStore.Name, OnModelCreating, UIntSentinel)) { var blogs = context.UnsignedBlogs.OrderBy(e => e.Id).ToList(); @@ -394,8 +394,8 @@ public class BlogWithUIntKey [ConditionalFact] public async Task Insert_int_enum_to_Identity_column() { - using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); - using (var context = new BlogContextIntEnumToIdentity(testStore.Name, OnModelCreating, IntKeySentinel)) + await using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using (var context = new BlogContextIntEnumToIdentity(testStore.Name, OnModelCreating, IntKeySentinel)) { context.Database.EnsureCreatedResiliently(); @@ -406,7 +406,7 @@ public async Task Insert_int_enum_to_Identity_column() context.SaveChanges(); } - using (var context = new BlogContextIntEnumToIdentity(testStore.Name, OnModelCreating, IntKeySentinel)) + await using (var context = new BlogContextIntEnumToIdentity(testStore.Name, OnModelCreating, IntKeySentinel)) { var blogs = context.EnumBlogs.OrderBy(e => e.Id).ToList(); @@ -450,8 +450,8 @@ public enum IntKey [ConditionalFact] public async Task Insert_ulong_enum_to_Identity_column() { - using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); - using (var context = new BlogContextULongEnumToIdentity(testStore.Name, OnModelCreating, ULongKeySentinel)) + await using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using (var context = new BlogContextULongEnumToIdentity(testStore.Name, OnModelCreating, ULongKeySentinel)) { context.Database.EnsureCreatedResiliently(); @@ -462,7 +462,7 @@ public async Task Insert_ulong_enum_to_Identity_column() context.SaveChanges(); } - using (var context = new BlogContextULongEnumToIdentity(testStore.Name, OnModelCreating, ULongKeySentinel)) + await using (var context = new BlogContextULongEnumToIdentity(testStore.Name, OnModelCreating, ULongKeySentinel)) { var blogs = context.EnumBlogs.OrderBy(e => e.Id).ToList(); @@ -505,8 +505,8 @@ public enum ULongKey : ulong [ConditionalFact] public async Task Insert_string_to_Identity_column_using_value_converter() { - using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); - using (var context = new BlogContextStringToIdentityUsingValueConverter(testStore.Name, OnModelCreating, StringSentinel)) + await using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using (var context = new BlogContextStringToIdentityUsingValueConverter(testStore.Name, OnModelCreating, StringSentinel)) { context.Database.EnsureCreatedResiliently(); @@ -517,7 +517,7 @@ public async Task Insert_string_to_Identity_column_using_value_converter() context.SaveChanges(); } - using (var context = new BlogContextStringToIdentityUsingValueConverter(testStore.Name, OnModelCreating, StringSentinel)) + await using (var context = new BlogContextStringToIdentityUsingValueConverter(testStore.Name, OnModelCreating, StringSentinel)) { var blogs = context.StringyBlogs.OrderBy(e => e.Id).ToList(); @@ -555,8 +555,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalFact] public async Task Insert_with_explicit_non_default_keys() { - using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); - using (var context = new BlogContextNoKeyGeneration(testStore.Name, OnModelCreating)) + await using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using (var context = new BlogContextNoKeyGeneration(testStore.Name, OnModelCreating)) { context.Database.EnsureCreatedResiliently(); @@ -566,7 +566,7 @@ public async Task Insert_with_explicit_non_default_keys() context.SaveChanges(); } - using (var context = new BlogContextNoKeyGeneration(testStore.Name, OnModelCreating)) + await using (var context = new BlogContextNoKeyGeneration(testStore.Name, OnModelCreating)) { var blogs = context.Blogs.OrderBy(e => e.Id).ToList(); @@ -592,8 +592,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalFact] public async Task Insert_with_explicit_with_default_keys() { - using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); - using (var context = new BlogContextNoKeyGenerationNullableKey(testStore.Name, OnModelCreating, NullableIntSentinel)) + await using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using (var context = new BlogContextNoKeyGenerationNullableKey(testStore.Name, OnModelCreating, NullableIntSentinel)) { context.Database.EnsureCreatedResiliently(); @@ -604,7 +604,7 @@ public async Task Insert_with_explicit_with_default_keys() context.SaveChanges(); } - using (var context = new BlogContextNoKeyGenerationNullableKey(testStore.Name, OnModelCreating, NullableIntSentinel)) + await using (var context = new BlogContextNoKeyGenerationNullableKey(testStore.Name, OnModelCreating, NullableIntSentinel)) { var blogs = context.NullableKeyBlogs.OrderBy(e => e.Id).ToList(); @@ -633,9 +633,9 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalFact] public async Task Insert_with_non_key_default_value() { - using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); - using (var context = new BlogContextNonKeyDefaultValue(testStore.Name, OnModelCreating)) + await using (var context = new BlogContextNonKeyDefaultValue(testStore.Name, OnModelCreating)) { context.Database.EnsureCreatedResiliently(); @@ -666,7 +666,7 @@ public async Task Insert_with_non_key_default_value() Assert.Equal(111, blogs[1].NeedsConverter.Value); } - using (var context = new BlogContextNonKeyDefaultValue(testStore.Name, OnModelCreating)) + await using (var context = new BlogContextNonKeyDefaultValue(testStore.Name, OnModelCreating)) { var blogs = context.Blogs.OrderBy(e => e.Name).ToList(); Assert.Equal(3, blogs.Count); @@ -686,7 +686,7 @@ public async Task Insert_with_non_key_default_value() context.SaveChanges(); } - using (var context = new BlogContextNonKeyDefaultValue(testStore.Name, OnModelCreating)) + await using (var context = new BlogContextNonKeyDefaultValue(testStore.Name, OnModelCreating)) { var blogs = context.Blogs.OrderBy(e => e.Name).ToList(); Assert.Equal(3, blogs.Count); @@ -703,9 +703,9 @@ public async Task Insert_with_non_key_default_value() [SqlServerCondition(SqlServerCondition.SupportsSqlClr)] public async Task Insert_with_non_key_default_spatial_value() { - using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); - using (var context = new BlogContextNonKeyDefaultSpatialValue(testStore.Name, OnModelCreating)) + await using (var context = new BlogContextNonKeyDefaultSpatialValue(testStore.Name, OnModelCreating)) { context.Database.EnsureCreatedResiliently(); @@ -735,7 +735,7 @@ public async Task Insert_with_non_key_default_spatial_value() Assert.Equal(3, point.Y); } - using (var context = new BlogContextNonKeyDefaultSpatialValue(testStore.Name, OnModelCreating)) + await using (var context = new BlogContextNonKeyDefaultSpatialValue(testStore.Name, OnModelCreating)) { var blogs = context.SpatialBlogs.OrderBy(e => e.Name).ToList(); Assert.Equal(3, blogs.Count); @@ -754,7 +754,7 @@ public async Task Insert_with_non_key_default_spatial_value() context.SaveChanges(); } - using (var context = new BlogContextNonKeyDefaultSpatialValue(testStore.Name, OnModelCreating)) + await using (var context = new BlogContextNonKeyDefaultSpatialValue(testStore.Name, OnModelCreating)) { var blogs = context.SpatialBlogs.OrderBy(e => e.Name).ToList(); Assert.Equal(3, blogs.Count); @@ -820,8 +820,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalFact] public async Task Insert_with_non_key_default_value_readonly() { - using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); - using (var context = new BlogContextNonKeyReadOnlyDefaultValue(testStore.Name, OnModelCreating, IntSentinel, DateTimeSentinel)) + await using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using (var context = new BlogContextNonKeyReadOnlyDefaultValue(testStore.Name, OnModelCreating, IntSentinel, DateTimeSentinel)) { context.Database.EnsureCreatedResiliently(); @@ -846,7 +846,7 @@ public async Task Insert_with_non_key_default_value_readonly() DateTime dateTime0; - using (var context = new BlogContextNonKeyReadOnlyDefaultValue(testStore.Name, OnModelCreating, IntSentinel, DateTimeSentinel)) + await using (var context = new BlogContextNonKeyReadOnlyDefaultValue(testStore.Name, OnModelCreating, IntSentinel, DateTimeSentinel)) { var blogs = context.Blogs.OrderBy(e => e.Id).ToList(); @@ -861,7 +861,7 @@ public async Task Insert_with_non_key_default_value_readonly() context.SaveChanges(); } - using (var context = new BlogContextNonKeyReadOnlyDefaultValue(testStore.Name, OnModelCreating, IntSentinel, DateTimeSentinel)) + await using (var context = new BlogContextNonKeyReadOnlyDefaultValue(testStore.Name, OnModelCreating, IntSentinel, DateTimeSentinel)) { var blogs = context.Blogs.OrderBy(e => e.Id).ToList(); @@ -897,8 +897,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalFact] public async Task Insert_and_update_with_computed_column() { - using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); - using (var context = new BlogContextComputedColumn(testStore.Name, OnModelCreating, IntSentinel, StringSentinel)) + await using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using (var context = new BlogContextComputedColumn(testStore.Name, OnModelCreating, IntSentinel, StringSentinel)) { context.Database.EnsureCreatedResiliently(); @@ -916,7 +916,7 @@ public async Task Insert_and_update_with_computed_column() Assert.Equal("One Unicorn", blog.FullName); } - using (var context = new BlogContextComputedColumn(testStore.Name, OnModelCreating, IntSentinel, StringSentinel)) + await using (var context = new BlogContextComputedColumn(testStore.Name, OnModelCreating, IntSentinel, StringSentinel)) { var blog = context.FullNameBlogs.Single(); @@ -974,8 +974,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalFact] public async Task Insert_and_update_with_computed_column_with_function() { - using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); - using (var context = new BlogContextComputedColumnWithFunction(testStore.Name, OnModelCreating, IntSentinel, StringSentinel)) + await using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using (var context = new BlogContextComputedColumnWithFunction(testStore.Name, OnModelCreating, IntSentinel, StringSentinel)) { context.Database.ExecuteSqlRaw ( @@ -986,7 +986,7 @@ public async Task Insert_and_update_with_computed_column_with_function() context.GetService().CreateTables(); } - using (var context = new BlogContextComputedColumnWithFunction(testStore.Name, OnModelCreating, IntSentinel, StringSentinel)) + await using (var context = new BlogContextComputedColumnWithFunction(testStore.Name, OnModelCreating, IntSentinel, StringSentinel)) { var blog = context.Add( new FullNameBlog @@ -1002,7 +1002,7 @@ public async Task Insert_and_update_with_computed_column_with_function() Assert.Equal("OneUnicorn", blog.FullName); } - using (var context = new BlogContextComputedColumnWithFunction(testStore.Name, OnModelCreating, IntSentinel, StringSentinel)) + await using (var context = new BlogContextComputedColumnWithFunction(testStore.Name, OnModelCreating, IntSentinel, StringSentinel)) { var blog = context.FullNameBlogs.Single(); @@ -1136,7 +1136,10 @@ RETURN @FullName DatabaseName, OnModelCreating, IntSentinel, StringSentinel); context.Database.ExecuteSqlRaw("ALTER TABLE dbo.FullNameBlogs DROP COLUMN FullName;"); context.Database.ExecuteSqlRaw("DROP FUNCTION [dbo].[GetFullName];"); - testStore?.Dispose(); + if (testStore is not null) + { + await testStore.DisposeAsync(); + } } } @@ -1144,8 +1147,8 @@ RETURN @FullName [MemberData(nameof(IsAsyncData))] public async Task Insert_with_computed_column_with_function_without_metadata_configuration(bool async) { - using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); - using (var context = new BlogContextComputedColumn(testStore.Name, OnModelCreating, IntSentinel, StringSentinel)) + await using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using (var context = new BlogContextComputedColumn(testStore.Name, OnModelCreating, IntSentinel, StringSentinel)) { context.GetService().CreateTables(); @@ -1165,7 +1168,7 @@ RETURN @FullName try { - using (var context = new BlogContextComputedColumn(testStore.Name, OnModelCreating, IntSentinel, StringSentinel)) + await using (var context = new BlogContextComputedColumn(testStore.Name, OnModelCreating, IntSentinel, StringSentinel)) { await context.AddAsync(new FullNameBlog { Id = IntSentinel, FullName = StringSentinel }); @@ -1181,7 +1184,7 @@ RETURN @FullName } finally { - using var context = new BlogContextComputedColumnWithTriggerMetadata( + await using var context = new BlogContextComputedColumnWithTriggerMetadata( testStore.Name, OnModelCreating, IntSentinel, StringSentinel); context.Database.ExecuteSqlRaw("ALTER TABLE dbo.FullNameBlogs DROP COLUMN FullName;"); context.Database.ExecuteSqlRaw("DROP FUNCTION [dbo].[GetFullName];"); @@ -1194,8 +1197,8 @@ public async Task Insert_with_trigger_without_metadata_configuration(bool async) { // Execute an insert against a table which has a trigger, but which haven't identified as such in our metadata. // This causes a specialized exception to be thrown, directing users to the relevant docs. - using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); - using (var context = new BlogContextComputedColumn(testStore.Name, OnModelCreating, IntSentinel, StringSentinel)) + await using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using (var context = new BlogContextComputedColumn(testStore.Name, OnModelCreating, IntSentinel, StringSentinel)) { context.GetService().CreateTables(); @@ -1211,7 +1214,7 @@ ON [FullNameBlogs] try { - using (var context = new BlogContextComputedColumn(testStore.Name, OnModelCreating, IntSentinel, StringSentinel)) + await using (var context = new BlogContextComputedColumn(testStore.Name, OnModelCreating, IntSentinel, StringSentinel)) { await context.AddAsync(new FullNameBlog { Id = IntSentinel, FullName = StringSentinel }); @@ -1227,7 +1230,7 @@ ON [FullNameBlogs] } finally { - using var context = new BlogContextComputedColumn(testStore.Name, OnModelCreating, IntSentinel, StringSentinel); + await using var context = new BlogContextComputedColumn(testStore.Name, OnModelCreating, IntSentinel, StringSentinel); context.Database.ExecuteSqlRaw("DROP TRIGGER [FullNameBlogs_Trigger]"); } } @@ -1235,9 +1238,9 @@ ON [FullNameBlogs] [ConditionalFact] public async Task Insert_with_client_generated_GUID_key() { - using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); Guid afterSave; - using (var context = new BlogContextClientGuidKey(testStore.Name, OnModelCreating, GuidSentinel)) + await using (var context = new BlogContextClientGuidKey(testStore.Name, OnModelCreating, GuidSentinel)) { context.Database.EnsureCreatedResiliently(); @@ -1264,7 +1267,7 @@ public async Task Insert_with_client_generated_GUID_key() Assert.Equal(beforeSaveNotId, afterSaveNotId); } - using (var context = new BlogContextClientGuidKey(testStore.Name, OnModelCreating, GuidSentinel)) + await using (var context = new BlogContextClientGuidKey(testStore.Name, OnModelCreating, GuidSentinel)) { Assert.Equal(afterSave, context.GuidBlogs.Single().Id); } @@ -1290,11 +1293,11 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) } [ConditionalFact] - [SqlServerCondition(SqlServerCondition.IsNotSqlAzure)] + [SqlServerCondition(SqlServerCondition.IsNotAzureSql)] public async Task Insert_with_ValueGeneratedOnAdd_GUID_nonkey_property_throws() { - using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); - using var context = new BlogContextClientGuidNonKey(testStore.Name, OnModelCreating, GuidSentinel); + await using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using var context = new BlogContextClientGuidNonKey(testStore.Name, OnModelCreating, GuidSentinel); context.Database.EnsureCreatedResiliently(); var blog = context.Add( @@ -1333,9 +1336,9 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalFact] public async Task Insert_with_server_generated_GUID_key() { - using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); Guid afterSave; - using (var context = new BlogContextServerGuidKey(testStore.Name, OnModelCreating, GuidSentinel)) + await using (var context = new BlogContextServerGuidKey(testStore.Name, OnModelCreating, GuidSentinel)) { context.Database.EnsureCreatedResiliently(); @@ -1364,7 +1367,7 @@ public async Task Insert_with_server_generated_GUID_key() Assert.NotEqual(beforeSaveNotId, afterSaveNotId); } - using (var context = new BlogContextServerGuidKey(testStore.Name, OnModelCreating, GuidSentinel)) + await using (var context = new BlogContextServerGuidKey(testStore.Name, OnModelCreating, GuidSentinel)) { Assert.Equal(afterSave, context.GuidBlogs.Single().Id); } @@ -1393,8 +1396,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalFact] public async Task Insert_with_explicit_non_default_keys_by_default() { - using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); - using var context = new BlogContext(testStore.Name, OnModelCreating); + await using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using var context = new BlogContext(testStore.Name, OnModelCreating); context.Database.EnsureCreatedResiliently(); context.AddRange( @@ -1410,8 +1413,8 @@ public async Task Insert_with_explicit_non_default_keys_by_default() [ConditionalFact] public async Task Insert_with_explicit_default_keys() { - using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); - using var context = new BlogContext(testStore.Name, OnModelCreating); + await using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using var context = new BlogContext(testStore.Name, OnModelCreating); context.Database.EnsureCreatedResiliently(); context.AddRange( @@ -1430,8 +1433,8 @@ public class BlogContext(string databaseName, Action modelBuilder) [ConditionalFact] public async Task Insert_with_implicit_default_keys() { - using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); - using (var context = new BlogContextSpecifyKeysUsingDefault(testStore.Name, OnModelCreating, IntSentinel)) + await using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using (var context = new BlogContextSpecifyKeysUsingDefault(testStore.Name, OnModelCreating, IntSentinel)) { context.Database.EnsureCreatedResiliently(); @@ -1441,7 +1444,7 @@ public async Task Insert_with_implicit_default_keys() context.SaveChanges(); } - using (var context = new BlogContextSpecifyKeysUsingDefault(testStore.Name, OnModelCreating, IntSentinel)) + await using (var context = new BlogContextSpecifyKeysUsingDefault(testStore.Name, OnModelCreating, IntSentinel)) { var blogs = context.Blogs.OrderBy(e => e.Id).ToList(); @@ -1470,8 +1473,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalFact] public async Task Insert_explicit_value_throws_when_readonly_sequence_before_save() { - using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); - using var context = new BlogContextReadOnlySequenceKeyColumnWithDefaultValue(testStore.Name, OnModelCreating, IntSentinel); + await using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using var context = new BlogContextReadOnlySequenceKeyColumnWithDefaultValue(testStore.Name, OnModelCreating, IntSentinel); context.Database.EnsureCreatedResiliently(); context.AddRange( @@ -1508,8 +1511,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalFact] public async Task Insert_explicit_value_throws_when_readonly_before_save() { - using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); - using var context = new BlogContextNonKeyReadOnlyDefaultValue(testStore.Name, OnModelCreating, IntSentinel, DateTimeSentinel); + await using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using var context = new BlogContextNonKeyReadOnlyDefaultValue(testStore.Name, OnModelCreating, IntSentinel, DateTimeSentinel); context.Database.EnsureCreatedResiliently(); context.AddRange( @@ -1536,8 +1539,8 @@ public async Task Insert_explicit_value_throws_when_readonly_before_save() [ConditionalFact] public async Task Insert_explicit_value_into_computed_column() { - using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); - using var context = new BlogContextComputedColumn(testStore.Name, OnModelCreating, IntSentinel, StringSentinel); + await using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using var context = new BlogContextComputedColumn(testStore.Name, OnModelCreating, IntSentinel, StringSentinel); context.Database.EnsureCreatedResiliently(); context.Add( @@ -1559,8 +1562,8 @@ public async Task Insert_explicit_value_into_computed_column() [ConditionalFact] public async Task Update_explicit_value_in_computed_column() { - using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); - using (var context = new BlogContextComputedColumn(testStore.Name, OnModelCreating, IntSentinel, StringSentinel)) + await using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using (var context = new BlogContextComputedColumn(testStore.Name, OnModelCreating, IntSentinel, StringSentinel)) { context.Database.EnsureCreatedResiliently(); @@ -1576,7 +1579,7 @@ public async Task Update_explicit_value_in_computed_column() context.SaveChanges(); } - using (var context = new BlogContextComputedColumn(testStore.Name, OnModelCreating, IntSentinel, StringSentinel)) + await using (var context = new BlogContextComputedColumn(testStore.Name, OnModelCreating, IntSentinel, StringSentinel)) { var blog = context.FullNameBlogs.Single(); @@ -1594,8 +1597,8 @@ public async Task Update_explicit_value_in_computed_column() [ConditionalFact] public async Task Resolve_concurrency() { - using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); - using var context = new BlogContextConcurrencyWithRowversion(testStore.Name, OnModelCreating, IntSentinel, TimestampSentinel); + await using var testStore = await SqlServerTestStore.CreateInitializedAsync(DatabaseName); + await using var context = new BlogContextConcurrencyWithRowversion(testStore.Name, OnModelCreating, IntSentinel, TimestampSentinel); context.Database.EnsureCreatedResiliently(); var blog = context.Add( @@ -1608,7 +1611,7 @@ public async Task Resolve_concurrency() context.SaveChanges(); - using var innerContext = new BlogContextConcurrencyWithRowversion(testStore.Name, OnModelCreating, IntSentinel, TimestampSentinel); + await using var innerContext = new BlogContextConcurrencyWithRowversion(testStore.Name, OnModelCreating, IntSentinel, TimestampSentinel); var updatedBlog = innerContext.ConcurrentBlogs.Single(); updatedBlog.Name = "One Pegasus"; innerContext.SaveChanges(); diff --git a/test/EFCore.SqlServer.FunctionalTests/StoreGeneratedSentinelSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/StoreGeneratedSentinelSqlServerTest.cs index 01dad9849aa..03aaa9ddb21 100644 --- a/test/EFCore.SqlServer.FunctionalTests/StoreGeneratedSentinelSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/StoreGeneratedSentinelSqlServerTest.cs @@ -3,8 +3,9 @@ namespace Microsoft.EntityFrameworkCore; -public class StoreGeneratedSentinelSqlServerTest(StoreGeneratedSentinelSqlServerTest.StoreGeneratedSentinelSqlServerFixture fixture) : StoreGeneratedSqlServerTestBase< - StoreGeneratedSentinelSqlServerTest.StoreGeneratedSentinelSqlServerFixture>(fixture) +public class StoreGeneratedSentinelSqlServerTest(StoreGeneratedSentinelSqlServerTest.StoreGeneratedSentinelSqlServerFixture fixture) + : StoreGeneratedSqlServerTestBase< + StoreGeneratedSentinelSqlServerTest.StoreGeneratedSentinelSqlServerFixture>(fixture) { public class StoreGeneratedSentinelSqlServerFixture : StoreGeneratedSqlServerFixtureBase { diff --git a/test/EFCore.SqlServer.FunctionalTests/StoreGeneratedSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/StoreGeneratedSqlServerTest.cs index f1e11fc06f3..da2902d4f8d 100644 --- a/test/EFCore.SqlServer.FunctionalTests/StoreGeneratedSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/StoreGeneratedSqlServerTest.cs @@ -3,7 +3,8 @@ namespace Microsoft.EntityFrameworkCore; -public class StoreGeneratedSqlServerTest(StoreGeneratedSqlServerTest.StoreGeneratedSqlServerFixture fixture) : StoreGeneratedSqlServerTestBase(fixture) +public class StoreGeneratedSqlServerTest(StoreGeneratedSqlServerTest.StoreGeneratedSqlServerFixture fixture) + : StoreGeneratedSqlServerTestBase(fixture) { public class StoreGeneratedSqlServerFixture : StoreGeneratedSqlServerFixtureBase { diff --git a/test/EFCore.SqlServer.FunctionalTests/TestUtilities/AzureSynapseTestStore.cs b/test/EFCore.SqlServer.FunctionalTests/TestUtilities/AzureSynapseTestStore.cs new file mode 100644 index 00000000000..3b7a628a676 --- /dev/null +++ b/test/EFCore.SqlServer.FunctionalTests/TestUtilities/AzureSynapseTestStore.cs @@ -0,0 +1,50 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#pragma warning disable IDE0022 // Use block body for methods +// ReSharper disable SuggestBaseTypeForParameter +namespace Microsoft.EntityFrameworkCore.TestUtilities; + +public class AzureSynapseTestStore : SqlServerTestStore +{ + public new static async Task GetNorthwindStoreAsync() + => (AzureSynapseTestStore)await SqlServerNorthwindTestStoreFactory.Instance + .GetOrCreate(SqlServerNorthwindTestStoreFactory.Name).InitializeAsync(null, (Func?)null); + + public new static AzureSynapseTestStore GetOrCreate(string name) + => new(name); + + public new static async Task GetOrCreateInitializedAsync(string name) + => (AzureSynapseTestStore)await new AzureSynapseTestStore(name).InitializeSqlServerAsync(null, (Func?)null, null); + + public new static AzureSynapseTestStore GetOrCreateWithInitScript(string name, string initScript) + => new(name, initScript: initScript); + + public new static AzureSynapseTestStore GetOrCreateWithScriptPath( + string name, + string scriptPath, + bool? multipleActiveResultSets = null, + bool shared = true) + => new(name, scriptPath: scriptPath, multipleActiveResultSets: multipleActiveResultSets, shared: shared); + + public new static AzureSynapseTestStore Create(string name, bool useFileName = false) + => new(name, useFileName, shared: false); + + public new static async Task CreateInitializedAsync( + string name, + bool useFileName = false, + bool? multipleActiveResultSets = null) + => (AzureSynapseTestStore)await new AzureSynapseTestStore(name, useFileName, shared: false, multipleActiveResultSets: multipleActiveResultSets) + .InitializeSqlServerAsync(null, (Func?)null, null); + + protected AzureSynapseTestStore(string name, bool useFileName = false, bool? multipleActiveResultSets = null, string? initScript = null, string? scriptPath = null, bool shared = true) + : base(name, useFileName, multipleActiveResultSets, initScript, scriptPath, shared) + { + } + + public override DbContextOptionsBuilder AddProviderOptions(DbContextOptionsBuilder builder) + => (UseConnectionString + ? builder.UseAzureSynapse(ConnectionString, b => b.ApplyConfiguration()) + : builder.UseAzureSynapse(Connection, b => b.ApplyConfiguration())) + .ConfigureWarnings(b => b.Ignore(SqlServerEventId.SavepointsDisabledBecauseOfMARS)); +} diff --git a/test/EFCore.SqlServer.FunctionalTests/TestUtilities/AzureSynapseTestStoreFactory.cs b/test/EFCore.SqlServer.FunctionalTests/TestUtilities/AzureSynapseTestStoreFactory.cs new file mode 100644 index 00000000000..d7e50e56ee4 --- /dev/null +++ b/test/EFCore.SqlServer.FunctionalTests/TestUtilities/AzureSynapseTestStoreFactory.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.TestUtilities; + +public class AzureSynapseTestStoreFactory : RelationalTestStoreFactory +{ + public static AzureSynapseTestStoreFactory Instance { get; } = new(); + + protected AzureSynapseTestStoreFactory() + { + } + + public override TestStore Create(string storeName) + => AzureSynapseTestStore.Create(storeName); + + public override TestStore GetOrCreate(string storeName) + => AzureSynapseTestStore.GetOrCreate(storeName); + + public override IServiceCollection AddProviderServices(IServiceCollection serviceCollection) + => serviceCollection + .AddEntityFrameworkAzureSynapse(); +} diff --git a/test/EFCore.SqlServer.FunctionalTests/TestUtilities/SqlServerCondition.cs b/test/EFCore.SqlServer.FunctionalTests/TestUtilities/SqlServerCondition.cs index 031ff85e9d6..24b17c653ef 100644 --- a/test/EFCore.SqlServer.FunctionalTests/TestUtilities/SqlServerCondition.cs +++ b/test/EFCore.SqlServer.FunctionalTests/TestUtilities/SqlServerCondition.cs @@ -6,8 +6,8 @@ namespace Microsoft.EntityFrameworkCore.TestUtilities; [Flags] public enum SqlServerCondition { - IsSqlAzure = 1 << 0, - IsNotSqlAzure = 1 << 1, + IsAzureSql = 1 << 0, + IsNotAzureSql = 1 << 1, SupportsMemoryOptimized = 1 << 2, SupportsAttach = 1 << 3, SupportsHiddenColumns = 1 << 4, @@ -21,4 +21,5 @@ public enum SqlServerCondition SupportsFunctions2017 = 1 << 12, SupportsFunctions2019 = 1 << 13, SupportsFunctions2022 = 1 << 14, + SupportsJsonType = 1 << 15, } diff --git a/test/EFCore.SqlServer.FunctionalTests/TestUtilities/SqlServerConditionAttribute.cs b/test/EFCore.SqlServer.FunctionalTests/TestUtilities/SqlServerConditionAttribute.cs index a28352fad6e..f2c4c635fb0 100644 --- a/test/EFCore.SqlServer.FunctionalTests/TestUtilities/SqlServerConditionAttribute.cs +++ b/test/EFCore.SqlServer.FunctionalTests/TestUtilities/SqlServerConditionAttribute.cs @@ -25,12 +25,12 @@ public ValueTask IsMetAsync() isMet &= TestEnvironment.IsMemoryOptimizedTablesSupported; } - if (Conditions.HasFlag(SqlServerCondition.IsSqlAzure)) + if (Conditions.HasFlag(SqlServerCondition.IsAzureSql)) { isMet &= TestEnvironment.IsSqlAzure; } - if (Conditions.HasFlag(SqlServerCondition.IsNotSqlAzure)) + if (Conditions.HasFlag(SqlServerCondition.IsNotAzureSql)) { isMet &= !TestEnvironment.IsSqlAzure; } @@ -92,6 +92,11 @@ public ValueTask IsMetAsync() isMet &= TestEnvironment.IsFunctions2022Supported; } + if (Conditions.HasFlag(SqlServerCondition.SupportsJsonType)) + { + isMet &= TestEnvironment.IsJsonTypeSupported; + } + return ValueTask.FromResult(isMet); } diff --git a/test/EFCore.SqlServer.FunctionalTests/TestUtilities/SqlServerDbContextOptionsBuilderExtensions.cs b/test/EFCore.SqlServer.FunctionalTests/TestUtilities/SqlServerDbContextOptionsBuilderExtensions.cs index 0751a0eb769..01998ce74f7 100644 --- a/test/EFCore.SqlServer.FunctionalTests/TestUtilities/SqlServerDbContextOptionsBuilderExtensions.cs +++ b/test/EFCore.SqlServer.FunctionalTests/TestUtilities/SqlServerDbContextOptionsBuilderExtensions.cs @@ -21,4 +21,38 @@ public static SqlServerDbContextOptionsBuilder ApplyConfiguration(this SqlServer return optionsBuilder; } + + public static AzureSqlDbContextOptionsBuilder ApplyConfiguration(this AzureSqlDbContextOptionsBuilder optionsBuilder) + { + var maxBatch = TestEnvironment.GetInt(nameof(SqlServerDbContextOptionsBuilder.MaxBatchSize)); + if (maxBatch.HasValue) + { + optionsBuilder.MaxBatchSize(maxBatch.Value); + } + + optionsBuilder.UseQuerySplittingBehavior(QuerySplittingBehavior.SingleQuery); + + optionsBuilder.ExecutionStrategy(d => new TestSqlServerRetryingExecutionStrategy(d)); + + optionsBuilder.CommandTimeout(SqlServerTestStore.CommandTimeout); + + return optionsBuilder; + } + + public static AzureSynapseDbContextOptionsBuilder ApplyConfiguration(this AzureSynapseDbContextOptionsBuilder optionsBuilder) + { + var maxBatch = TestEnvironment.GetInt(nameof(SqlServerDbContextOptionsBuilder.MaxBatchSize)); + if (maxBatch.HasValue) + { + optionsBuilder.MaxBatchSize(maxBatch.Value); + } + + optionsBuilder.UseQuerySplittingBehavior(QuerySplittingBehavior.SingleQuery); + + optionsBuilder.ExecutionStrategy(d => new TestSqlServerRetryingExecutionStrategy(d)); + + optionsBuilder.CommandTimeout(SqlServerTestStore.CommandTimeout); + + return optionsBuilder; + } } diff --git a/test/EFCore.SqlServer.FunctionalTests/TestUtilities/SqlServerTestStore.cs b/test/EFCore.SqlServer.FunctionalTests/TestUtilities/SqlServerTestStore.cs index 6ad3e77667b..5cc5dc08056 100644 --- a/test/EFCore.SqlServer.FunctionalTests/TestUtilities/SqlServerTestStore.cs +++ b/test/EFCore.SqlServer.FunctionalTests/TestUtilities/SqlServerTestStore.cs @@ -50,7 +50,7 @@ public static async Task CreateInitializedAsync( private readonly string? _initScript; private readonly string? _scriptPath; - private SqlServerTestStore( + protected SqlServerTestStore( string name, bool useFileName = false, bool? multipleActiveResultSets = null, @@ -86,7 +86,7 @@ public async Task InitializeSqlServerAsync( protected override async Task InitializeAsync(Func createContext, Func? seed, Func? clean) { - if (await CreateDatabase(clean)) + if (await CreateDatabaseAsync(clean)) { if (_scriptPath != null) { @@ -112,47 +112,43 @@ protected override async Task InitializeAsync(Func createContext, Fun public override DbContextOptionsBuilder AddProviderOptions(DbContextOptionsBuilder builder) => (UseConnectionString - ? builder.UseSqlServer(ConnectionString, b => b.ApplyConfiguration()) - : builder.UseSqlServer(Connection, b => b.ApplyConfiguration())) + ? builder.UseSqlServer(ConnectionString, b => b.ApplyConfiguration()) + : builder.UseSqlServer(Connection, b => b.ApplyConfiguration())) .ConfigureWarnings(b => b.Ignore(SqlServerEventId.SavepointsDisabledBecauseOfMARS)); - private async Task CreateDatabase(Func? clean) + private async Task CreateDatabaseAsync(Func? clean) { - using (var master = new SqlConnection(CreateConnectionString("master", fileName: null, multipleActiveResultSets: false))) + await using var master = new SqlConnection(CreateConnectionString("master", fileName: null, multipleActiveResultSets: false)); + + if (ExecuteScalar(master, $"SELECT COUNT(*) FROM sys.databases WHERE name = N'{Name}'") > 0) { - if (ExecuteScalar(master, $"SELECT COUNT(*) FROM sys.databases WHERE name = N'{Name}'") > 0) + // Only reseed scripted databases during CI runs + if (_scriptPath != null && !TestEnvironment.IsCI) { - // Only reseed scripted databases during CI runs - if (_scriptPath != null && !TestEnvironment.IsCI) - { - return false; - } + return false; + } + + if (_fileName == null) + { + await using var context = new DbContext( + AddProviderOptions(new DbContextOptionsBuilder().EnableServiceProviderCaching(false)).Options); + await CleanAsync(context); - if (_fileName == null) + if (clean != null) { - using var context = new DbContext( - AddProviderOptions( - new DbContextOptionsBuilder() - .EnableServiceProviderCaching(false)) - .Options); - await CleanAsync(context); - - if (clean != null) - { - await clean(context); - } - - return true; + await clean(context); } - // Delete the database to ensure it's recreated with the correct file path - DeleteDatabase(); + return true; } - ExecuteNonQuery(master, GetCreateDatabaseStatement(Name, _fileName)); - WaitForExists((SqlConnection)Connection); + // Delete the database to ensure it's recreated with the correct file path + await DeleteDatabaseAsync(); } + await ExecuteNonQueryAsync(master, GetCreateDatabaseStatement(Name, _fileName)); + await WaitForExistsAsync((SqlConnection)Connection); + return true; } @@ -177,10 +173,10 @@ public void ExecuteScript(string script) return 0; }, ""); - private static void WaitForExists(SqlConnection connection) - => new TestSqlServerRetryingExecutionStrategy().Execute(connection, WaitForExistsImplementation); + private static Task WaitForExistsAsync(SqlConnection connection) + => new TestSqlServerRetryingExecutionStrategy().ExecuteAsync(connection, WaitForExistsImplementation); - private static void WaitForExistsImplementation(SqlConnection connection) + private static async Task WaitForExistsImplementation(SqlConnection connection) { var retryCount = 0; while (true) @@ -189,13 +185,13 @@ private static void WaitForExistsImplementation(SqlConnection connection) { if (connection.State != ConnectionState.Closed) { - connection.Close(); + await connection.CloseAsync(); } SqlConnection.ClearPool(connection); - connection.Open(); - connection.Close(); + await connection.OpenAsync(); + await connection.CloseAsync(); return; } catch (SqlException e) @@ -206,7 +202,7 @@ private static void WaitForExistsImplementation(SqlConnection connection) throw; } - Thread.Sleep(100); + await Task.Delay(100); } } } @@ -237,16 +233,19 @@ private static string GetCreateDatabaseStatement(string name, string? fileName) return result; } - public void DeleteDatabase() + public async Task DeleteDatabaseAsync() { - using var master = new SqlConnection(CreateConnectionString("master")); - ExecuteNonQuery( + await using var master = new SqlConnection(CreateConnectionString("master")); + + await ExecuteNonQueryAsync( master, string.Format( - @"IF EXISTS (SELECT * FROM sys.databases WHERE name = N'{0}') - BEGIN - ALTER DATABASE [{0}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE; - DROP DATABASE [{0}]; - END", Name)); + """ +IF EXISTS (SELECT * FROM sys.databases WHERE name = N'{0}') +BEGIN + ALTER DATABASE [{0}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE; + DROP DATABASE [{0}]; +END +""", Name)); SqlConnection.ClearAllPools(); } @@ -444,14 +443,14 @@ private static DbCommand CreateCommand( return command; } - public override void Dispose() + public override async ValueTask DisposeAsync() { - base.Dispose(); + await base.DisposeAsync(); if (_fileName != null // Clean up the database using a local file, as it might get deleted later || (TestEnvironment.IsSqlAzure && !Shared)) { - DeleteDatabase(); + await DeleteDatabaseAsync(); } } diff --git a/test/EFCore.SqlServer.FunctionalTests/TestUtilities/TestEnvironment.cs b/test/EFCore.SqlServer.FunctionalTests/TestUtilities/TestEnvironment.cs index a93f0517a71..34e7e76ab28 100644 --- a/test/EFCore.SqlServer.FunctionalTests/TestUtilities/TestEnvironment.cs +++ b/test/EFCore.SqlServer.FunctionalTests/TestUtilities/TestEnvironment.cs @@ -398,6 +398,10 @@ public static bool IsFunctions2022Supported } } + // TODO:SQLJSON Issue #34414 + public static bool IsJsonTypeSupported + => false; + public static byte SqlServerMajorVersion => GetProductMajorVersion(); diff --git a/test/EFCore.SqlServer.FunctionalTests/TestUtilities/TestRelationalCommandBuilderFactory.cs b/test/EFCore.SqlServer.FunctionalTests/TestUtilities/TestRelationalCommandBuilderFactory.cs index 574f5e92b8c..7d682aeb67c 100644 --- a/test/EFCore.SqlServer.FunctionalTests/TestUtilities/TestRelationalCommandBuilderFactory.cs +++ b/test/EFCore.SqlServer.FunctionalTests/TestUtilities/TestRelationalCommandBuilderFactory.cs @@ -84,7 +84,7 @@ private class TestRelationalCommand( string commandText, IReadOnlyList parameters) : IRelationalCommand { - private readonly RelationalCommand _realRelationalCommand = new RelationalCommand(dependencies, commandText, parameters); + private readonly RelationalCommand _realRelationalCommand = new(dependencies, commandText, parameters); public string CommandText => _realRelationalCommand.CommandText; diff --git a/test/EFCore.SqlServer.FunctionalTests/TestUtilities/TestRelationalTransaction.cs b/test/EFCore.SqlServer.FunctionalTests/TestUtilities/TestRelationalTransaction.cs index 278d037e5d6..db65a446446 100644 --- a/test/EFCore.SqlServer.FunctionalTests/TestUtilities/TestRelationalTransaction.cs +++ b/test/EFCore.SqlServer.FunctionalTests/TestUtilities/TestRelationalTransaction.cs @@ -21,7 +21,8 @@ public class TestRelationalTransaction( DbTransaction transaction, IDiagnosticsLogger logger, bool transactionOwned, - ISqlGenerationHelper sqlGenerationHelper) : RelationalTransaction(connection, transaction, new Guid(), logger, transactionOwned, sqlGenerationHelper) + ISqlGenerationHelper sqlGenerationHelper) : RelationalTransaction( + connection, transaction, new Guid(), logger, transactionOwned, sqlGenerationHelper) { private readonly TestSqlServerConnection _testConnection = (TestSqlServerConnection)connection; diff --git a/test/EFCore.SqlServer.FunctionalTests/TestUtilities/TestSqlServerRetryingExecutionStrategy.cs b/test/EFCore.SqlServer.FunctionalTests/TestUtilities/TestSqlServerRetryingExecutionStrategy.cs index ec517ff802f..ac0eea2e54c 100644 --- a/test/EFCore.SqlServer.FunctionalTests/TestUtilities/TestSqlServerRetryingExecutionStrategy.cs +++ b/test/EFCore.SqlServer.FunctionalTests/TestUtilities/TestSqlServerRetryingExecutionStrategy.cs @@ -43,6 +43,13 @@ public TestSqlServerRetryingExecutionStrategy(ExecutionStrategyDependencies depe { } + public TestSqlServerRetryingExecutionStrategy( + ExecutionStrategyDependencies dependencies, + IEnumerable errorNumbersToAdd) + : base(dependencies, DefaultMaxRetryCount, DefaultMaxDelay, _additionalErrorNumbers.Concat(errorNumbersToAdd)) + { + } + protected override bool ShouldRetryOn(Exception exception) { if (base.ShouldRetryOn(exception)) diff --git a/test/EFCore.SqlServer.FunctionalTests/TransactionInterceptionSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/TransactionInterceptionSqlServerTest.cs index 6802c817936..8f42c0f6d0d 100644 --- a/test/EFCore.SqlServer.FunctionalTests/TransactionInterceptionSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/TransactionInterceptionSqlServerTest.cs @@ -24,9 +24,9 @@ protected override IServiceCollection InjectInterceptors( } public class TransactionInterceptionSqlServerTest(TransactionInterceptionSqlServerTest.InterceptionSqlServerFixture fixture) - : TransactionInterceptionSqlServerTestBase(fixture), IClassFixture + : TransactionInterceptionSqlServerTestBase(fixture), + IClassFixture { - // ReleaseSavepoint is unsupported by SQL Server and is ignored public override Task Intercept_ReleaseSavepoint(bool async) => Task.CompletedTask; @@ -38,11 +38,11 @@ protected override bool ShouldSubscribeToDiagnosticListener } } - public class TransactionInterceptionWithDiagnosticsSqlServerTest(TransactionInterceptionWithDiagnosticsSqlServerTest.InterceptionSqlServerFixture fixture) + public class TransactionInterceptionWithDiagnosticsSqlServerTest( + TransactionInterceptionWithDiagnosticsSqlServerTest.InterceptionSqlServerFixture fixture) : TransactionInterceptionSqlServerTestBase(fixture), IClassFixture { - // ReleaseSavepoint is unsupported by SQL Server and is ignored public override Task Intercept_ReleaseSavepoint(bool async) => Task.CompletedTask; diff --git a/test/EFCore.SqlServer.FunctionalTests/Update/JsonUpdateJsonTypeSqlServerFixture.cs b/test/EFCore.SqlServer.FunctionalTests/Update/JsonUpdateJsonTypeSqlServerFixture.cs new file mode 100644 index 00000000000..840544363e4 --- /dev/null +++ b/test/EFCore.SqlServer.FunctionalTests/Update/JsonUpdateJsonTypeSqlServerFixture.cs @@ -0,0 +1,74 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#nullable disable +using Microsoft.EntityFrameworkCore.TestModels.JsonQuery; + +namespace Microsoft.EntityFrameworkCore.Update; + +public class JsonUpdateJsonTypeSqlServerFixture : JsonUpdateSqlServerFixture +{ + protected override string StoreName + => "JsonUpdateJsonTypeTest"; + + protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) + { + base.OnModelCreating(modelBuilder, context); + + modelBuilder.Entity( + b => + { + b.OwnsOne(x => x.OwnedReferenceRoot).ToJson().HasColumnType("json"); + b.OwnsMany(x => x.OwnedCollectionRoot).ToJson().HasColumnType("json"); + }); + + modelBuilder.Entity( + b => + { + b.OwnsOne(x => x.ReferenceOnBase).ToJson().HasColumnType("json"); + b.OwnsMany(x => x.CollectionOnBase).ToJson().HasColumnType("json"); + }); + + modelBuilder.Entity( + b => + { + b.HasBaseType(); + b.OwnsOne(x => x.ReferenceOnDerived).ToJson().HasColumnType("json"); + b.OwnsMany(x => x.CollectionOnDerived).ToJson().HasColumnType("json"); + }); + + modelBuilder.Entity( + b => + { + b.OwnsOne(x => x.Reference).ToJson().HasColumnType("json"); + b.OwnsMany(x => x.Collection).ToJson().HasColumnType("json"); + b.PrimitiveCollection(e => e.TestDefaultStringCollection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestMaxLengthStringCollection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestInt16Collection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestInt32Collection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestDecimalCollection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestDateTimeCollection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestDateTimeOffsetCollection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestTimeSpanCollection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestInt64Collection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestDoubleCollection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestSingleCollection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestBooleanCollection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestCharacterCollection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestByteCollection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestGuidCollection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestUnsignedInt16Collection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestUnsignedInt32Collection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestUnsignedInt64Collection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestSignedByteCollection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestNullableInt32Collection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestEnumCollection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestEnumWithIntConverterCollection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestNullableEnumCollection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestNullableEnumWithIntConverterCollection).HasColumnType("json"); + b.PrimitiveCollection(e => e.TestNullableEnumWithConverterThatHandlesNullsCollection).HasColumnType("json"); + }); + + modelBuilder.Entity().OwnsOne(x => x.Reference).ToJson().HasColumnType("json"); + } +} diff --git a/test/EFCore.SqlServer.FunctionalTests/Update/JsonUpdateJsonTypeSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Update/JsonUpdateJsonTypeSqlServerTest.cs new file mode 100644 index 00000000000..b21adf1969f --- /dev/null +++ b/test/EFCore.SqlServer.FunctionalTests/Update/JsonUpdateJsonTypeSqlServerTest.cs @@ -0,0 +1,2961 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#nullable disable +using Xunit.Sdk; + +namespace Microsoft.EntityFrameworkCore.Update; + +[SqlServerCondition(SqlServerCondition.SupportsJsonType)] +public class JsonUpdateJsonTypeSqlServerTest : JsonUpdateTestBase +{ + public JsonUpdateJsonTypeSqlServerTest(JsonUpdateJsonTypeSqlServerFixture fixture) + : base(fixture) + => ClearLog(); + + [ConditionalFact] + public virtual void Check_all_tests_overridden() + => TestHelpers.AssertAllMethodsOverridden(GetType()); + + public override async Task Add_element_to_json_collection_branch() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Add_element_to_json_collection_branch())).InnerException?.Message); + + AssertSql( + """ +@p0='[{"Date":"2101-01-01T00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":10.1,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_c1_c1"},{"SomethingSomething":"e1_r_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_c1_r"}},{"Date":"2102-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":10.2,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_c2_c1"},{"SomethingSomething":"e1_r_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_c2_r"}},{"Date":"2010-10-10T00:00:00","Enum":-3,"Enums":null,"Fraction":42.42,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":[{"SomethingSomething":"ss1"},{"SomethingSomething":"ss2"}],"OwnedReferenceLeaf":{"SomethingSomething":"ss3"}}]' (Nullable = false) (Size = 789) +@p1='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesBasic] SET [OwnedReferenceRoot] = JSON_MODIFY([OwnedReferenceRoot], 'strict $.OwnedCollectionBranch', JSON_QUERY(@p0)) +OUTPUT 1 +WHERE [Id] = @p1; +"""); + } + + public override async Task Add_element_to_json_collection_leaf() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Add_element_to_json_collection_leaf())).InnerException?.Message); + + AssertSql( + """ +@p0='[{"SomethingSomething":"e1_r_r_c1"},{"SomethingSomething":"e1_r_r_c2"},{"SomethingSomething":"ss1"}]' (Nullable = false) (Size = 100) +@p1='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesBasic] SET [OwnedReferenceRoot] = JSON_MODIFY([OwnedReferenceRoot], 'strict $.OwnedReferenceBranch.OwnedCollectionLeaf', JSON_QUERY(@p0)) +OUTPUT 1 +WHERE [Id] = @p1; +"""); + } + + public override async Task Add_element_to_json_collection_on_derived() + { + await base.Add_element_to_json_collection_on_derived(); + + AssertSql( + """ +@p0='[{"Date":"2221-01-01T00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":221.1,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"d2_r_c1"},{"SomethingSomething":"d2_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"d2_r_r"}},{"Date":"2222-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":222.1,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"d2_r_c1"},{"SomethingSomething":"d2_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"d2_r_r"}},{"Date":"2010-10-10T00:00:00","Enum":-3,"Enums":null,"Fraction":42.42,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":[{"SomethingSomething":"ss1"},{"SomethingSomething":"ss2"}],"OwnedReferenceLeaf":{"SomethingSomething":"ss3"}}]' (Nullable = false) (Size = 773) +@p1='2' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesInheritance] SET [CollectionOnDerived] = @p0 +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[Discriminator], [j].[Name], [j].[Fraction], [j].[CollectionOnBase], [j].[ReferenceOnBase], [j].[CollectionOnDerived], [j].[ReferenceOnDerived] +FROM [JsonEntitiesInheritance] AS [j] +WHERE [j].[Discriminator] = N'JsonEntityInheritanceDerived' +"""); + } + + public override async Task Add_element_to_json_collection_root() + { + await base.Add_element_to_json_collection_root(); + + AssertSql( + """ +@p0='[{"Name":"e1_c1","Names":["e1_c11","e1_c12"],"Number":11,"Numbers":[-1000,0,1000],"OwnedCollectionBranch":[{"Date":"2111-01-01T00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":11.1,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_c1_c1"},{"SomethingSomething":"e1_c1_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c1_r"}},{"Date":"2112-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":11.2,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_c2_c1"},{"SomethingSomething":"e1_c1_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c2_r"}}],"OwnedReferenceBranch":{"Date":"2110-01-01T00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":11.0,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_r_c1"},{"SomethingSomething":"e1_c1_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_r_r"}}},{"Name":"e1_c2","Names":["e1_c21","e1_c22"],"Number":12,"Numbers":[-1001,0,1001],"OwnedCollectionBranch":[{"Date":"2121-01-01T00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":12.1,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_c1_c1"},{"SomethingSomething":"e1_c2_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_c1_r"}},{"Date":"2122-01-01T00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":12.2,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_c2_c1"},{"SomethingSomething":"e1_c2_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_c2_r"}}],"OwnedReferenceBranch":{"Date":"2120-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":12.0,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_r_c1"},{"SomethingSomething":"e1_c2_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_r_r"}}},{"Name":"new Name","Names":null,"Number":142,"Numbers":null,"OwnedCollectionBranch":[],"OwnedReferenceBranch":{"Date":"2010-10-10T00:00:00","Enum":-3,"Enums":null,"Fraction":42.42,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":[{"SomethingSomething":"ss1"},{"SomethingSomething":"ss2"}],"OwnedReferenceLeaf":{"SomethingSomething":"ss3"}}}]' (Nullable = false) (Size = 2268) +@p1='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesBasic] SET [OwnedCollectionRoot] = @p0 +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Add_element_to_json_collection_root_null_navigations() + { + await base.Add_element_to_json_collection_root_null_navigations(); + + AssertSql( + """ +@p0='[{"Name":"e1_c1","Names":["e1_c11","e1_c12"],"Number":11,"Numbers":[-1000,0,1000],"OwnedCollectionBranch":[{"Date":"2111-01-01T00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":11.1,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_c1_c1"},{"SomethingSomething":"e1_c1_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c1_r"}},{"Date":"2112-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":11.2,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_c2_c1"},{"SomethingSomething":"e1_c1_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c2_r"}}],"OwnedReferenceBranch":{"Date":"2110-01-01T00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":11.0,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_r_c1"},{"SomethingSomething":"e1_c1_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_r_r"}}},{"Name":"e1_c2","Names":["e1_c21","e1_c22"],"Number":12,"Numbers":[-1001,0,1001],"OwnedCollectionBranch":[{"Date":"2121-01-01T00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":12.1,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_c1_c1"},{"SomethingSomething":"e1_c2_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_c1_r"}},{"Date":"2122-01-01T00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":12.2,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_c2_c1"},{"SomethingSomething":"e1_c2_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_c2_r"}}],"OwnedReferenceBranch":{"Date":"2120-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":12.0,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_r_c1"},{"SomethingSomething":"e1_c2_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_r_r"}}},{"Name":"new Name","Names":null,"Number":142,"Numbers":null,"OwnedCollectionBranch":null,"OwnedReferenceBranch":{"Date":"2010-10-10T00:00:00","Enum":-3,"Enums":null,"Fraction":42.42,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":null,"OwnedReferenceLeaf":null}}]' (Nullable = false) (Size = 2191) +@p1='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesBasic] SET [OwnedCollectionRoot] = @p0 +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Add_entity_with_json() + { + await base.Add_entity_with_json(); + + AssertSql( + """ +@p0='{"Name":"RootName","Names":null,"Number":42,"Numbers":null,"OwnedCollectionBranch":[],"OwnedReferenceBranch":{"Date":"2010-10-10T00:00:00","Enum":-3,"Enums":null,"Fraction":42.42,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":[{"SomethingSomething":"ss1"},{"SomethingSomething":"ss2"}],"OwnedReferenceLeaf":{"SomethingSomething":"ss3"}}}' (Nullable = false) (Size = 353) +@p1='[]' (Nullable = false) (Size = 2) +@p2='2' +@p3=NULL (DbType = Int32) +@p4='NewEntity' (Size = 4000) + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +INSERT INTO [JsonEntitiesBasic] ([OwnedReferenceRoot], [OwnedCollectionRoot], [Id], [EntityBasicId], [Name]) +VALUES (@p0, @p1, @p2, @p3, @p4); +""", + // + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Add_entity_with_json_null_navigations() + { + // TODO:SQLJSON Updates to null fail (See UpdateToNull.cs) + await Assert.ThrowsAsync( + () => base.Add_entity_with_json_null_navigations()); + + AssertSql( + """ +@p0='{"Name":"RootName","Names":null,"Number":42,"Numbers":null,"OwnedCollectionBranch":null,"OwnedReferenceBranch":{"Date":"2010-10-10T00:00:00","Enum":-3,"Enums":null,"Fraction":42.42,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":[{"SomethingSomething":"ss1"},{"SomethingSomething":"ss2"}],"OwnedReferenceLeaf":null}}' (Nullable = false) (Size = 331) +@p1='2' +@p2=NULL (DbType = Int32) +@p3='NewEntity' (Size = 4000) + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +INSERT INTO [JsonEntitiesBasic] ([OwnedReferenceRoot], [Id], [EntityBasicId], [Name]) +VALUES (@p0, @p1, @p2, @p3); +""", + // + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Add_json_reference_leaf() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Add_json_reference_leaf())).InnerException?.Message); + + AssertSql( + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +""", + // + """ +@p0=NULL (Nullable = false) +@p1='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesBasic] SET [OwnedReferenceRoot] = JSON_MODIFY([OwnedReferenceRoot], 'strict $.OwnedCollectionBranch[0].OwnedReferenceLeaf', JSON_QUERY(@p0)) +OUTPUT 1 +WHERE [Id] = @p1; +"""); + } + + public override async Task Add_json_reference_root() + { + // TODO:SQLJSON Updates to null fail (See UpdateToNull.cs) + await Assert.ThrowsAsync( + () => base.Add_json_reference_root()); + + AssertSql( + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +""", + // + """ +@p0=NULL (Nullable = false) +@p1='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesBasic] SET [OwnedReferenceRoot] = @p0 +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Delete_entity_with_json() + { + await base.Delete_entity_with_json(); + + AssertSql( + """ +@p0='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +DELETE FROM [JsonEntitiesBasic] +OUTPUT 1 +WHERE [Id] = @p0; +""", + // + """ +SELECT COUNT(*) +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Delete_json_collection_branch() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Delete_json_collection_branch())).InnerException?.Message); + + AssertSql( + """ +@p0=NULL (Nullable = false) +@p1='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesBasic] SET [OwnedReferenceRoot] = JSON_MODIFY([OwnedReferenceRoot], 'strict $.OwnedCollectionBranch', JSON_QUERY(@p0)) +OUTPUT 1 +WHERE [Id] = @p1; +"""); + } + + public override async Task Delete_json_collection_root() + { + // TODO:SQLJSON Updates to null fail (See UpdateToNull.cs) + await Assert.ThrowsAsync( + () => base.Delete_json_collection_root()); + + AssertSql( + """ +@p0=NULL (Nullable = false) +@p1='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesBasic] SET [OwnedCollectionRoot] = @p0 +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Delete_json_reference_leaf() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Delete_json_reference_leaf())).InnerException?.Message); + + AssertSql( + """ +@p0=NULL (Nullable = false) +@p1='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesBasic] SET [OwnedReferenceRoot] = JSON_MODIFY([OwnedReferenceRoot], 'strict $.OwnedReferenceBranch.OwnedReferenceLeaf', JSON_QUERY(@p0)) +OUTPUT 1 +WHERE [Id] = @p1; +"""); + } + + public override async Task Delete_json_reference_root() + { + // TODO:SQLJSON Updates to null fail (See UpdateToNull.cs) + await Assert.ThrowsAsync( + () => base.Delete_json_reference_root()); + + AssertSql( + """ +@p0=NULL (Nullable = false) +@p1='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesBasic] SET [OwnedReferenceRoot] = @p0 +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Edit_element_in_json_collection_branch() + { + await base.Edit_element_in_json_collection_branch(); + + AssertSql( + """ +@p0='2111-11-11T00:00:00' (Nullable = false) (Size = 4000) +@p1='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesBasic] SET [OwnedCollectionRoot] = JSON_MODIFY([OwnedCollectionRoot], 'strict $[0].OwnedCollectionBranch[0].Date', @p0) +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Edit_element_in_json_collection_root1() + { + await base.Edit_element_in_json_collection_root1(); + + AssertSql( + """ +@p0='Modified' (Nullable = false) (Size = 4000) +@p1='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesBasic] SET [OwnedCollectionRoot] = JSON_MODIFY([OwnedCollectionRoot], 'strict $[0].Name', @p0) +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Edit_element_in_json_collection_root2() + { + await base.Edit_element_in_json_collection_root2(); + + AssertSql( + """ +@p0='Modified' (Nullable = false) (Size = 4000) +@p1='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesBasic] SET [OwnedCollectionRoot] = JSON_MODIFY([OwnedCollectionRoot], 'strict $[1].Name', @p0) +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Edit_element_in_json_multiple_levels_partial_update() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Edit_element_in_json_multiple_levels_partial_update())).InnerException?.Message); + + AssertSql( + """ +@p0='[{"Date":"2111-01-01T00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":11.1,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"...and another"},{"SomethingSomething":"e1_c1_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c1_r"}},{"Date":"2112-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":11.2,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"yet another change"},{"SomethingSomething":"and another"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c2_r"}}]' (Nullable = false) (Size = 561) +@p1='{"Name":"edit","Names":["e1_r1","e1_r2"],"Number":10,"Numbers":[-2147483648,-1,0,1,2147483647],"OwnedCollectionBranch":[{"Date":"2101-01-01T00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":10.1,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_c1_c1"},{"SomethingSomething":"e1_r_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_c1_r"}},{"Date":"2102-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":10.2,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_c2_c1"},{"SomethingSomething":"e1_r_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_c2_r"}}],"OwnedReferenceBranch":{"Date":"2111-11-11T00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":10.0,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_r_c1"},{"SomethingSomething":"e1_r_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_r_r"}}}' (Nullable = false) (Size = 960) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesBasic] SET [OwnedCollectionRoot] = JSON_MODIFY([OwnedCollectionRoot], 'strict $[0].OwnedCollectionBranch', JSON_QUERY(@p0)), [OwnedReferenceRoot] = @p1 +OUTPUT 1 +WHERE [Id] = @p2; +"""); + } + + public override async Task Edit_element_in_json_branch_collection_and_add_element_to_the_same_collection() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Edit_element_in_json_branch_collection_and_add_element_to_the_same_collection())).InnerException?.Message); + + AssertSql( + """ +@p0='[{"Date":"2101-01-01T00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":4321.3,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_c1_c1"},{"SomethingSomething":"e1_r_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_c1_r"}},{"Date":"2102-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":10.2,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_c2_c1"},{"SomethingSomething":"e1_r_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_c2_r"}},{"Date":"2222-11-11T00:00:00","Enum":-3,"Enums":null,"Fraction":45.32,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":null,"OwnedReferenceLeaf":{"SomethingSomething":"cc"}}]' (Nullable = false) (Size = 735) +@p1='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesBasic] SET [OwnedReferenceRoot] = JSON_MODIFY([OwnedReferenceRoot], 'strict $.OwnedCollectionBranch', JSON_QUERY(@p0)) +OUTPUT 1 +WHERE [Id] = @p1; +"""); + } + + public override async Task Edit_two_elements_in_the_same_json_collection() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Edit_two_elements_in_the_same_json_collection())).InnerException?.Message); + + AssertSql( + """ +@p0='[{"SomethingSomething":"edit1"},{"SomethingSomething":"edit2"}]' (Nullable = false) (Size = 63) +@p1='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesBasic] SET [OwnedReferenceRoot] = JSON_MODIFY([OwnedReferenceRoot], 'strict $.OwnedCollectionBranch[0].OwnedCollectionLeaf', JSON_QUERY(@p0)) +OUTPUT 1 +WHERE [Id] = @p1; +"""); + } + + public override async Task Edit_two_elements_in_the_same_json_collection_at_the_root() + { + await base.Edit_two_elements_in_the_same_json_collection_at_the_root(); + + AssertSql( + """ +@p0='[{"Name":"edit1","Names":["e1_c11","e1_c12"],"Number":11,"Numbers":[-1000,0,1000],"OwnedCollectionBranch":[{"Date":"2111-01-01T00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":11.1,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_c1_c1"},{"SomethingSomething":"e1_c1_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c1_r"}},{"Date":"2112-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":11.2,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_c2_c1"},{"SomethingSomething":"e1_c1_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c2_r"}}],"OwnedReferenceBranch":{"Date":"2110-01-01T00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":11.0,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_r_c1"},{"SomethingSomething":"e1_c1_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_r_r"}}},{"Name":"edit2","Names":["e1_c21","e1_c22"],"Number":12,"Numbers":[-1001,0,1001],"OwnedCollectionBranch":[{"Date":"2121-01-01T00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":12.1,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_c1_c1"},{"SomethingSomething":"e1_c2_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_c1_r"}},{"Date":"2122-01-01T00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":12.2,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_c2_c1"},{"SomethingSomething":"e1_c2_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_c2_r"}}],"OwnedReferenceBranch":{"Date":"2120-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":12.0,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_r_c1"},{"SomethingSomething":"e1_c2_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_r_r"}}}]' (Nullable = false) (Size = 1913) +@p1='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesBasic] SET [OwnedCollectionRoot] = @p0 +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Edit_collection_element_and_reference_at_once() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Edit_collection_element_and_reference_at_once())).InnerException?.Message); + + AssertSql( + """ +@p0='{"Date":"2102-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":10.2,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"edit1"},{"SomethingSomething":"e1_r_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"edit2"}}' (Nullable = false) (Size = 262) +@p1='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesBasic] SET [OwnedReferenceRoot] = JSON_MODIFY([OwnedReferenceRoot], 'strict $.OwnedCollectionBranch[1]', JSON_QUERY(@p0)) +OUTPUT 1 +WHERE [Id] = @p1; +"""); + } + + public override async Task Edit_single_enum_property() + { + await base.Edit_single_enum_property(); + + AssertSql( + """ +@p0='2' +@p1='2' +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesBasic] SET [OwnedCollectionRoot] = JSON_MODIFY([OwnedCollectionRoot], 'strict $[1].OwnedCollectionBranch[1].Enum', @p0), [OwnedReferenceRoot] = JSON_MODIFY([OwnedReferenceRoot], 'strict $.OwnedReferenceBranch.Enum', @p1) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Edit_single_numeric_property() + { + await base.Edit_single_numeric_property(); + + AssertSql( + """ +@p0='1024' +@p1='999' +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesBasic] SET [OwnedCollectionRoot] = JSON_MODIFY([OwnedCollectionRoot], 'strict $[1].Number', @p0), [OwnedReferenceRoot] = JSON_MODIFY([OwnedReferenceRoot], 'strict $.Number', @p1) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +"""); + } + + public override async Task Edit_single_property_bool() + { + await base.Edit_single_property_bool(); + + AssertSql( + """ +@p0='True' +@p1='False' +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestBoolean', @p0), [Reference] = JSON_MODIFY([Reference], 'strict $.TestBoolean', @p1) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_byte() + { + await base.Edit_single_property_byte(); + + AssertSql( + """ +@p0='14' (Size = 1) +@p1='25' (Size = 1) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestByte', @p0), [Reference] = JSON_MODIFY([Reference], 'strict $.TestByte', @p1) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_char() + { + await base.Edit_single_property_char(); + + AssertSql( + """ +@p0='t' (Nullable = false) (Size = 4000) +@p1='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Reference] = JSON_MODIFY([Reference], 'strict $.TestCharacter', @p0) +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_datetime() + { + await base.Edit_single_property_datetime(); + + AssertSql( + """ +@p0='3000-01-01T12:34:56' (Nullable = false) (Size = 4000) +@p1='3000-01-01T12:34:56' (Nullable = false) (Size = 4000) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestDateTime', @p0), [Reference] = JSON_MODIFY([Reference], 'strict $.TestDateTime', @p1) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_datetimeoffset() + { + await base.Edit_single_property_datetimeoffset(); + + AssertSql( + """ +@p0='3000-01-01T12:34:56-04:00' (Nullable = false) (Size = 4000) +@p1='3000-01-01T12:34:56-04:00' (Nullable = false) (Size = 4000) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestDateTimeOffset', @p0), [Reference] = JSON_MODIFY([Reference], 'strict $.TestDateTimeOffset', @p1) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_decimal() + { + // TODO:SQLJSON Cannot insert decimal (See DecimalParameters.cs) + await Assert.ThrowsAsync(() => base.Edit_single_property_decimal()); + + AssertSql( + """ +@p0='-13579.01' (Precision = 18) (Scale = 3) +@p1='-13579.01' (Precision = 18) (Scale = 3) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestDecimal', @p0), [Reference] = JSON_MODIFY([Reference], 'strict $.TestDecimal', @p1) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_double() + { + await base.Edit_single_property_double(); + + AssertSql( + """ +@p0='-1.23579' +@p1='-1.23579' +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestDouble', @p0), [Reference] = JSON_MODIFY([Reference], 'strict $.TestDouble', @p1) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_guid() + { + await base.Edit_single_property_guid(); + + AssertSql( + """ +@p0='12345678-1234-4321-5555-987654321000' (Nullable = false) (Size = 4000) +@p1='12345678-1234-4321-5555-987654321000' (Nullable = false) (Size = 4000) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestGuid', @p0), [Reference] = JSON_MODIFY([Reference], 'strict $.TestGuid', @p1) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_int16() + { + await base.Edit_single_property_int16(); + + AssertSql( + """ +@p0='-3234' +@p1='-3234' +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestInt16', @p0), [Reference] = JSON_MODIFY([Reference], 'strict $.TestInt16', @p1) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_int32() + { + await base.Edit_single_property_int32(); + + AssertSql( + """ +@p0='-3234' +@p1='-3234' +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestInt32', @p0), [Reference] = JSON_MODIFY([Reference], 'strict $.TestInt32', @p1) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_int64() + { + await base.Edit_single_property_int64(); + + AssertSql( + """ +@p0='-3234' +@p1='-3234' +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestInt64', @p0), [Reference] = JSON_MODIFY([Reference], 'strict $.TestInt64', @p1) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_signed_byte() + { + await base.Edit_single_property_signed_byte(); + + AssertSql( + """ +@p0='-108' +@p1='-108' +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestSignedByte', @p0), [Reference] = JSON_MODIFY([Reference], 'strict $.TestSignedByte', @p1) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_single() + { + await base.Edit_single_property_single(); + + AssertSql( + """ +@p0='-7.234' +@p1='-7.234' +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestSingle', @p0), [Reference] = JSON_MODIFY([Reference], 'strict $.TestSingle', @p1) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_timespan() + { + await base.Edit_single_property_timespan(); + + AssertSql( + """ +@p0='10:01:01.007' (Nullable = false) (Size = 4000) +@p1='10:01:01.007' (Nullable = false) (Size = 4000) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestTimeSpan', @p0), [Reference] = JSON_MODIFY([Reference], 'strict $.TestTimeSpan', @p1) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_uint16() + { + await base.Edit_single_property_uint16(); + + AssertSql( + """ +@p0='1534' +@p1='1534' +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestUnsignedInt16', @p0), [Reference] = JSON_MODIFY([Reference], 'strict $.TestUnsignedInt16', @p1) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_uint32() + { + await base.Edit_single_property_uint32(); + + AssertSql( + """ +@p0='1237775789' +@p1='1237775789' +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestUnsignedInt32', @p0), [Reference] = JSON_MODIFY([Reference], 'strict $.TestUnsignedInt32', @p1) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_uint64() + { + // TODO:SQLJSON Cannot insert decimal (See DecimalParameters.cs) + await Assert.ThrowsAsync(() => base.Edit_single_property_uint64()); + + AssertSql( + """ +@p0='1234555555123456789' (Precision = 20) +@p1='1234555555123456789' (Precision = 20) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestUnsignedInt64', @p0), [Reference] = JSON_MODIFY([Reference], 'strict $.TestUnsignedInt64', @p1) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_dateonly() + { + await base.Edit_single_property_dateonly(); + + AssertSql( + """ +@p0='2000-02-04' (Nullable = false) (Size = 4000) +@p1='1023-01-01' (Nullable = false) (Size = 4000) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestDateOnly', @p0), [Reference] = JSON_MODIFY([Reference], 'strict $.TestDateOnly', @p1) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_collection_of_string() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Edit_single_property_collection_of_string())).InnerException?.Message); + + AssertSql( + """ +@p0='["1024","2048"]' (Nullable = false) (Size = 15) +@p1='["999","997"]' (Nullable = false) (Size = 13) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesBasic] SET [OwnedCollectionRoot] = JSON_MODIFY([OwnedCollectionRoot], 'strict $[1].Names', JSON_QUERY(@p0)), [OwnedReferenceRoot] = JSON_MODIFY([OwnedReferenceRoot], 'strict $.Names', JSON_QUERY(@p1)) +OUTPUT 1 +WHERE [Id] = @p2; +"""); + } + + public override async Task Edit_single_property_nullable_int32() + { + await base.Edit_single_property_nullable_int32(); + + AssertSql( + """ +@p0='122354' +@p1='64528' +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestNullableInt32', @p0), [Reference] = JSON_MODIFY([Reference], 'strict $.TestNullableInt32', @p1) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_nullable_int32_set_to_null() + { + await base.Edit_single_property_nullable_int32_set_to_null(); + + AssertSql( + """ +@p0=NULL (Nullable = false) (DbType = Int32) +@p1=NULL (Nullable = false) (DbType = Int32) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestNullableInt32', @p0), [Reference] = JSON_MODIFY([Reference], 'strict $.TestNullableInt32', @p1) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_enum() + { + await base.Edit_single_property_enum(); + + AssertSql( + """ +@p0='-3' +@p1='-3' +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestEnum', @p0), [Reference] = JSON_MODIFY([Reference], 'strict $.TestEnum', @p1) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_enum_with_int_converter() + { + await base.Edit_single_property_enum_with_int_converter(); + + AssertSql( + """ +@p0='-3' +@p1='-3' +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestEnumWithIntConverter', @p0), [Reference] = JSON_MODIFY([Reference], 'strict $.TestEnumWithIntConverter', @p1) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_nullable_enum() + { + await base.Edit_single_property_nullable_enum(); + + AssertSql( + """ +@p0='-3' +@p1='-3' +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestEnum', @p0), [Reference] = JSON_MODIFY([Reference], 'strict $.TestEnum', @p1) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_nullable_enum_set_to_null() + { + await base.Edit_single_property_nullable_enum_set_to_null(); + + AssertSql( + """ +@p0=NULL (Nullable = false) (DbType = Int32) +@p1=NULL (Nullable = false) (DbType = Int32) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestNullableEnum', @p0), [Reference] = JSON_MODIFY([Reference], 'strict $.TestNullableEnum', @p1) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_nullable_enum_with_int_converter() + { + await base.Edit_single_property_nullable_enum_with_int_converter(); + + AssertSql( + """ +@p0='-1' +@p1='-3' +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestNullableEnumWithIntConverter', @p0), [Reference] = JSON_MODIFY([Reference], 'strict $.TestNullableEnumWithIntConverter', @p1) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_nullable_enum_with_int_converter_set_to_null() + { + await base.Edit_single_property_nullable_enum_with_int_converter_set_to_null(); + + AssertSql( + """ +@p0=NULL (Nullable = false) (DbType = Int32) +@p1=NULL (Nullable = false) (DbType = Int32) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestNullableEnumWithIntConverter', @p0), [Reference] = JSON_MODIFY([Reference], 'strict $.TestNullableEnumWithIntConverter', @p1) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_nullable_enum_with_converter_that_handles_nulls() + { + await base.Edit_single_property_nullable_enum_with_converter_that_handles_nulls(); + + AssertSql( + """ +@p0='Three' (Nullable = false) (Size = 4000) +@p1='One' (Nullable = false) (Size = 4000) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestNullableEnumWithConverterThatHandlesNulls', @p0), [Reference] = JSON_MODIFY([Reference], 'strict $.TestNullableEnumWithConverterThatHandlesNulls', @p1) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_nullable_enum_with_converter_that_handles_nulls_set_to_null() + { + await base.Edit_single_property_nullable_enum_with_converter_that_handles_nulls_set_to_null(); + + AssertSql( + """ +@p0='Null' (Nullable = false) (Size = 4000) +@p1='Null' (Nullable = false) (Size = 4000) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestNullableEnumWithConverterThatHandlesNulls', @p0), [Reference] = JSON_MODIFY([Reference], 'strict $.TestNullableEnumWithConverterThatHandlesNulls', @p1) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_two_properties_on_same_entity_updates_the_entire_entity() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Edit_two_properties_on_same_entity_updates_the_entire_entity())).InnerException?.Message); + + AssertSql( + """ +@p0='{"TestBoolean":false,"TestBooleanCollection":[true,false],"TestByte":25,"TestByteArray":"","TestByteCollection":null,"TestCharacter":"h","TestCharacterCollection":["A","B","\u0022"],"TestDateOnly":"2323-04-03","TestDateOnlyCollection":["3234-01-23","4331-01-21"],"TestDateTime":"2100-11-11T12:34:56","TestDateTimeCollection":["2000-01-01T12:34:56","3000-01-01T12:34:56"],"TestDateTimeOffset":"2200-11-11T12:34:56-05:00","TestDateTimeOffsetCollection":["2000-01-01T12:34:56-08:00"],"TestDecimal":-123450.01,"TestDecimalCollection":[-1234567890.01],"TestDefaultString":"MyDefaultStringInCollection1","TestDefaultStringCollection":["S1","\u0022S2\u0022","S3"],"TestDouble":-1.2345,"TestDoubleCollection":[-1.23456789,1.23456789,0],"TestEnum":-1,"TestEnumCollection":[-1,-3,-7],"TestEnumWithIntConverter":2,"TestEnumWithIntConverterCollection":[-1,-3,-7],"TestGuid":"00000000-0000-0000-0000-000000000000","TestGuidCollection":["12345678-1234-4321-7777-987654321000"],"TestInt16":-12,"TestInt16Collection":[-32768,0,32767],"TestInt32":32,"TestInt32Collection":[-2147483648,0,2147483647],"TestInt64":64,"TestInt64Collection":[-9223372036854775808,0,9223372036854775807],"TestMaxLengthString":"Baz","TestMaxLengthStringCollection":["S1","S2","S3"],"TestNullableEnum":-1,"TestNullableEnumCollection":[-1,null,-3,-7],"TestNullableEnumWithConverterThatHandlesNulls":"Two","TestNullableEnumWithConverterThatHandlesNullsCollection":[-1,null,-7],"TestNullableEnumWithIntConverter":-3,"TestNullableEnumWithIntConverterCollection":[-1,null,-3,-7],"TestNullableInt32":90,"TestNullableInt32Collection":[null,-2147483648,0,null,2147483647,null],"TestSignedByte":-18,"TestSignedByteCollection":[-128,0,127],"TestSingle":-1.4,"TestSingleCollection":[-1.234,0,-1.234],"TestTimeOnly":"05:07:08.0000000","TestTimeOnlyCollection":["13:42:23.0000000","07:17:25.0000000"],"TestTimeSpan":"6:05:04.003","TestTimeSpanCollection":["10:09:08.007","-9:50:51.993"],"TestUnsignedInt16":12,"TestUnsignedInt16Collection":[0,0,65535],"TestUnsignedInt32":12345,"TestUnsignedInt32Collection":[0,0,4294967295],"TestUnsignedInt64":1234567867,"TestUnsignedInt64Collection":[0,0,18446744073709551615]}' (Nullable = false) (Size = 2158) +@p1='{"TestBoolean":true,"TestBooleanCollection":[true,false],"TestByte":255,"TestByteArray":"AQID","TestByteCollection":null,"TestCharacter":"a","TestCharacterCollection":["A","B","\u0022"],"TestDateOnly":"2023-10-10","TestDateOnlyCollection":["1234-01-23","4321-01-21"],"TestDateTime":"2000-01-01T12:34:56","TestDateTimeCollection":["2000-01-01T12:34:56","3000-01-01T12:34:56"],"TestDateTimeOffset":"2000-01-01T12:34:56-08:00","TestDateTimeOffsetCollection":["2000-01-01T12:34:56-08:00"],"TestDecimal":-1234567890.01,"TestDecimalCollection":[-1234567890.01],"TestDefaultString":"MyDefaultStringInReference1","TestDefaultStringCollection":["S1","\u0022S2\u0022","S3"],"TestDouble":-1.23456789,"TestDoubleCollection":[-1.23456789,1.23456789,0],"TestEnum":-1,"TestEnumCollection":[-1,-3,-7],"TestEnumWithIntConverter":2,"TestEnumWithIntConverterCollection":[-1,-3,-7],"TestGuid":"12345678-1234-4321-7777-987654321000","TestGuidCollection":["12345678-1234-4321-7777-987654321000"],"TestInt16":-1234,"TestInt16Collection":[-32768,0,32767],"TestInt32":32,"TestInt32Collection":[-2147483648,0,2147483647],"TestInt64":64,"TestInt64Collection":[-9223372036854775808,0,9223372036854775807],"TestMaxLengthString":"Foo","TestMaxLengthStringCollection":["S1","S2","S3"],"TestNullableEnum":-1,"TestNullableEnumCollection":[-1,null,-3,-7],"TestNullableEnumWithConverterThatHandlesNulls":"Three","TestNullableEnumWithConverterThatHandlesNullsCollection":[-1,null,-7],"TestNullableEnumWithIntConverter":2,"TestNullableEnumWithIntConverterCollection":[-1,null,-3,-7],"TestNullableInt32":78,"TestNullableInt32Collection":[null,-2147483648,0,null,2147483647,null],"TestSignedByte":-128,"TestSignedByteCollection":[-128,0,127],"TestSingle":-1.234,"TestSingleCollection":[-1.234,0,-1.234],"TestTimeOnly":"11:12:13.0000000","TestTimeOnlyCollection":["11:42:23.0000000","07:17:27.0000000"],"TestTimeSpan":"10:09:08.007","TestTimeSpanCollection":["10:09:08.007","-9:50:51.993"],"TestUnsignedInt16":1234,"TestUnsignedInt16Collection":[0,0,65535],"TestUnsignedInt32":1234565789,"TestUnsignedInt32Collection":[0,0,4294967295],"TestUnsignedInt64":1234567890123456789,"TestUnsignedInt64Collection":[0,0,18446744073709551615]}' (Nullable = false) (Size = 2192) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0]', JSON_QUERY(@p0)), [Reference] = @p1 +OUTPUT 1 +WHERE [Id] = @p2; +"""); + } + + public override async Task Edit_a_scalar_property_and_reference_navigation_on_the_same_entity() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Edit_a_scalar_property_and_reference_navigation_on_the_same_entity())).InnerException?.Message); + + AssertSql( + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +""", + // + """ +@p0='{"Date":"2100-01-01T00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":123.532,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_r_c1"},{"SomethingSomething":"e1_r_r_c2"}],"OwnedReferenceLeaf":null}' (Nullable = false) (Size = 245) +@p1='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesBasic] SET [OwnedReferenceRoot] = JSON_MODIFY([OwnedReferenceRoot], 'strict $.OwnedReferenceBranch', JSON_QUERY(@p0)) +OUTPUT 1 +WHERE [Id] = @p1; +"""); + } + + public override async Task Edit_a_scalar_property_and_collection_navigation_on_the_same_entity() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Edit_a_scalar_property_and_collection_navigation_on_the_same_entity())).InnerException?.Message); + + AssertSql( + """ +SELECT [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] +FROM [JsonEntitiesBasic] AS [j] +""", + // + """ +@p0='{"Date":"2100-01-01T00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":123.532,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":null,"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_r_r"}}' (Nullable = false) (Size = 207) +@p1='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesBasic] SET [OwnedReferenceRoot] = JSON_MODIFY([OwnedReferenceRoot], 'strict $.OwnedReferenceBranch', JSON_QUERY(@p0)) +OUTPUT 1 +WHERE [Id] = @p1; +"""); + } + + public override async Task Edit_a_scalar_property_and_another_property_behind_reference_navigation_on_the_same_entity() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Edit_a_scalar_property_and_another_property_behind_reference_navigation_on_the_same_entity())) + .InnerException?.Message); + + AssertSql( + """ +@p0='{"Date":"2100-01-01T00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":523.532,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_r_c1"},{"SomethingSomething":"e1_r_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"edit"}}' (Nullable = false) (Size = 270) +@p1='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesBasic] SET [OwnedReferenceRoot] = JSON_MODIFY([OwnedReferenceRoot], 'strict $.OwnedReferenceBranch', JSON_QUERY(@p0)) +OUTPUT 1 +WHERE [Id] = @p1; +"""); + } + + public override async Task Edit_single_property_with_converter_bool_to_int_zero_one() + { + await base.Edit_single_property_with_converter_bool_to_int_zero_one(); + + AssertSql( + """ +@p0='0' +@p1='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesConverters] SET [Reference] = JSON_MODIFY([Reference], 'strict $.BoolConvertedToIntZeroOne', @p0) +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[Reference] +FROM [JsonEntitiesConverters] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_with_converter_bool_to_string_True_False() + { + await base.Edit_single_property_with_converter_bool_to_string_True_False(); + + AssertSql( + """ +@p0='True' (Nullable = false) (Size = 4000) +@p1='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesConverters] SET [Reference] = JSON_MODIFY([Reference], 'strict $.BoolConvertedToStringTrueFalse', @p0) +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[Reference] +FROM [JsonEntitiesConverters] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_with_converter_bool_to_string_Y_N() + { + await base.Edit_single_property_with_converter_bool_to_string_Y_N(); + + AssertSql( + """ +@p0='N' (Nullable = false) (Size = 4000) +@p1='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesConverters] SET [Reference] = JSON_MODIFY([Reference], 'strict $.BoolConvertedToStringYN', @p0) +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[Reference] +FROM [JsonEntitiesConverters] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_with_converter_int_zero_one_to_bool() + { + await base.Edit_single_property_with_converter_int_zero_one_to_bool(); + + AssertSql( + """ +@p0='True' +@p1='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesConverters] SET [Reference] = JSON_MODIFY([Reference], 'strict $.IntZeroOneConvertedToBool', @p0) +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[Reference] +FROM [JsonEntitiesConverters] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + [ConditionalFact] + public override async Task Edit_single_property_with_converter_string_True_False_to_bool() + { + await base.Edit_single_property_with_converter_string_True_False_to_bool(); + + AssertSql( + """ +@p0='False' +@p1='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesConverters] SET [Reference] = JSON_MODIFY([Reference], 'strict $.StringTrueFalseConvertedToBool', @p0) +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[Reference] +FROM [JsonEntitiesConverters] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + [ConditionalFact] + public override async Task Edit_single_property_with_converter_string_Y_N_to_bool() + { + await base.Edit_single_property_with_converter_string_Y_N_to_bool(); + + AssertSql( + """ +@p0='True' +@p1='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesConverters] SET [Reference] = JSON_MODIFY([Reference], 'strict $.StringYNConvertedToBool', @p0) +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[Reference] +FROM [JsonEntitiesConverters] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_collection_of_numeric() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Edit_single_property_collection_of_numeric())).InnerException?.Message); + + AssertSql( + """ +@p0='[1024,2048]' (Nullable = false) (Size = 11) +@p1='[999,997]' (Nullable = false) (Size = 9) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesBasic] SET [OwnedCollectionRoot] = JSON_MODIFY([OwnedCollectionRoot], 'strict $[1].Numbers', JSON_QUERY(@p0)), [OwnedReferenceRoot] = JSON_MODIFY([OwnedReferenceRoot], 'strict $.Numbers', JSON_QUERY(@p1)) +OUTPUT 1 +WHERE [Id] = @p2; +"""); + } + + public override async Task Edit_single_property_collection_of_bool() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Edit_single_property_collection_of_bool())).InnerException?.Message); + + AssertSql( + """ +@p0='[true,true,true,false]' (Nullable = false) (Size = 22) +@p1='[true,true,false]' (Nullable = false) (Size = 17) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestBooleanCollection', JSON_QUERY(@p0)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestBooleanCollection', JSON_QUERY(@p1)) +OUTPUT 1 +WHERE [Id] = @p2; +"""); + } + + public override async Task Edit_single_property_collection_of_byte() + { + await base.Edit_single_property_collection_of_byte(); + + AssertSql( + """ +@p0='Dg==' (Nullable = false) (Size = 4000) +@p1='GRo=' (Nullable = false) (Size = 4000) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestByteCollection', @p0), [Reference] = JSON_MODIFY([Reference], 'strict $.TestByteCollection', @p1) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + [ConditionalFact(Skip = "TODO:SQLJSON Hangs (See InsertsHang.cs")] + public override async Task Edit_single_property_collection_of_char() + { + await base.Edit_single_property_collection_of_char(); + + AssertSql( + """ +@p0='["A","B","\u0022","\u0000"]' (Nullable = false) (Size = 4000) +@p1='["E","F","C","\u00F6","r","E","\u0022","\\"]' (Nullable = false) (Size = 4000) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestCharacterCollection', JSON_QUERY(@p0)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestCharacterCollection', JSON_QUERY(@p1)) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_collection_of_datetime() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Edit_single_property_collection_of_datetime())).InnerException?.Message); + + AssertSql( + """ +@p0='["2000-01-01T12:34:56","3000-01-01T12:34:56","3000-01-01T12:34:56"]' (Nullable = false) (Size = 67) +@p1='["2000-01-01T12:34:56","3000-01-01T12:34:56","3000-01-01T12:34:56"]' (Nullable = false) (Size = 67) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestDateTimeCollection', JSON_QUERY(@p0)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestDateTimeCollection', JSON_QUERY(@p1)) +OUTPUT 1 +WHERE [Id] = @p2; +"""); + } + + public override async Task Edit_single_property_collection_of_datetimeoffset() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Edit_single_property_collection_of_datetimeoffset())).InnerException?.Message); + + AssertSql( + """ +@p0='["3000-01-01T12:34:56-04:00"]' (Nullable = false) (Size = 29) +@p1='["3000-01-01T12:34:56-04:00"]' (Nullable = false) (Size = 29) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestDateTimeOffsetCollection', JSON_QUERY(@p0)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestDateTimeOffsetCollection', JSON_QUERY(@p1)) +OUTPUT 1 +WHERE [Id] = @p2; +"""); + } + + public override async Task Edit_single_property_collection_of_decimal() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Edit_single_property_collection_of_decimal())).InnerException?.Message); + + AssertSql( + """ +@p0='[-13579.01]' (Nullable = false) (Size = 11) +@p1='[-13579.01]' (Nullable = false) (Size = 11) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestDecimalCollection', JSON_QUERY(@p0)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestDecimalCollection', JSON_QUERY(@p1)) +OUTPUT 1 +WHERE [Id] = @p2; +"""); + } + + public override async Task Edit_single_property_collection_of_double() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Edit_single_property_collection_of_double())).InnerException?.Message); + + AssertSql( + """ +@p0='[-1.23456789,1.23456789,0,-1.23579]' (Nullable = false) (Size = 35) +@p1='[-1.23456789,1.23456789,0,-1.23579]' (Nullable = false) (Size = 35) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestDoubleCollection', JSON_QUERY(@p0)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestDoubleCollection', JSON_QUERY(@p1)) +OUTPUT 1 +WHERE [Id] = @p2; +"""); + } + + public override async Task Edit_single_property_collection_of_guid() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Edit_single_property_collection_of_guid())).InnerException?.Message); + + AssertSql( + """ +@p0='["12345678-1234-4321-5555-987654321000"]' (Nullable = false) (Size = 40) +@p1='["12345678-1234-4321-5555-987654321000"]' (Nullable = false) (Size = 40) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestGuidCollection', JSON_QUERY(@p0)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestGuidCollection', JSON_QUERY(@p1)) +OUTPUT 1 +WHERE [Id] = @p2; +"""); + } + + public override async Task Edit_single_property_collection_of_int16() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Edit_single_property_collection_of_int16())).InnerException?.Message); + + AssertSql( + """ +@p0='[-3234]' (Nullable = false) (Size = 7) +@p1='[-3234]' (Nullable = false) (Size = 7) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestInt16Collection', JSON_QUERY(@p0)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestInt16Collection', JSON_QUERY(@p1)) +OUTPUT 1 +WHERE [Id] = @p2; +"""); + } + + public override async Task Edit_single_property_collection_of_int32() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Edit_single_property_collection_of_int32())).InnerException?.Message); + + AssertSql( + """ +@p0='[-3234]' (Nullable = false) (Size = 7) +@p1='[-3234]' (Nullable = false) (Size = 7) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestInt32Collection', JSON_QUERY(@p0)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestInt32Collection', JSON_QUERY(@p1)) +OUTPUT 1 +WHERE [Id] = @p2; +"""); + } + + public override async Task Edit_single_property_collection_of_int64() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Edit_single_property_collection_of_int64())).InnerException?.Message); + + AssertSql( + """ +@p0='[]' (Nullable = false) (Size = 2) +@p1='[]' (Nullable = false) (Size = 2) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestInt64Collection', JSON_QUERY(@p0)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestInt64Collection', JSON_QUERY(@p1)) +OUTPUT 1 +WHERE [Id] = @p2; +"""); + } + + public override async Task Edit_single_property_collection_of_signed_byte() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Edit_single_property_collection_of_signed_byte())).InnerException?.Message); + + AssertSql( + """ +@p0='[-108]' (Nullable = false) (Size = 6) +@p1='[-108]' (Nullable = false) (Size = 6) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestSignedByteCollection', JSON_QUERY(@p0)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestSignedByteCollection', JSON_QUERY(@p1)) +OUTPUT 1 +WHERE [Id] = @p2; +"""); + } + + public override async Task Edit_single_property_collection_of_single() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Edit_single_property_collection_of_single())).InnerException?.Message); + + AssertSql( + """ +@p0='[-1.234,-1.234]' (Nullable = false) (Size = 15) +@p1='[0,-1.234]' (Nullable = false) (Size = 10) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestSingleCollection', JSON_QUERY(@p0)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestSingleCollection', JSON_QUERY(@p1)) +OUTPUT 1 +WHERE [Id] = @p2; +"""); + } + + public override async Task Edit_single_property_collection_of_timespan() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Edit_single_property_collection_of_timespan())).InnerException?.Message); + + AssertSql( + """ +@p0='["10:09:08.007","10:01:01.007"]' (Nullable = false) (Size = 31) +@p1='["10:01:01.007","-9:50:51.993"]' (Nullable = false) (Size = 31) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestTimeSpanCollection', JSON_QUERY(@p0)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestTimeSpanCollection', JSON_QUERY(@p1)) +OUTPUT 1 +WHERE [Id] = @p2; +"""); + } + + public override async Task Edit_single_property_collection_of_dateonly() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Edit_single_property_collection_of_dateonly())).InnerException?.Message); + + AssertSql( + """ +@p0='["3234-01-23","0001-01-07"]' (Nullable = false) (Size = 27) +@p1='["0001-01-07","4321-01-21"]' (Nullable = false) (Size = 27) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestDateOnlyCollection', JSON_QUERY(@p0)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestDateOnlyCollection', JSON_QUERY(@p1)) +OUTPUT 1 +WHERE [Id] = @p2; +"""); + } + + public override async Task Edit_single_property_collection_of_timeonly() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Edit_single_property_collection_of_timeonly())).InnerException?.Message); + + AssertSql( + """ +@p0='["13:42:23.0000000","01:01:07.0000000"]' (Nullable = false) (Size = 39) +@p1='["01:01:07.0000000","07:17:27.0000000"]' (Nullable = false) (Size = 39) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestTimeOnlyCollection', JSON_QUERY(@p0)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestTimeOnlyCollection', JSON_QUERY(@p1)) +OUTPUT 1 +WHERE [Id] = @p2; +"""); + } + + public override async Task Edit_single_property_collection_of_uint16() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Edit_single_property_collection_of_uint16())).InnerException?.Message); + + AssertSql( + """ +@p0='[1534]' (Nullable = false) (Size = 6) +@p1='[1534]' (Nullable = false) (Size = 6) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestUnsignedInt16Collection', JSON_QUERY(@p0)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestUnsignedInt16Collection', JSON_QUERY(@p1)) +OUTPUT 1 +WHERE [Id] = @p2; +"""); + } + + public override async Task Edit_single_property_collection_of_uint32() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Edit_single_property_collection_of_uint32())).InnerException?.Message); + + AssertSql( + """ +@p0='[1237775789]' (Nullable = false) (Size = 12) +@p1='[1237775789]' (Nullable = false) (Size = 12) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestUnsignedInt32Collection', JSON_QUERY(@p0)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestUnsignedInt32Collection', JSON_QUERY(@p1)) +OUTPUT 1 +WHERE [Id] = @p2; +"""); + } + + public override async Task Edit_single_property_collection_of_uint64() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Edit_single_property_collection_of_uint64())).InnerException?.Message); + + AssertSql( + """ +@p0='[1234555555123456789]' (Nullable = false) (Size = 21) +@p1='[1234555555123456789]' (Nullable = false) (Size = 21) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestUnsignedInt64Collection', JSON_QUERY(@p0)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestUnsignedInt64Collection', JSON_QUERY(@p1)) +OUTPUT 1 +WHERE [Id] = @p2; +"""); + } + + public override async Task Edit_single_property_collection_of_nullable_int32() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Edit_single_property_collection_of_nullable_int32())).InnerException?.Message); + + AssertSql( + """ +@p0='[null,77]' (Nullable = false) (Size = 9) +@p1='[null,-2147483648,0,null,2147483647,null,77,null]' (Nullable = false) (Size = 49) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestNullableInt32Collection', JSON_QUERY(@p0)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestNullableInt32Collection', JSON_QUERY(@p1)) +OUTPUT 1 +WHERE [Id] = @p2; +"""); + } + + public override async Task Edit_single_property_collection_of_nullable_int32_set_to_null() + { + await base.Edit_single_property_collection_of_nullable_int32_set_to_null(); + + AssertSql( + """ +@p0=NULL (Nullable = false) (Size = 4000) +@p1=NULL (Nullable = false) (Size = 4000) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestNullableInt32Collection', JSON_QUERY(@p0)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestNullableInt32Collection', JSON_QUERY(@p1)) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_collection_of_enum() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Edit_single_property_collection_of_enum())).InnerException?.Message); + + AssertSql( + """ +@p0='[-3]' (Nullable = false) (Size = 4) +@p1='[-3]' (Nullable = false) (Size = 4) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestEnumCollection', JSON_QUERY(@p0)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestEnumCollection', JSON_QUERY(@p1)) +OUTPUT 1 +WHERE [Id] = @p2; +"""); + } + + public override async Task Edit_single_property_collection_of_enum_with_int_converter() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Edit_single_property_collection_of_enum_with_int_converter())).InnerException?.Message); + + AssertSql( + """ +@p0='[-3]' (Nullable = false) (Size = 4) +@p1='[-3]' (Nullable = false) (Size = 4) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestEnumWithIntConverterCollection', JSON_QUERY(@p0)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestEnumWithIntConverterCollection', JSON_QUERY(@p1)) +OUTPUT 1 +WHERE [Id] = @p2; +"""); + } + + public override async Task Edit_single_property_collection_of_nullable_enum() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Edit_single_property_collection_of_nullable_enum())).InnerException?.Message); + + AssertSql( + """ +@p0='[-3]' (Nullable = false) (Size = 4) +@p1='[-3]' (Nullable = false) (Size = 4) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestEnumCollection', JSON_QUERY(@p0)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestEnumCollection', JSON_QUERY(@p1)) +OUTPUT 1 +WHERE [Id] = @p2; +"""); + } + + public override async Task Edit_single_property_collection_of_nullable_enum_set_to_null() + { + await base.Edit_single_property_collection_of_nullable_enum_set_to_null(); + + AssertSql( + """ +@p0=NULL (Nullable = false) (Size = 4000) +@p1=NULL (Nullable = false) (Size = 4000) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestNullableEnumCollection', JSON_QUERY(@p0)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestNullableEnumCollection', JSON_QUERY(@p1)) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_collection_of_nullable_enum_with_int_converter() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Edit_single_property_collection_of_nullable_enum_with_int_converter())).InnerException?.Message); + + AssertSql( + """ +@p0='[-1,null,-7,2]' (Nullable = false) (Size = 14) +@p1='[-1,-3,-7,2]' (Nullable = false) (Size = 12) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestNullableEnumWithIntConverterCollection', JSON_QUERY(@p0)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestNullableEnumWithIntConverterCollection', JSON_QUERY(@p1)) +OUTPUT 1 +WHERE [Id] = @p2; +"""); + } + + public override async Task Edit_single_property_collection_of_nullable_enum_with_int_converter_set_to_null() + { + await base.Edit_single_property_collection_of_nullable_enum_with_int_converter_set_to_null(); + + AssertSql( + """ +@p0=NULL (Nullable = false) (Size = 4000) +@p1=NULL (Nullable = false) (Size = 4000) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestNullableEnumWithIntConverterCollection', JSON_QUERY(@p0)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestNullableEnumWithIntConverterCollection', JSON_QUERY(@p1)) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_collection_of_nullable_enum_with_converter_that_handles_nulls() + { + // TODO:SQLJSON (See JsonTypeToFunction.cs) + Assert.Equal( + "Argument data type json is invalid for argument 3 of json_modify function.", + (await Assert.ThrowsAsync( + () => base.Edit_single_property_collection_of_nullable_enum_with_converter_that_handles_nulls())).InnerException?.Message); + + AssertSql( + """ +@p0='[-3]' (Nullable = false) (Size = 4) +@p1='[-1]' (Nullable = false) (Size = 4) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestNullableEnumWithConverterThatHandlesNullsCollection', JSON_QUERY(@p0)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestNullableEnumWithConverterThatHandlesNullsCollection', JSON_QUERY(@p1)) +OUTPUT 1 +WHERE [Id] = @p2; +"""); + } + + public override async Task Edit_single_property_collection_of_nullable_enum_with_converter_that_handles_nulls_set_to_null() + { + await base.Edit_single_property_collection_of_nullable_enum_with_converter_that_handles_nulls_set_to_null(); + + AssertSql( + """ +@p0=NULL (Nullable = false) (Size = 4000) +@p1=NULL (Nullable = false) (Size = 4000) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestNullableEnumWithConverterThatHandlesNullsCollection', JSON_QUERY(@p0)), [Reference] = JSON_MODIFY([Reference], 'strict $.TestNullableEnumWithConverterThatHandlesNullsCollection', JSON_QUERY(@p1)) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override Task Add_and_update_nested_optional_owned_collection_to_JSON(bool? value) + // TODO:SQLJSON Updates to null fail (See UpdateToNull.cs) + => Assert.ThrowsAsync( + () => base.Add_and_update_nested_optional_owned_collection_to_JSON(value)); + + public override Task Add_and_update_top_level_optional_owned_collection_to_JSON(bool? value) + // TODO:SQLJSON Updates to null fail (See UpdateToNull.cs) + => Assert.ThrowsAsync( + () => base.Add_and_update_top_level_optional_owned_collection_to_JSON(value)); + + [ConditionalTheory(Skip = "TODO:SQLJSON Hangs (See InsertsHang.cs")] + public override async Task Add_and_update_nested_optional_primitive_collection(bool? value) + { + await base.Add_and_update_nested_optional_primitive_collection(value); + + var characterCollection = value switch + { + true => "[\"A\"]", + false => "[]", + _ => "null" + }; + + var parameterSize = value switch + { + true => "1558", + false => "1555", + _ => "1557" + }; + + var updateParameter = value switch + { + true => "NULL", + false => "'[\"Z\"]'", + _ => "'[]'" + }; + + AssertSql( + @"@p0='[{""TestBoolean"":false,""TestBooleanCollection"":[],""TestByte"":0,""TestByteArray"":null,""TestByteCollection"":null,""TestCharacter"":""\u0000"",""TestCharacterCollection"":" + + characterCollection + + @",""TestDateOnly"":""0001-01-01"",""TestDateOnlyCollection"":[],""TestDateTime"":""0001-01-01T00:00:00"",""TestDateTimeCollection"":[],""TestDateTimeOffset"":""0001-01-01T00:00:00+00:00"",""TestDateTimeOffsetCollection"":[],""TestDecimal"":0,""TestDecimalCollection"":[],""TestDefaultString"":null,""TestDefaultStringCollection"":[],""TestDouble"":0,""TestDoubleCollection"":[],""TestEnum"":0,""TestEnumCollection"":[],""TestEnumWithIntConverter"":0,""TestEnumWithIntConverterCollection"":[],""TestGuid"":""00000000-0000-0000-0000-000000000000"",""TestGuidCollection"":[],""TestInt16"":0,""TestInt16Collection"":[],""TestInt32"":0,""TestInt32Collection"":[],""TestInt64"":0,""TestInt64Collection"":[],""TestMaxLengthString"":null,""TestMaxLengthStringCollection"":[],""TestNullableEnum"":null,""TestNullableEnumCollection"":[],""TestNullableEnumWithConverterThatHandlesNulls"":null,""TestNullableEnumWithConverterThatHandlesNullsCollection"":[],""TestNullableEnumWithIntConverter"":null,""TestNullableEnumWithIntConverterCollection"":[],""TestNullableInt32"":null,""TestNullableInt32Collection"":[],""TestSignedByte"":0,""TestSignedByteCollection"":[],""TestSingle"":0,""TestSingleCollection"":[],""TestTimeOnly"":""00:00:00.0000000"",""TestTimeOnlyCollection"":[],""TestTimeSpan"":""0:00:00"",""TestTimeSpanCollection"":[],""TestUnsignedInt16"":0,""TestUnsignedInt16Collection"":[],""TestUnsignedInt32"":0,""TestUnsignedInt32Collection"":[],""TestUnsignedInt64"":0,""TestUnsignedInt64Collection"":[]}]' (Nullable = false) (Size = " + + parameterSize + + @") +@p1='7624' +@p2='[]' (Size = 4000) +@p3=NULL (Size = 8000) (DbType = Binary) +@p4='[]' (Size = 4000) +@p5='[]' (Size = 4000) +@p6='[]' (Size = 4000) +@p7='[]' (Size = 4000) +@p8='[]' (Size = 4000) +@p9='[]' (Size = 4000) +@p10='[]' (Size = 4000) +@p11='[]' (Size = 4000) +@p12='[]' (Nullable = false) (Size = 4000) +@p13='[]' (Size = 4000) +@p14='[]' (Size = 4000) +@p15='[]' (Size = 4000) +@p16='[]' (Size = 4000) +@p17='[]' (Size = 4000) +@p18=NULL (Size = 4000) +@p19='[]' (Size = 4000) +@p20='[]' (Size = 4000) +@p21='[]' (Size = 4000) +@p22='[]' (Size = 4000) +@p23='[]' (Size = 4000) +@p24='[]' (Size = 4000) +@p25='[]' (Size = 4000) +@p26='[]' (Size = 4000) + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +INSERT INTO [JsonEntitiesAllTypes] ([Collection], [Id], [TestBooleanCollection], [TestByteCollection], [TestCharacterCollection], [TestDateTimeCollection], [TestDateTimeOffsetCollection], [TestDecimalCollection], [TestDefaultStringCollection], [TestDoubleCollection], [TestEnumCollection], [TestEnumWithIntConverterCollection], [TestGuidCollection], [TestInt16Collection], [TestInt32Collection], [TestInt64Collection], [TestMaxLengthStringCollection], [TestNullableEnumCollection], [TestNullableEnumWithConverterThatHandlesNullsCollection], [TestNullableEnumWithIntConverterCollection], [TestNullableInt32Collection], [TestSignedByteCollection], [TestSingleCollection], [TestTimeSpanCollection], [TestUnsignedInt16Collection], [TestUnsignedInt32Collection], [TestUnsignedInt64Collection]) +VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10, @p11, @p12, @p13, @p14, @p15, @p16, @p17, @p18, @p19, @p20, @p21, @p22, @p23, @p24, @p25, @p26);", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 7624 +""", + // + "@p0=" + + updateParameter + + @" (Nullable = false) (Size = 4000) +@p1='7624' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestCharacterCollection', JSON_QUERY(@p0)) +OUTPUT 1 +WHERE [Id] = @p1;", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 7624 +"""); + } + + // Nested collections are not mapped in the relational model, so there is no data stored in the document for them + public override Task Edit_single_property_collection_of_collection_of_bool() + => Assert.ThrowsAsync(base.Edit_single_property_collection_of_collection_of_bool); + + // Nested collections are not mapped in the relational model, so there is no data stored in the document for them + public override Task Edit_single_property_collection_of_collection_of_char() + => Assert.ThrowsAsync(base.Edit_single_property_collection_of_collection_of_char); + + // Nested collections are not mapped in the relational model, so there is no data stored in the document for them + public override Task Edit_single_property_collection_of_collection_of_double() + => Assert.ThrowsAsync(base.Edit_single_property_collection_of_collection_of_double); + + // Nested collections are not mapped in the relational model, so there is no data stored in the document for them + public override Task Edit_single_property_collection_of_collection_of_int16() + => Assert.ThrowsAsync(base.Edit_single_property_collection_of_collection_of_int16); + + // Nested collections are not mapped in the relational model, so there is no data stored in the document for them + public override Task Edit_single_property_collection_of_collection_of_int32() + => Assert.ThrowsAsync(base.Edit_single_property_collection_of_collection_of_int32); + + // Nested collections are not mapped in the relational model, so there is no data stored in the document for them + public override Task Edit_single_property_collection_of_collection_of_nullable_enum_set_to_null() + => Assert.ThrowsAsync(base.Edit_single_property_collection_of_collection_of_nullable_enum_set_to_null); + + // Nested collections are not mapped in the relational model, so there is no data stored in the document for them + public override Task Edit_single_property_collection_of_collection_of_nullable_enum_with_int_converter() + => Assert.ThrowsAsync( + base.Edit_single_property_collection_of_collection_of_nullable_enum_with_int_converter); + + // Nested collections are not mapped in the relational model, so there is no data stored in the document for them + public override Task Edit_single_property_collection_of_collection_of_nullable_int32() + => Assert.ThrowsAsync(base.Edit_single_property_collection_of_collection_of_nullable_int32); + + // Nested collections are not mapped in the relational model, so there is no data stored in the document for them + public override Task Edit_single_property_collection_of_collection_of_nullable_int32_set_to_null() + => Assert.ThrowsAsync(base.Edit_single_property_collection_of_collection_of_nullable_int32_set_to_null); + + // Nested collections are not mapped in the relational model, so there is no data stored in the document for them + public override Task Edit_single_property_collection_of_collection_of_single() + => Assert.ThrowsAsync(base.Edit_single_property_collection_of_collection_of_single); + + public override async Task Edit_single_property_timeonly() + { + await base.Edit_single_property_timeonly(); + + AssertSql( + """ +@p0='01:01:07.0000000' (Nullable = false) (Size = 4000) +@p1='01:01:07.0000000' (Nullable = false) (Size = 4000) +@p2='1' + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestTimeOnly', @p0), [Reference] = JSON_MODIFY([Reference], 'strict $.TestTimeOnly', @p1) +OUTPUT 1 +WHERE [Id] = @p2; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_relational_collection_of_bool() + { + await base.Edit_single_property_relational_collection_of_bool(); + + AssertSql( + """ +@p1='1' +@p0='[true,true,false]' (Size = 8000) + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [TestBooleanCollection] = @p0 +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_relational_collection_of_byte() + { + await base.Edit_single_property_relational_collection_of_byte(); + + AssertSql( + """ +@p1='1' +@p0='[25,26]' (Size = 8000) + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [TestByteCollection] = @p0 +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + [ConditionalFact(Skip = "TODO:SQLJSON Investigate")] + public override async Task Edit_single_property_relational_collection_of_char() + { + await base.Edit_single_property_relational_collection_of_char(); + + AssertSql(); + } + + public override async Task Edit_single_property_relational_collection_of_datetime() + { + await base.Edit_single_property_relational_collection_of_datetime(); + + AssertSql( + """ +@p1='1' +@p0='["2000-01-01T12:34:56","3000-01-01T12:34:56","3000-01-01T12:34:56"]' (Size = 8000) + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [TestDateTimeCollection] = @p0 +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_relational_collection_of_datetimeoffset() + { + await base.Edit_single_property_relational_collection_of_datetimeoffset(); + + AssertSql( + """ +@p1='1' +@p0='["3000-01-01T12:34:56-04:00"]' (Size = 8000) + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [TestDateTimeOffsetCollection] = @p0 +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_relational_collection_of_decimal() + { + await base.Edit_single_property_relational_collection_of_decimal(); + + AssertSql( + """ +@p1='1' +@p0='[-13579.01]' (Size = 8000) + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [TestDecimalCollection] = @p0 +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_relational_collection_of_double() + { + await base.Edit_single_property_relational_collection_of_double(); + + AssertSql( + """ +@p1='1' +@p0='[-1.23456789,1.23456789,0,-1.23579]' (Size = 8000) + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [TestDoubleCollection] = @p0 +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_relational_collection_of_guid() + { + await base.Edit_single_property_relational_collection_of_guid(); + + AssertSql( + """ +@p1='1' +@p0='["12345678-1234-4321-5555-987654321000"]' (Nullable = false) (Size = 8000) + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [TestGuidCollection] = @p0 +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_relational_collection_of_int16() + { + await base.Edit_single_property_relational_collection_of_int16(); + + AssertSql( + """ +@p1='1' +@p0='[-3234]' (Size = 8000) + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [TestInt16Collection] = @p0 +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_relational_collection_of_int32() + { + await base.Edit_single_property_relational_collection_of_int32(); + + AssertSql( + """ +@p1='1' +@p0='[-3234]' (Size = 8000) + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [TestInt32Collection] = @p0 +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_relational_collection_of_int64() + { + await base.Edit_single_property_relational_collection_of_int64(); + + AssertSql( + """ +@p1='1' +@p0='[]' (Size = 8000) + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [TestInt64Collection] = @p0 +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_relational_collection_of_signed_byte() + { + await base.Edit_single_property_relational_collection_of_signed_byte(); + + AssertSql( + """ +@p1='1' +@p0='[-108]' (Size = 8000) + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [TestSignedByteCollection] = @p0 +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_relational_collection_of_single() + { + await base.Edit_single_property_relational_collection_of_single(); + + AssertSql( + """ +@p1='1' +@p0='[0,-1.234]' (Size = 8000) + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [TestSingleCollection] = @p0 +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_relational_collection_of_timespan() + { + await base.Edit_single_property_relational_collection_of_timespan(); + + AssertSql( + """ +@p1='1' +@p0='["10:01:01.007","7:09:08.007"]' (Size = 8000) + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [TestTimeSpanCollection] = @p0 +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_relational_collection_of_uint16() + { + await base.Edit_single_property_relational_collection_of_uint16(); + + AssertSql( + """ +@p1='1' +@p0='[1534]' (Size = 8000) + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [TestUnsignedInt16Collection] = @p0 +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_relational_collection_of_uint32() + { + await base.Edit_single_property_relational_collection_of_uint32(); + + AssertSql( + """ +@p1='1' +@p0='[1237775789]' (Size = 8000) + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [TestUnsignedInt32Collection] = @p0 +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_relational_collection_of_uint64() + { + await base.Edit_single_property_relational_collection_of_uint64(); + + AssertSql( + """ +@p1='1' +@p0='[1234555555123456789]' (Size = 8000) + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [TestUnsignedInt64Collection] = @p0 +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_relational_collection_of_nullable_int32() + { + await base.Edit_single_property_relational_collection_of_nullable_int32(); + + AssertSql( + """ +@p1='1' +@p0='[null,-2147483648,0,null,2147483647,null,77,null]' (Size = 8000) + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [TestNullableInt32Collection] = @p0 +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_relational_collection_of_nullable_int32_set_to_null() + { + // TODO:SQLJSON Updates to null fail (See UpdateToNull.cs) + await Assert.ThrowsAsync( + () => base.Edit_single_property_relational_collection_of_nullable_int32_set_to_null()); + + AssertSql( + """ +@p1='1' +@p0=NULL (Size = 8000) + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [TestNullableInt32Collection] = @p0 +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_relational_collection_of_enum() + { + await base.Edit_single_property_relational_collection_of_enum(); + + AssertSql( + """ +@p1='1' +@p0='[-3]' (Size = 8000) + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [TestEnumCollection] = @p0 +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_relational_collection_of_enum_with_int_converter() + { + await base.Edit_single_property_relational_collection_of_enum_with_int_converter(); + + AssertSql( + """ +@p1='1' +@p0='[-3]' (Size = 8000) + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [TestEnumWithIntConverterCollection] = @p0 +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_relational_collection_of_nullable_enum() + { + await base.Edit_single_property_relational_collection_of_nullable_enum(); + + AssertSql( + """ +@p1='1' +@p0='[-3]' (Size = 8000) + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [TestEnumCollection] = @p0 +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_relational_collection_of_nullable_enum_set_to_null() + { + // TODO:SQLJSON Updates to null fail (See UpdateToNull.cs) + await Assert.ThrowsAsync( + () => base.Edit_single_property_relational_collection_of_nullable_enum_set_to_null()); + + AssertSql( + """ +@p1='1' +@p0=NULL (Size = 8000) + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [TestNullableEnumCollection] = @p0 +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_relational_collection_of_nullable_enum_with_int_converter() + { + await base.Edit_single_property_relational_collection_of_nullable_enum_with_int_converter(); + + AssertSql( + """ +@p1='1' +@p0='[-1,-3,-7,2]' (Size = 8000) + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [TestNullableEnumWithIntConverterCollection] = @p0 +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_relational_collection_of_nullable_enum_with_int_converter_set_to_null() + { + // TODO:SQLJSON Updates to null fail (See UpdateToNull.cs) + await Assert.ThrowsAsync( + () => base.Edit_single_property_relational_collection_of_nullable_enum_with_int_converter_set_to_null()); + + AssertSql( + """ +@p1='1' +@p0=NULL (Size = 8000) + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [TestNullableEnumWithIntConverterCollection] = @p0 +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_relational_collection_of_nullable_enum_with_converter_that_handles_nulls() + { + await base.Edit_single_property_relational_collection_of_nullable_enum_with_converter_that_handles_nulls(); + + AssertSql( + """ +@p1='1' +@p0='[-1]' (Size = 8000) + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [TestNullableEnumWithConverterThatHandlesNullsCollection] = @p0 +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_relational_collection_of_nullable_enum_with_converter_that_handles_nulls_set_to_null() + { + // TODO:SQLJSON Updates to null fail (See UpdateToNull.cs) + await Assert.ThrowsAsync( + () => base.Edit_single_property_relational_collection_of_nullable_enum_with_converter_that_handles_nulls_set_to_null()); + + AssertSql( + """ +@p1='1' +@p0=NULL (Size = 8000) + +SET IMPLICIT_TRANSACTIONS OFF; +SET NOCOUNT ON; +UPDATE [JsonEntitiesAllTypes] SET [TestNullableEnumWithConverterThatHandlesNullsCollection] = @p0 +OUTPUT 1 +WHERE [Id] = @p1; +""", + // + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + public override async Task Edit_single_property_collection_of_collection_of_int64() + { + await base.Edit_single_property_collection_of_collection_of_int64(); + + AssertSql( + """ +SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] +FROM [JsonEntitiesAllTypes] AS [j] +WHERE [j].[Id] = 1 +"""); + } + + protected override void ClearLog() + => Fixture.TestSqlLoggerFactory.Clear(); + + private void AssertSql(params string[] expected) + => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); +} diff --git a/test/EFCore.SqlServer.FunctionalTests/Update/JsonUpdateSqlServerFixture.cs b/test/EFCore.SqlServer.FunctionalTests/Update/JsonUpdateSqlServerFixture.cs index 719cbced154..fb12560e0c8 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Update/JsonUpdateSqlServerFixture.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Update/JsonUpdateSqlServerFixture.cs @@ -12,6 +12,9 @@ public class JsonUpdateSqlServerFixture : JsonUpdateFixtureBase protected override ITestStoreFactory TestStoreFactory => SqlServerTestStoreFactory.Instance; + public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) + => base.AddOptions(builder).ConfigureWarnings(e => e.Log(SqlServerEventId.JsonTypeExperimental)); + protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) { base.OnModelCreating(modelBuilder, context); diff --git a/test/EFCore.SqlServer.FunctionalTests/Update/JsonUpdateSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Update/JsonUpdateSqlServerTest.cs index 05ce6fb7ce2..42fee62b579 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Update/JsonUpdateSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Update/JsonUpdateSqlServerTest.cs @@ -11,9 +11,7 @@ public class JsonUpdateSqlServerTest : JsonUpdateTestBase ClearLog(); public override async Task Add_element_to_json_collection_branch() { @@ -21,7 +19,7 @@ public override async Task Add_element_to_json_collection_branch() AssertSql( """ -@p0='[{"Date":"2101-01-01T00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":10.1,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_c1_c1"},{"SomethingSomething":"e1_r_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_c1_r"}},{"Date":"2102-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":10.2,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_c2_c1"},{"SomethingSomething":"e1_r_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_c2_r"}},{"Date":"2010-10-10T00:00:00","Enum":-3,"Enums":null,"Fraction":42.42,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":[{"SomethingSomething":"ss1"},{"SomethingSomething":"ss2"}],"OwnedReferenceLeaf":{"SomethingSomething":"ss3"}}]' (Nullable = false) (Size = 789) +@p0='[{"Date":"2101-01-01T00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":10.1,"Id":89,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_c1_c1"},{"SomethingSomething":"e1_r_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_c1_r"}},{"Date":"2102-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":10.2,"Id":90,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_c2_c1"},{"SomethingSomething":"e1_r_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_c2_r"}},{"Date":"2010-10-10T00:00:00","Enum":-3,"Enums":null,"Fraction":42.42,"Id":77,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":[{"SomethingSomething":"ss1"},{"SomethingSomething":"ss2"}],"OwnedReferenceLeaf":{"SomethingSomething":"ss3"}}]' (Nullable = false) (Size = 813) @p1='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -65,7 +63,7 @@ public override async Task Add_element_to_json_collection_on_derived() AssertSql( """ -@p0='[{"Date":"2221-01-01T00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":221.1,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"d2_r_c1"},{"SomethingSomething":"d2_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"d2_r_r"}},{"Date":"2222-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":222.1,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"d2_r_c1"},{"SomethingSomething":"d2_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"d2_r_r"}},{"Date":"2010-10-10T00:00:00","Enum":-3,"Enums":null,"Fraction":42.42,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":[{"SomethingSomething":"ss1"},{"SomethingSomething":"ss2"}],"OwnedReferenceLeaf":{"SomethingSomething":"ss3"}}]' (Nullable = false) (Size = 773) +@p0='[{"Date":"2221-01-01T00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":221.1,"Id":104,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"d2_r_c1"},{"SomethingSomething":"d2_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"d2_r_r"}},{"Date":"2222-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":222.1,"Id":105,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"d2_r_c1"},{"SomethingSomething":"d2_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"d2_r_r"}},{"Date":"2010-10-10T00:00:00","Enum":-3,"Enums":null,"Fraction":42.42,"Id":77,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":[{"SomethingSomething":"ss1"},{"SomethingSomething":"ss2"}],"OwnedReferenceLeaf":{"SomethingSomething":"ss3"}}]' (Nullable = false) (Size = 799) @p1='2' SET IMPLICIT_TRANSACTIONS OFF; @@ -88,7 +86,7 @@ public override async Task Add_element_to_json_collection_root() AssertSql( """ -@p0='[{"Name":"e1_c1","Names":["e1_c11","e1_c12"],"Number":11,"Numbers":[-1000,0,1000],"OwnedCollectionBranch":[{"Date":"2111-01-01T00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":11.1,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_c1_c1"},{"SomethingSomething":"e1_c1_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c1_r"}},{"Date":"2112-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":11.2,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_c2_c1"},{"SomethingSomething":"e1_c1_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c2_r"}}],"OwnedReferenceBranch":{"Date":"2110-01-01T00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":11.0,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_r_c1"},{"SomethingSomething":"e1_c1_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_r_r"}}},{"Name":"e1_c2","Names":["e1_c21","e1_c22"],"Number":12,"Numbers":[-1001,0,1001],"OwnedCollectionBranch":[{"Date":"2121-01-01T00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":12.1,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_c1_c1"},{"SomethingSomething":"e1_c2_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_c1_r"}},{"Date":"2122-01-01T00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":12.2,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_c2_c1"},{"SomethingSomething":"e1_c2_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_c2_r"}}],"OwnedReferenceBranch":{"Date":"2120-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":12.0,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_r_c1"},{"SomethingSomething":"e1_c2_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_r_r"}}},{"Name":"new Name","Names":null,"Number":142,"Numbers":null,"OwnedCollectionBranch":[],"OwnedReferenceBranch":{"Date":"2010-10-10T00:00:00","Enum":-3,"Enums":null,"Fraction":42.42,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":[{"SomethingSomething":"ss1"},{"SomethingSomething":"ss2"}],"OwnedReferenceLeaf":{"SomethingSomething":"ss3"}}}]' (Nullable = false) (Size = 2268) +@p0='[{"Id":0,"Name":"e1_c1","Names":["e1_c11","e1_c12"],"Number":11,"Numbers":[-1000,0,1000],"OwnedCollectionBranch":[{"Date":"2111-01-01T00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":11.1,"Id":92,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_c1_c1"},{"SomethingSomething":"e1_c1_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c1_r"}},{"Date":"2112-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":11.2,"Id":93,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_c2_c1"},{"SomethingSomething":"e1_c1_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c2_r"}}],"OwnedReferenceBranch":{"Date":"2110-01-01T00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":11.0,"Id":91,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_r_c1"},{"SomethingSomething":"e1_c1_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_r_r"}}},{"Id":0,"Name":"e1_c2","Names":["e1_c21","e1_c22"],"Number":12,"Numbers":[-1001,0,1001],"OwnedCollectionBranch":[{"Date":"2121-01-01T00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":12.1,"Id":95,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_c1_c1"},{"SomethingSomething":"e1_c2_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_c1_r"}},{"Date":"2122-01-01T00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":12.2,"Id":96,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_c2_c1"},{"SomethingSomething":"e1_c2_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_c2_r"}}],"OwnedReferenceBranch":{"Date":"2120-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":12.0,"Id":94,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_r_c1"},{"SomethingSomething":"e1_c2_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_r_r"}}},{"Id":0,"Name":"new Name","Names":null,"Number":142,"Numbers":null,"OwnedCollectionBranch":[],"OwnedReferenceBranch":{"Date":"2010-10-10T00:00:00","Enum":-3,"Enums":null,"Fraction":42.42,"Id":7,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":[{"SomethingSomething":"ss1"},{"SomethingSomething":"ss2"}],"OwnedReferenceLeaf":{"SomethingSomething":"ss3"}}}]' (Nullable = false) (Size = 2344) @p1='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -110,7 +108,7 @@ public override async Task Add_element_to_json_collection_root_null_navigations( AssertSql( """ -@p0='[{"Name":"e1_c1","Names":["e1_c11","e1_c12"],"Number":11,"Numbers":[-1000,0,1000],"OwnedCollectionBranch":[{"Date":"2111-01-01T00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":11.1,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_c1_c1"},{"SomethingSomething":"e1_c1_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c1_r"}},{"Date":"2112-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":11.2,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_c2_c1"},{"SomethingSomething":"e1_c1_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c2_r"}}],"OwnedReferenceBranch":{"Date":"2110-01-01T00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":11.0,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_r_c1"},{"SomethingSomething":"e1_c1_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_r_r"}}},{"Name":"e1_c2","Names":["e1_c21","e1_c22"],"Number":12,"Numbers":[-1001,0,1001],"OwnedCollectionBranch":[{"Date":"2121-01-01T00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":12.1,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_c1_c1"},{"SomethingSomething":"e1_c2_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_c1_r"}},{"Date":"2122-01-01T00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":12.2,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_c2_c1"},{"SomethingSomething":"e1_c2_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_c2_r"}}],"OwnedReferenceBranch":{"Date":"2120-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":12.0,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_r_c1"},{"SomethingSomething":"e1_c2_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_r_r"}}},{"Name":"new Name","Names":null,"Number":142,"Numbers":null,"OwnedCollectionBranch":null,"OwnedReferenceBranch":{"Date":"2010-10-10T00:00:00","Enum":-3,"Enums":null,"Fraction":42.42,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":null,"OwnedReferenceLeaf":null}}]' (Nullable = false) (Size = 2191) +@p0='[{"Id":0,"Name":"e1_c1","Names":["e1_c11","e1_c12"],"Number":11,"Numbers":[-1000,0,1000],"OwnedCollectionBranch":[{"Date":"2111-01-01T00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":11.1,"Id":92,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_c1_c1"},{"SomethingSomething":"e1_c1_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c1_r"}},{"Date":"2112-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":11.2,"Id":93,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_c2_c1"},{"SomethingSomething":"e1_c1_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c2_r"}}],"OwnedReferenceBranch":{"Date":"2110-01-01T00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":11.0,"Id":91,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_r_c1"},{"SomethingSomething":"e1_c1_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_r_r"}}},{"Id":0,"Name":"e1_c2","Names":["e1_c21","e1_c22"],"Number":12,"Numbers":[-1001,0,1001],"OwnedCollectionBranch":[{"Date":"2121-01-01T00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":12.1,"Id":95,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_c1_c1"},{"SomethingSomething":"e1_c2_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_c1_r"}},{"Date":"2122-01-01T00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":12.2,"Id":96,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_c2_c1"},{"SomethingSomething":"e1_c2_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_c2_r"}}],"OwnedReferenceBranch":{"Date":"2120-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":12.0,"Id":94,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_r_c1"},{"SomethingSomething":"e1_c2_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_r_r"}}},{"Id":0,"Name":"new Name","Names":null,"Number":142,"Numbers":null,"OwnedCollectionBranch":null,"OwnedReferenceBranch":{"Date":"2010-10-10T00:00:00","Enum":-3,"Enums":null,"Fraction":42.42,"Id":7,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":null,"OwnedReferenceLeaf":null}}]' (Nullable = false) (Size = 2267) @p1='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -132,7 +130,7 @@ public override async Task Add_entity_with_json() AssertSql( """ -@p0='{"Name":"RootName","Names":null,"Number":42,"Numbers":null,"OwnedCollectionBranch":[],"OwnedReferenceBranch":{"Date":"2010-10-10T00:00:00","Enum":-3,"Enums":null,"Fraction":42.42,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":[{"SomethingSomething":"ss1"},{"SomethingSomething":"ss2"}],"OwnedReferenceLeaf":{"SomethingSomething":"ss3"}}}' (Nullable = false) (Size = 353) +@p0='{"Id":0,"Name":"RootName","Names":null,"Number":42,"Numbers":null,"OwnedCollectionBranch":[],"OwnedReferenceBranch":{"Date":"2010-10-10T00:00:00","Enum":-3,"Enums":null,"Fraction":42.42,"Id":7,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":[{"SomethingSomething":"ss1"},{"SomethingSomething":"ss2"}],"OwnedReferenceLeaf":{"SomethingSomething":"ss3"}}}' (Nullable = false) (Size = 367) @p1='[]' (Nullable = false) (Size = 2) @p2='2' @p3=NULL (DbType = Int32) @@ -156,7 +154,7 @@ public override async Task Add_entity_with_json_null_navigations() AssertSql( """ -@p0='{"Name":"RootName","Names":null,"Number":42,"Numbers":null,"OwnedCollectionBranch":null,"OwnedReferenceBranch":{"Date":"2010-10-10T00:00:00","Enum":-3,"Enums":null,"Fraction":42.42,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":[{"SomethingSomething":"ss1"},{"SomethingSomething":"ss2"}],"OwnedReferenceLeaf":null}}' (Nullable = false) (Size = 331) +@p0='{"Id":0,"Name":"RootName","Names":null,"Number":42,"Numbers":null,"OwnedCollectionBranch":null,"OwnedReferenceBranch":{"Date":"2010-10-10T00:00:00","Enum":-3,"Enums":null,"Fraction":42.42,"Id":7,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":[{"SomethingSomething":"ss1"},{"SomethingSomething":"ss2"}],"OwnedReferenceLeaf":null}}' (Nullable = false) (Size = 345) @p1='2' @p2=NULL (DbType = Int32) @p3='NewEntity' (Size = 4000) @@ -201,7 +199,7 @@ public override async Task Add_json_reference_root() AssertSql( """ -@p0='{"Name":"RootName","Names":null,"Number":42,"Numbers":null,"OwnedCollectionBranch":[],"OwnedReferenceBranch":{"Date":"2010-10-10T00:00:00","Enum":-3,"Enums":null,"Fraction":42.42,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":[{"SomethingSomething":"ss1"},{"SomethingSomething":"ss2"}],"OwnedReferenceLeaf":{"SomethingSomething":"ss3"}}}' (Nullable = false) (Size = 353) +@p0='{"Id":0,"Name":"RootName","Names":null,"Number":42,"Numbers":null,"OwnedCollectionBranch":[],"OwnedReferenceBranch":{"Date":"2010-10-10T00:00:00","Enum":-3,"Enums":null,"Fraction":42.42,"Id":7,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":[{"SomethingSomething":"ss1"},{"SomethingSomething":"ss2"}],"OwnedReferenceLeaf":{"SomethingSomething":"ss3"}}}' (Nullable = false) (Size = 367) @p1='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -332,7 +330,7 @@ public override async Task Edit_element_in_json_collection_branch() AssertSql( """ -@p0='2111-11-11T00:00:00' (Nullable = false) (Size = 19) +@p0='2111-11-11T00:00:00' (Nullable = false) (Size = 4000) @p1='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -398,8 +396,8 @@ public override async Task Edit_element_in_json_multiple_levels_partial_update() AssertSql( """ -@p0='[{"Date":"2111-01-01T00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":11.1,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"...and another"},{"SomethingSomething":"e1_c1_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c1_r"}},{"Date":"2112-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":11.2,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"yet another change"},{"SomethingSomething":"and another"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c2_r"}}]' (Nullable = false) (Size = 561) -@p1='{"Name":"edit","Names":["e1_r1","e1_r2"],"Number":10,"Numbers":[-2147483648,-1,0,1,2147483647],"OwnedCollectionBranch":[{"Date":"2101-01-01T00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":10.1,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_c1_c1"},{"SomethingSomething":"e1_r_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_c1_r"}},{"Date":"2102-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":10.2,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_c2_c1"},{"SomethingSomething":"e1_r_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_c2_r"}}],"OwnedReferenceBranch":{"Date":"2111-11-11T00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":10.0,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_r_c1"},{"SomethingSomething":"e1_r_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_r_r"}}}' (Nullable = false) (Size = 960) +@p0='[{"Date":"2111-01-01T00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":11.1,"Id":92,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"...and another"},{"SomethingSomething":"e1_c1_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c1_r"}},{"Date":"2112-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":11.2,"Id":93,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"yet another change"},{"SomethingSomething":"and another"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c2_r"}}]' (Nullable = false) (Size = 577) +@p1='{"Id":0,"Name":"edit","Names":["e1_r1","e1_r2"],"Number":10,"Numbers":[-2147483648,-1,0,1,2147483647],"OwnedCollectionBranch":[{"Date":"2101-01-01T00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":10.1,"Id":89,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_c1_c1"},{"SomethingSomething":"e1_r_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_c1_r"}},{"Date":"2102-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":10.2,"Id":90,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_c2_c1"},{"SomethingSomething":"e1_r_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_c2_r"}}],"OwnedReferenceBranch":{"Date":"2111-11-11T00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":10.0,"Id":88,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_r_c1"},{"SomethingSomething":"e1_r_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_r_r"}}}' (Nullable = false) (Size = 991) @p2='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -421,7 +419,7 @@ public override async Task Edit_element_in_json_branch_collection_and_add_elemen AssertSql( """ -@p0='[{"Date":"2101-01-01T00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":4321.3,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_c1_c1"},{"SomethingSomething":"e1_r_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_c1_r"}},{"Date":"2102-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":10.2,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_c2_c1"},{"SomethingSomething":"e1_r_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_c2_r"}},{"Date":"2222-11-11T00:00:00","Enum":-3,"Enums":null,"Fraction":45.32,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":null,"OwnedReferenceLeaf":{"SomethingSomething":"cc"}}]' (Nullable = false) (Size = 735) +@p0='[{"Date":"2101-01-01T00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":4321.3,"Id":89,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_c1_c1"},{"SomethingSomething":"e1_r_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_c1_r"}},{"Date":"2102-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":10.2,"Id":90,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_c2_c1"},{"SomethingSomething":"e1_r_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_c2_r"}},{"Date":"2222-11-11T00:00:00","Enum":-3,"Enums":null,"Fraction":45.32,"Id":77,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":null,"OwnedReferenceLeaf":{"SomethingSomething":"cc"}}]' (Nullable = false) (Size = 759) @p1='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -465,7 +463,7 @@ public override async Task Edit_two_elements_in_the_same_json_collection_at_the_ AssertSql( """ -@p0='[{"Name":"edit1","Names":["e1_c11","e1_c12"],"Number":11,"Numbers":[-1000,0,1000],"OwnedCollectionBranch":[{"Date":"2111-01-01T00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":11.1,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_c1_c1"},{"SomethingSomething":"e1_c1_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c1_r"}},{"Date":"2112-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":11.2,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_c2_c1"},{"SomethingSomething":"e1_c1_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c2_r"}}],"OwnedReferenceBranch":{"Date":"2110-01-01T00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":11.0,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_r_c1"},{"SomethingSomething":"e1_c1_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_r_r"}}},{"Name":"edit2","Names":["e1_c21","e1_c22"],"Number":12,"Numbers":[-1001,0,1001],"OwnedCollectionBranch":[{"Date":"2121-01-01T00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":12.1,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_c1_c1"},{"SomethingSomething":"e1_c2_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_c1_r"}},{"Date":"2122-01-01T00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":12.2,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_c2_c1"},{"SomethingSomething":"e1_c2_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_c2_r"}}],"OwnedReferenceBranch":{"Date":"2120-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":12.0,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_r_c1"},{"SomethingSomething":"e1_c2_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_r_r"}}}]' (Nullable = false) (Size = 1913) +@p0='[{"Id":0,"Name":"edit1","Names":["e1_c11","e1_c12"],"Number":11,"Numbers":[-1000,0,1000],"OwnedCollectionBranch":[{"Date":"2111-01-01T00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":11.1,"Id":92,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_c1_c1"},{"SomethingSomething":"e1_c1_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c1_r"}},{"Date":"2112-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":11.2,"Id":93,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_c2_c1"},{"SomethingSomething":"e1_c1_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c2_r"}}],"OwnedReferenceBranch":{"Date":"2110-01-01T00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":11.0,"Id":91,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_r_c1"},{"SomethingSomething":"e1_c1_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_r_r"}}},{"Id":0,"Name":"edit2","Names":["e1_c21","e1_c22"],"Number":12,"Numbers":[-1001,0,1001],"OwnedCollectionBranch":[{"Date":"2121-01-01T00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":12.1,"Id":95,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_c1_c1"},{"SomethingSomething":"e1_c2_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_c1_r"}},{"Date":"2122-01-01T00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":12.2,"Id":96,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_c2_c1"},{"SomethingSomething":"e1_c2_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_c2_r"}}],"OwnedReferenceBranch":{"Date":"2120-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":12.0,"Id":94,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_r_c1"},{"SomethingSomething":"e1_c2_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_r_r"}}}]' (Nullable = false) (Size = 1975) @p1='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -487,7 +485,7 @@ public override async Task Edit_collection_element_and_reference_at_once() AssertSql( """ -@p0='{"Date":"2102-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":10.2,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"edit1"},{"SomethingSomething":"e1_r_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"edit2"}}' (Nullable = false) (Size = 262) +@p0='{"Date":"2102-01-01T00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":10.2,"Id":90,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"edit1"},{"SomethingSomething":"e1_r_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"edit2"}}' (Nullable = false) (Size = 270) @p1='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -603,7 +601,7 @@ public override async Task Edit_single_property_char() AssertSql( """ -@p0='t' (Nullable = false) (Size = 1) +@p0='t' (Nullable = false) (Size = 4000) @p1='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -626,8 +624,8 @@ public override async Task Edit_single_property_datetime() AssertSql( """ -@p0='3000-01-01T12:34:56' (Nullable = false) (Size = 19) -@p1='3000-01-01T12:34:56' (Nullable = false) (Size = 19) +@p0='3000-01-01T12:34:56' (Nullable = false) (Size = 4000) +@p1='3000-01-01T12:34:56' (Nullable = false) (Size = 4000) @p2='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -650,8 +648,8 @@ public override async Task Edit_single_property_datetimeoffset() AssertSql( """ -@p0='3000-01-01T12:34:56-04:00' (Nullable = false) (Size = 25) -@p1='3000-01-01T12:34:56-04:00' (Nullable = false) (Size = 25) +@p0='3000-01-01T12:34:56-04:00' (Nullable = false) (Size = 4000) +@p1='3000-01-01T12:34:56-04:00' (Nullable = false) (Size = 4000) @p2='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -722,8 +720,8 @@ public override async Task Edit_single_property_guid() AssertSql( """ -@p0='12345678-1234-4321-5555-987654321000' (Nullable = false) (Size = 36) -@p1='12345678-1234-4321-5555-987654321000' (Nullable = false) (Size = 36) +@p0='12345678-1234-4321-5555-987654321000' (Nullable = false) (Size = 4000) +@p1='12345678-1234-4321-5555-987654321000' (Nullable = false) (Size = 4000) @p2='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -866,8 +864,8 @@ public override async Task Edit_single_property_timespan() AssertSql( """ -@p0='10:01:01.007' (Nullable = false) (Size = 12) -@p1='10:01:01.007' (Nullable = false) (Size = 12) +@p0='10:01:01.007' (Nullable = false) (Size = 4000) +@p1='10:01:01.007' (Nullable = false) (Size = 4000) @p2='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -1226,7 +1224,7 @@ public override async Task Edit_a_scalar_property_and_reference_navigation_on_th AssertSql( """ -@p0='{"Date":"2100-01-01T00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":523.532,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_r_c1"},{"SomethingSomething":"e1_r_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"edit"}}' (Nullable = false) (Size = 270) +@p0='{"Date":"2100-01-01T00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":523.532,"Id":88,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_r_c1"},{"SomethingSomething":"e1_r_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"edit"}}' (Nullable = false) (Size = 278) @p1='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -1248,7 +1246,7 @@ public override async Task Edit_a_scalar_property_and_collection_navigation_on_t AssertSql( """ -@p0='{"Date":"2100-01-01T00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":523.532,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"edit"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_r_r"}}' (Nullable = false) (Size = 234) +@p0='{"Date":"2100-01-01T00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":523.532,"Id":88,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"edit"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_r_r"}}' (Nullable = false) (Size = 242) @p1='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -1270,7 +1268,7 @@ public override async Task Edit_a_scalar_property_and_another_property_behind_re AssertSql( """ -@p0='{"Date":"2100-01-01T00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":523.532,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_r_c1"},{"SomethingSomething":"e1_r_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"edit"}}' (Nullable = false) (Size = 270) +@p0='{"Date":"2100-01-01T00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":523.532,"Id":88,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_r_c1"},{"SomethingSomething":"e1_r_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"edit"}}' (Nullable = false) (Size = 278) @p1='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -1315,7 +1313,7 @@ public override async Task Edit_single_property_with_converter_bool_to_string_Tr AssertSql( """ -@p0='True' (Nullable = false) (Size = 5) +@p0='True' (Nullable = false) (Size = 4000) @p1='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -1338,7 +1336,7 @@ public override async Task Edit_single_property_with_converter_bool_to_string_Y_ AssertSql( """ -@p0='N' (Nullable = false) (Size = 1) +@p0='N' (Nullable = false) (Size = 4000) @p1='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -1432,8 +1430,8 @@ public override async Task Edit_single_property_collection_of_numeric() AssertSql( """ -@p0='[1024,2048]' (Nullable = false) (Size = 4000) -@p1='[999,997]' (Nullable = false) (Size = 4000) +@p0='[1024,2048]' (Nullable = false) (Size = 11) +@p1='[999,997]' (Nullable = false) (Size = 9) @p2='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -1455,8 +1453,8 @@ public override async Task Edit_single_property_collection_of_bool() AssertSql( """ -@p0='[true,true,true,false]' (Nullable = false) (Size = 4000) -@p1='[true,true,false]' (Nullable = false) (Size = 4000) +@p0='[true,true,true,false]' (Nullable = false) (Size = 22) +@p1='[true,true,false]' (Nullable = false) (Size = 17) @p2='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -1479,8 +1477,8 @@ public override async Task Edit_single_property_collection_of_byte() AssertSql( """ -@p0='Dg==' (Nullable = false) (Size = 4) -@p1='GRo=' (Nullable = false) (Size = 4) +@p0='Dg==' (Nullable = false) (Size = 4000) +@p1='GRo=' (Nullable = false) (Size = 4000) @p2='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -1503,8 +1501,8 @@ public override async Task Edit_single_property_collection_of_char() AssertSql( """ -@p0='["A","B","\u0022","\u0000"]' (Nullable = false) (Size = 4000) -@p1='["E","F","C","\u00F6","r","E","\u0022","\\"]' (Nullable = false) (Size = 4000) +@p0='["A","B","\u0022","\u0000"]' (Nullable = false) (Size = 27) +@p1='["E","F","C","\u00F6","r","E","\u0022","\\"]' (Nullable = false) (Size = 44) @p2='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -1527,8 +1525,8 @@ public override async Task Edit_single_property_collection_of_datetime() AssertSql( """ -@p0='["2000-01-01T12:34:56","3000-01-01T12:34:56","3000-01-01T12:34:56"]' (Nullable = false) (Size = 4000) -@p1='["2000-01-01T12:34:56","3000-01-01T12:34:56","3000-01-01T12:34:56"]' (Nullable = false) (Size = 4000) +@p0='["2000-01-01T12:34:56","3000-01-01T12:34:56","3000-01-01T12:34:56"]' (Nullable = false) (Size = 67) +@p1='["2000-01-01T12:34:56","3000-01-01T12:34:56","3000-01-01T12:34:56"]' (Nullable = false) (Size = 67) @p2='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -1551,8 +1549,8 @@ public override async Task Edit_single_property_collection_of_datetimeoffset() AssertSql( """ -@p0='["3000-01-01T12:34:56-04:00"]' (Nullable = false) (Size = 4000) -@p1='["3000-01-01T12:34:56-04:00"]' (Nullable = false) (Size = 4000) +@p0='["3000-01-01T12:34:56-04:00"]' (Nullable = false) (Size = 29) +@p1='["3000-01-01T12:34:56-04:00"]' (Nullable = false) (Size = 29) @p2='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -1575,8 +1573,8 @@ public override async Task Edit_single_property_collection_of_decimal() AssertSql( """ -@p0='[-13579.01]' (Nullable = false) (Size = 4000) -@p1='[-13579.01]' (Nullable = false) (Size = 4000) +@p0='[-13579.01]' (Nullable = false) (Size = 11) +@p1='[-13579.01]' (Nullable = false) (Size = 11) @p2='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -1599,8 +1597,8 @@ public override async Task Edit_single_property_collection_of_double() AssertSql( """ -@p0='[-1.23456789,1.23456789,0,-1.23579]' (Nullable = false) (Size = 4000) -@p1='[-1.23456789,1.23456789,0,-1.23579]' (Nullable = false) (Size = 4000) +@p0='[-1.23456789,1.23456789,0,-1.23579]' (Nullable = false) (Size = 35) +@p1='[-1.23456789,1.23456789,0,-1.23579]' (Nullable = false) (Size = 35) @p2='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -1623,8 +1621,8 @@ public override async Task Edit_single_property_collection_of_guid() AssertSql( """ -@p0='["12345678-1234-4321-5555-987654321000"]' (Nullable = false) (Size = 4000) -@p1='["12345678-1234-4321-5555-987654321000"]' (Nullable = false) (Size = 4000) +@p0='["12345678-1234-4321-5555-987654321000"]' (Nullable = false) (Size = 40) +@p1='["12345678-1234-4321-5555-987654321000"]' (Nullable = false) (Size = 40) @p2='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -1647,8 +1645,8 @@ public override async Task Edit_single_property_collection_of_int16() AssertSql( """ -@p0='[-3234]' (Nullable = false) (Size = 4000) -@p1='[-3234]' (Nullable = false) (Size = 4000) +@p0='[-3234]' (Nullable = false) (Size = 7) +@p1='[-3234]' (Nullable = false) (Size = 7) @p2='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -1671,8 +1669,8 @@ public override async Task Edit_single_property_collection_of_int32() AssertSql( """ -@p0='[-3234]' (Nullable = false) (Size = 4000) -@p1='[-3234]' (Nullable = false) (Size = 4000) +@p0='[-3234]' (Nullable = false) (Size = 7) +@p1='[-3234]' (Nullable = false) (Size = 7) @p2='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -1695,8 +1693,8 @@ public override async Task Edit_single_property_collection_of_int64() AssertSql( """ -@p0='[]' (Nullable = false) (Size = 4000) -@p1='[]' (Nullable = false) (Size = 4000) +@p0='[]' (Nullable = false) (Size = 2) +@p1='[]' (Nullable = false) (Size = 2) @p2='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -1719,8 +1717,8 @@ public override async Task Edit_single_property_collection_of_signed_byte() AssertSql( """ -@p0='[-108]' (Nullable = false) (Size = 4000) -@p1='[-108]' (Nullable = false) (Size = 4000) +@p0='[-108]' (Nullable = false) (Size = 6) +@p1='[-108]' (Nullable = false) (Size = 6) @p2='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -1743,8 +1741,8 @@ public override async Task Edit_single_property_collection_of_single() AssertSql( """ -@p0='[-1.234,-1.234]' (Nullable = false) (Size = 4000) -@p1='[0,-1.234]' (Nullable = false) (Size = 4000) +@p0='[-1.234,-1.234]' (Nullable = false) (Size = 15) +@p1='[0,-1.234]' (Nullable = false) (Size = 10) @p2='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -1767,8 +1765,8 @@ public override async Task Edit_single_property_collection_of_timespan() AssertSql( """ -@p0='["10:09:08.007","10:01:01.007"]' (Nullable = false) (Size = 4000) -@p1='["10:01:01.007","-9:50:51.993"]' (Nullable = false) (Size = 4000) +@p0='["10:09:08.007","10:01:01.007"]' (Nullable = false) (Size = 31) +@p1='["10:01:01.007","-9:50:51.993"]' (Nullable = false) (Size = 31) @p2='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -1791,8 +1789,8 @@ public override async Task Edit_single_property_collection_of_dateonly() AssertSql( """ -@p0='["3234-01-23","0001-01-07"]' (Nullable = false) (Size = 4000) -@p1='["0001-01-07","4321-01-21"]' (Nullable = false) (Size = 4000) +@p0='["3234-01-23","0001-01-07"]' (Nullable = false) (Size = 27) +@p1='["0001-01-07","4321-01-21"]' (Nullable = false) (Size = 27) @p2='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -1815,8 +1813,8 @@ public override async Task Edit_single_property_collection_of_timeonly() AssertSql( """ -@p0='["13:42:23.0000000","01:01:07.0000000"]' (Nullable = false) (Size = 4000) -@p1='["01:01:07.0000000","07:17:27.0000000"]' (Nullable = false) (Size = 4000) +@p0='["13:42:23.0000000","01:01:07.0000000"]' (Nullable = false) (Size = 39) +@p1='["01:01:07.0000000","07:17:27.0000000"]' (Nullable = false) (Size = 39) @p2='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -1839,8 +1837,8 @@ public override async Task Edit_single_property_collection_of_uint16() AssertSql( """ -@p0='[1534]' (Nullable = false) (Size = 4000) -@p1='[1534]' (Nullable = false) (Size = 4000) +@p0='[1534]' (Nullable = false) (Size = 6) +@p1='[1534]' (Nullable = false) (Size = 6) @p2='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -1863,8 +1861,8 @@ public override async Task Edit_single_property_collection_of_uint32() AssertSql( """ -@p0='[1237775789]' (Nullable = false) (Size = 4000) -@p1='[1237775789]' (Nullable = false) (Size = 4000) +@p0='[1237775789]' (Nullable = false) (Size = 12) +@p1='[1237775789]' (Nullable = false) (Size = 12) @p2='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -1887,8 +1885,8 @@ public override async Task Edit_single_property_collection_of_uint64() AssertSql( """ -@p0='[1234555555123456789]' (Nullable = false) (Size = 4000) -@p1='[1234555555123456789]' (Nullable = false) (Size = 4000) +@p0='[1234555555123456789]' (Nullable = false) (Size = 21) +@p1='[1234555555123456789]' (Nullable = false) (Size = 21) @p2='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -1911,8 +1909,8 @@ public override async Task Edit_single_property_collection_of_nullable_int32() AssertSql( """ -@p0='[null,77]' (Nullable = false) (Size = 4000) -@p1='[null,-2147483648,0,null,2147483647,null,77,null]' (Nullable = false) (Size = 4000) +@p0='[null,77]' (Nullable = false) (Size = 9) +@p1='[null,-2147483648,0,null,2147483647,null,77,null]' (Nullable = false) (Size = 49) @p2='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -1959,8 +1957,8 @@ public override async Task Edit_single_property_collection_of_enum() AssertSql( """ -@p0='[-3]' (Nullable = false) (Size = 4000) -@p1='[-3]' (Nullable = false) (Size = 4000) +@p0='[-3]' (Nullable = false) (Size = 4) +@p1='[-3]' (Nullable = false) (Size = 4) @p2='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -1983,8 +1981,8 @@ public override async Task Edit_single_property_collection_of_enum_with_int_conv AssertSql( """ -@p0='[-3]' (Nullable = false) (Size = 4000) -@p1='[-3]' (Nullable = false) (Size = 4000) +@p0='[-3]' (Nullable = false) (Size = 4) +@p1='[-3]' (Nullable = false) (Size = 4) @p2='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -2007,8 +2005,8 @@ public override async Task Edit_single_property_collection_of_nullable_enum() AssertSql( """ -@p0='[-3]' (Nullable = false) (Size = 4000) -@p1='[-3]' (Nullable = false) (Size = 4000) +@p0='[-3]' (Nullable = false) (Size = 4) +@p1='[-3]' (Nullable = false) (Size = 4) @p2='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -2055,8 +2053,8 @@ public override async Task Edit_single_property_collection_of_nullable_enum_with AssertSql( """ -@p0='[-1,null,-7,2]' (Nullable = false) (Size = 4000) -@p1='[-1,-3,-7,2]' (Nullable = false) (Size = 4000) +@p0='[-1,null,-7,2]' (Nullable = false) (Size = 14) +@p1='[-1,-3,-7,2]' (Nullable = false) (Size = 12) @p2='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -2103,8 +2101,8 @@ public override async Task Edit_single_property_collection_of_nullable_enum_with AssertSql( """ -@p0='[-3]' (Nullable = false) (Size = 4000) -@p1='[-1]' (Nullable = false) (Size = 4000) +@p0='[-3]' (Nullable = false) (Size = 4) +@p1='[-1]' (Nullable = false) (Size = 4) @p2='1' SET IMPLICIT_TRANSACTIONS OFF; @@ -2153,8 +2151,8 @@ public override async Task Add_and_update_top_level_optional_owned_collection_to { case true: AssertSql( - """ -@p0='[{"Name":null,"Names":null,"Number":0,"Numbers":null,"OwnedCollectionBranch":null,"OwnedReferenceBranch":null}]' (Nullable = false) (Size = 111) + """ +@p0='[{"Id":0,"Name":null,"Names":null,"Number":0,"Numbers":null,"OwnedCollectionBranch":null,"OwnedReferenceBranch":null}]' (Nullable = false) (Size = 118) @p1='2' @p2=NULL (DbType = Int32) @p3='NewEntity' (Size = 4000) @@ -2164,14 +2162,14 @@ public override async Task Add_and_update_top_level_optional_owned_collection_to INSERT INTO [JsonEntitiesBasic] ([OwnedCollectionRoot], [Id], [EntityBasicId], [Name]) VALUES (@p0, @p1, @p2, @p3); """, - // - """ + // + """ SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] FROM [JsonEntitiesBasic] AS [j] WHERE [j].[Id] = 2 """, - // - """ + // + """ @p0=NULL (Nullable = false) @p1='2' @@ -2181,12 +2179,12 @@ FROM [JsonEntitiesBasic] AS [j] OUTPUT 1 WHERE [Id] = @p1; """, - // - """ + // + """ select OwnedCollectionRoot from JsonEntitiesBasic where Id = 2 """, - // - """ + // + """ SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] FROM [JsonEntitiesBasic] AS [j] WHERE [j].[Id] = 2 @@ -2194,7 +2192,7 @@ FROM [JsonEntitiesBasic] AS [j] break; case false: AssertSql( - """ + """ @p0='[]' (Nullable = false) (Size = 2) @p1='2' @p2=NULL (DbType = Int32) @@ -2205,15 +2203,15 @@ FROM [JsonEntitiesBasic] AS [j] INSERT INTO [JsonEntitiesBasic] ([OwnedCollectionRoot], [Id], [EntityBasicId], [Name]) VALUES (@p0, @p1, @p2, @p3); """, - // - """ + // + """ SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] FROM [JsonEntitiesBasic] AS [j] WHERE [j].[Id] = 2 """, - // - """ -@p0='[{"Name":null,"Names":null,"Number":0,"Numbers":null,"OwnedCollectionBranch":null,"OwnedReferenceBranch":null}]' (Nullable = false) (Size = 111) + // + """ +@p0='[{"Id":0,"Name":null,"Names":null,"Number":0,"Numbers":null,"OwnedCollectionBranch":null,"OwnedReferenceBranch":null}]' (Nullable = false) (Size = 118) @p1='2' SET IMPLICIT_TRANSACTIONS OFF; @@ -2222,14 +2220,13 @@ FROM [JsonEntitiesBasic] AS [j] OUTPUT 1 WHERE [Id] = @p1; """, + // - - // - """ + """ select OwnedCollectionRoot from JsonEntitiesBasic where Id = 2 """, - // - """ + // + """ SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] FROM [JsonEntitiesBasic] AS [j] WHERE [j].[Id] = 2 @@ -2237,7 +2234,7 @@ FROM [JsonEntitiesBasic] AS [j] break; default: AssertSql( - """ + """ @p0='2' @p1=NULL (DbType = Int32) @p2='NewEntity' (Size = 4000) @@ -2248,14 +2245,14 @@ INSERT INTO [JsonEntitiesBasic] ([Id], [EntityBasicId], [Name]) VALUES (@p0, @p1, @p2); """, - // - """ + // + """ SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] FROM [JsonEntitiesBasic] AS [j] WHERE [j].[Id] = 2 """, - // - """ + // + """ @p0='[]' (Nullable = false) (Size = 2) @p3='2' @p1=NULL (DbType = Int32) @@ -2267,12 +2264,12 @@ FROM [JsonEntitiesBasic] AS [j] OUTPUT 1 WHERE [Id] = @p3; """, - // - """ + // + """ select OwnedCollectionRoot from JsonEntitiesBasic where Id = 2 """, - // - """ + // + """ SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] FROM [JsonEntitiesBasic] AS [j] WHERE [j].[Id] = 2 @@ -2289,8 +2286,8 @@ public override async Task Add_and_update_nested_optional_owned_collection_to_JS { case true: AssertSql( - """ -@p0='{"Name":null,"Names":null,"Number":0,"Numbers":null,"OwnedCollectionBranch":[{"Date":"0001-01-01T00:00:00","Enum":0,"Enums":null,"Fraction":0,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":null,"OwnedReferenceLeaf":null}],"OwnedReferenceBranch":null}' (Nullable = false) (Size = 266) + """ +@p0='{"Id":0,"Name":null,"Names":null,"Number":0,"Numbers":null,"OwnedCollectionBranch":[{"Date":"0001-01-01T00:00:00","Enum":0,"Enums":null,"Fraction":0,"Id":0,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":null,"OwnedReferenceLeaf":null}],"OwnedReferenceBranch":null}' (Nullable = false) (Size = 280) @p1='2' @p2=NULL (DbType = Int32) @p3='NewEntity' (Size = 4000) @@ -2300,14 +2297,14 @@ public override async Task Add_and_update_nested_optional_owned_collection_to_JS INSERT INTO [JsonEntitiesBasic] ([OwnedReferenceRoot], [Id], [EntityBasicId], [Name]) VALUES (@p0, @p1, @p2, @p3); """, - // - """ + // + """ SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] FROM [JsonEntitiesBasic] AS [j] WHERE [j].[Id] = 2 """, - // - """ + // + """ @p0=NULL (Nullable = false) @p1='2' @@ -2317,8 +2314,8 @@ FROM [JsonEntitiesBasic] AS [j] OUTPUT 1 WHERE [Id] = @p1; """, - // - """ + // + """ SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] FROM [JsonEntitiesBasic] AS [j] WHERE [j].[Id] = 2 @@ -2326,8 +2323,8 @@ FROM [JsonEntitiesBasic] AS [j] break; case false: AssertSql( - """ -@p0='{"Name":null,"Names":null,"Number":0,"Numbers":null,"OwnedCollectionBranch":[],"OwnedReferenceBranch":null}' (Nullable = false) (Size = 107) + """ +@p0='{"Id":0,"Name":null,"Names":null,"Number":0,"Numbers":null,"OwnedCollectionBranch":[],"OwnedReferenceBranch":null}' (Nullable = false) (Size = 114) @p1='2' @p2=NULL (DbType = Int32) @p3='NewEntity' (Size = 4000) @@ -2337,15 +2334,15 @@ FROM [JsonEntitiesBasic] AS [j] INSERT INTO [JsonEntitiesBasic] ([OwnedReferenceRoot], [Id], [EntityBasicId], [Name]) VALUES (@p0, @p1, @p2, @p3); """, - // - """ + // + """ SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] FROM [JsonEntitiesBasic] AS [j] WHERE [j].[Id] = 2 """, - // - """ -@p0='[{"Date":"0001-01-01T00:00:00","Enum":0,"Enums":null,"Fraction":0,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":null,"OwnedReferenceLeaf":null}]' (Nullable = false) (Size = 161) + // + """ +@p0='[{"Date":"0001-01-01T00:00:00","Enum":0,"Enums":null,"Fraction":0,"Id":0,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":null,"OwnedReferenceLeaf":null}]' (Nullable = false) (Size = 168) @p1='2' SET IMPLICIT_TRANSACTIONS OFF; @@ -2354,8 +2351,8 @@ FROM [JsonEntitiesBasic] AS [j] OUTPUT 1 WHERE [Id] = @p1; """, - // - """ + // + """ SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] FROM [JsonEntitiesBasic] AS [j] WHERE [j].[Id] = 2 @@ -2363,8 +2360,8 @@ FROM [JsonEntitiesBasic] AS [j] break; default: AssertSql( - """ -@p0='{"Name":null,"Names":null,"Number":0,"Numbers":null,"OwnedCollectionBranch":null,"OwnedReferenceBranch":null}' (Nullable = false) (Size = 109) + """ +@p0='{"Id":0,"Name":null,"Names":null,"Number":0,"Numbers":null,"OwnedCollectionBranch":null,"OwnedReferenceBranch":null}' (Nullable = false) (Size = 116) @p1='2' @p2=NULL (DbType = Int32) @p3='NewEntity' (Size = 4000) @@ -2374,15 +2371,15 @@ FROM [JsonEntitiesBasic] AS [j] INSERT INTO [JsonEntitiesBasic] ([OwnedReferenceRoot], [Id], [EntityBasicId], [Name]) VALUES (@p0, @p1, @p2, @p3); """, - // - """ + // + """ SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] FROM [JsonEntitiesBasic] AS [j] WHERE [j].[Id] = 2 """, - // - """ -@p0='{"Name":null,"Names":null,"Number":0,"Numbers":null,"OwnedCollectionBranch":[],"OwnedReferenceBranch":null}' (Nullable = false) (Size = 107) + // + """ +@p0='{"Id":0,"Name":null,"Names":null,"Number":0,"Numbers":null,"OwnedCollectionBranch":[],"OwnedReferenceBranch":null}' (Nullable = false) (Size = 114) @p1='2' SET IMPLICIT_TRANSACTIONS OFF; @@ -2391,8 +2388,8 @@ FROM [JsonEntitiesBasic] AS [j] OUTPUT 1 WHERE [Id] = @p1; """, - // - """ + // + """ SELECT TOP(2) [j].[Id], [j].[EntityBasicId], [j].[Name], [j].[OwnedCollectionRoot], [j].[OwnedReferenceRoot] FROM [JsonEntitiesBasic] AS [j] WHERE [j].[Id] = 2 @@ -2405,21 +2402,28 @@ public override async Task Add_and_update_nested_optional_primitive_collection(b { await base.Add_and_update_nested_optional_primitive_collection(value); - string characterCollection = value switch + var characterCollection = value switch { - true => "[\"A\"]", + true => "[\"A\"]", false => "[]", - _ => "null" + _ => "null" }; - string parameterSize = value switch + var parameterSize = value switch { true => "1558", false => "1555", _ => "1557" }; - string updateParameter = value switch + var updateParameterSize = value switch + { + true => "4000", + false => "5", + _ => "2" + }; + + var updateParameter = value switch { true => "NULL", false => "'[\"Z\"]'", @@ -2427,7 +2431,11 @@ public override async Task Add_and_update_nested_optional_primitive_collection(b }; AssertSql( - @"@p0='[{""TestBoolean"":false,""TestBooleanCollection"":[],""TestByte"":0,""TestByteArray"":null,""TestByteCollection"":null,""TestCharacter"":""\u0000"",""TestCharacterCollection"":" + characterCollection + @",""TestDateOnly"":""0001-01-01"",""TestDateOnlyCollection"":[],""TestDateTime"":""0001-01-01T00:00:00"",""TestDateTimeCollection"":[],""TestDateTimeOffset"":""0001-01-01T00:00:00+00:00"",""TestDateTimeOffsetCollection"":[],""TestDecimal"":0,""TestDecimalCollection"":[],""TestDefaultString"":null,""TestDefaultStringCollection"":[],""TestDouble"":0,""TestDoubleCollection"":[],""TestEnum"":0,""TestEnumCollection"":[],""TestEnumWithIntConverter"":0,""TestEnumWithIntConverterCollection"":[],""TestGuid"":""00000000-0000-0000-0000-000000000000"",""TestGuidCollection"":[],""TestInt16"":0,""TestInt16Collection"":[],""TestInt32"":0,""TestInt32Collection"":[],""TestInt64"":0,""TestInt64Collection"":[],""TestMaxLengthString"":null,""TestMaxLengthStringCollection"":[],""TestNullableEnum"":null,""TestNullableEnumCollection"":[],""TestNullableEnumWithConverterThatHandlesNulls"":null,""TestNullableEnumWithConverterThatHandlesNullsCollection"":[],""TestNullableEnumWithIntConverter"":null,""TestNullableEnumWithIntConverterCollection"":[],""TestNullableInt32"":null,""TestNullableInt32Collection"":[],""TestSignedByte"":0,""TestSignedByteCollection"":[],""TestSingle"":0,""TestSingleCollection"":[],""TestTimeOnly"":""00:00:00.0000000"",""TestTimeOnlyCollection"":[],""TestTimeSpan"":""0:00:00"",""TestTimeSpanCollection"":[],""TestUnsignedInt16"":0,""TestUnsignedInt16Collection"":[],""TestUnsignedInt32"":0,""TestUnsignedInt32Collection"":[],""TestUnsignedInt64"":0,""TestUnsignedInt64Collection"":[]}]' (Nullable = false) (Size = " + parameterSize + @") + @"@p0='[{""TestBoolean"":false,""TestBooleanCollection"":[],""TestByte"":0,""TestByteArray"":null,""TestByteCollection"":null,""TestCharacter"":""\u0000"",""TestCharacterCollection"":" + + characterCollection + + @",""TestDateOnly"":""0001-01-01"",""TestDateOnlyCollection"":[],""TestDateTime"":""0001-01-01T00:00:00"",""TestDateTimeCollection"":[],""TestDateTimeOffset"":""0001-01-01T00:00:00+00:00"",""TestDateTimeOffsetCollection"":[],""TestDecimal"":0,""TestDecimalCollection"":[],""TestDefaultString"":null,""TestDefaultStringCollection"":[],""TestDouble"":0,""TestDoubleCollection"":[],""TestEnum"":0,""TestEnumCollection"":[],""TestEnumWithIntConverter"":0,""TestEnumWithIntConverterCollection"":[],""TestGuid"":""00000000-0000-0000-0000-000000000000"",""TestGuidCollection"":[],""TestInt16"":0,""TestInt16Collection"":[],""TestInt32"":0,""TestInt32Collection"":[],""TestInt64"":0,""TestInt64Collection"":[],""TestMaxLengthString"":null,""TestMaxLengthStringCollection"":[],""TestNullableEnum"":null,""TestNullableEnumCollection"":[],""TestNullableEnumWithConverterThatHandlesNulls"":null,""TestNullableEnumWithConverterThatHandlesNullsCollection"":[],""TestNullableEnumWithIntConverter"":null,""TestNullableEnumWithIntConverterCollection"":[],""TestNullableInt32"":null,""TestNullableInt32Collection"":[],""TestSignedByte"":0,""TestSignedByteCollection"":[],""TestSingle"":0,""TestSingleCollection"":[],""TestTimeOnly"":""00:00:00.0000000"",""TestTimeOnlyCollection"":[],""TestTimeSpan"":""0:00:00"",""TestTimeSpanCollection"":[],""TestUnsignedInt16"":0,""TestUnsignedInt16Collection"":[],""TestUnsignedInt32"":0,""TestUnsignedInt32Collection"":[],""TestUnsignedInt64"":0,""TestUnsignedInt64Collection"":[]}]' (Nullable = false) (Size = " + + parameterSize + + @") @p1='7624' @p2='[]' (Size = 4000) @p3=NULL (Size = 8000) (DbType = Binary) @@ -2459,15 +2467,18 @@ public override async Task Add_and_update_nested_optional_primitive_collection(b SET NOCOUNT ON; INSERT INTO [JsonEntitiesAllTypes] ([Collection], [Id], [TestBooleanCollection], [TestByteCollection], [TestCharacterCollection], [TestDateTimeCollection], [TestDateTimeOffsetCollection], [TestDecimalCollection], [TestDefaultStringCollection], [TestDoubleCollection], [TestEnumCollection], [TestEnumWithIntConverterCollection], [TestGuidCollection], [TestInt16Collection], [TestInt32Collection], [TestInt64Collection], [TestMaxLengthStringCollection], [TestNullableEnumCollection], [TestNullableEnumWithConverterThatHandlesNullsCollection], [TestNullableEnumWithIntConverterCollection], [TestNullableInt32Collection], [TestSignedByteCollection], [TestSingleCollection], [TestTimeSpanCollection], [TestUnsignedInt16Collection], [TestUnsignedInt32Collection], [TestUnsignedInt64Collection]) VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10, @p11, @p12, @p13, @p14, @p15, @p16, @p17, @p18, @p19, @p20, @p21, @p22, @p23, @p24, @p25, @p26);", - // - """ + // + """ SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] FROM [JsonEntitiesAllTypes] AS [j] WHERE [j].[Id] = 7624 """, - // - -"@p0=" + updateParameter + @" (Nullable = false) (Size = 4000) + // + "@p0=" + + updateParameter + + @" (Nullable = false) (Size = " + + updateParameterSize + + @") @p1='7624' SET IMPLICIT_TRANSACTIONS OFF; @@ -2475,8 +2486,8 @@ FROM [JsonEntitiesAllTypes] AS [j] UPDATE [JsonEntitiesAllTypes] SET [Collection] = JSON_MODIFY([Collection], 'strict $[0].TestCharacterCollection', JSON_QUERY(@p0)) OUTPUT 1 WHERE [Id] = @p1;", - // - """ + // + """ SELECT TOP(2) [j].[Id], [j].[TestBooleanCollection], [j].[TestByteCollection], [j].[TestCharacterCollection], [j].[TestDateTimeCollection], [j].[TestDateTimeOffsetCollection], [j].[TestDecimalCollection], [j].[TestDefaultStringCollection], [j].[TestDoubleCollection], [j].[TestEnumCollection], [j].[TestEnumWithIntConverterCollection], [j].[TestGuidCollection], [j].[TestInt16Collection], [j].[TestInt32Collection], [j].[TestInt64Collection], [j].[TestMaxLengthStringCollection], [j].[TestNullableEnumCollection], [j].[TestNullableEnumWithConverterThatHandlesNullsCollection], [j].[TestNullableEnumWithIntConverterCollection], [j].[TestNullableInt32Collection], [j].[TestSignedByteCollection], [j].[TestSingleCollection], [j].[TestTimeSpanCollection], [j].[TestUnsignedInt16Collection], [j].[TestUnsignedInt32Collection], [j].[TestUnsignedInt64Collection], [j].[Collection], [j].[Reference] FROM [JsonEntitiesAllTypes] AS [j] WHERE [j].[Id] = 7624 @@ -2509,7 +2520,8 @@ public override Task Edit_single_property_collection_of_collection_of_nullable_e // Nested collections are not mapped in the relational model, so there is no data stored in the document for them public override Task Edit_single_property_collection_of_collection_of_nullable_enum_with_int_converter() - => Assert.ThrowsAsync(base.Edit_single_property_collection_of_collection_of_nullable_enum_with_int_converter); + => Assert.ThrowsAsync( + base.Edit_single_property_collection_of_collection_of_nullable_enum_with_int_converter); // Nested collections are not mapped in the relational model, so there is no data stored in the document for them public override Task Edit_single_property_collection_of_collection_of_nullable_int32() diff --git a/test/EFCore.SqlServer.FunctionalTests/Update/MismatchedKeyTypesSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Update/MismatchedKeyTypesSqlServerTest.cs index 621d1edc673..9013bbabdf6 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Update/MismatchedKeyTypesSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Update/MismatchedKeyTypesSqlServerTest.cs @@ -796,11 +796,8 @@ public async Task InitializeAsync() await SeedAsync(); } - public Task DisposeAsync() - { - Store.Dispose(); - return Task.CompletedTask; - } + public async Task DisposeAsync() + => await Store.DisposeAsync(); } private class TemporaryByteValueGenerator : ValueGenerator 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 b90081b5225..2ffeb1f8853 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Update/UpdatesSqlServerTPTTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Update/UpdatesSqlServerTPTTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore.Update; -public class UpdatesSqlServerTPTTest(UpdatesSqlServerTPTTest.UpdatesSqlServerTPTFixture fixture, ITestOutputHelper testOutputHelper) : UpdatesSqlServerTestBase(fixture, testOutputHelper) +public class UpdatesSqlServerTPTTest(UpdatesSqlServerTPTTest.UpdatesSqlServerTPTFixture fixture, ITestOutputHelper testOutputHelper) + : UpdatesSqlServerTestBase(fixture, testOutputHelper) { public override async Task Save_with_shared_foreign_key() { @@ -47,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 """, @@ -74,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.SqlServer.FunctionalTests/WithConstructorsSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/WithConstructorsSqlServerTest.cs index 8b5fadfeb69..fbfb02d2b2c 100644 --- a/test/EFCore.SqlServer.FunctionalTests/WithConstructorsSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/WithConstructorsSqlServerTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class WithConstructorsSqlServerTest(WithConstructorsSqlServerTest.WithConstructorsSqlServerFixture fixture) : WithConstructorsTestBase(fixture) +public class WithConstructorsSqlServerTest(WithConstructorsSqlServerTest.WithConstructorsSqlServerFixture fixture) + : WithConstructorsTestBase(fixture) { protected override void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction) => facade.UseTransaction(transaction.GetDbTransaction()); diff --git a/test/EFCore.SqlServer.HierarchyId.Tests/CSharpDbContextGeneratorTest.cs b/test/EFCore.SqlServer.HierarchyId.Tests/CSharpDbContextGeneratorTest.cs index bf5b0752820..19e7e3e67b1 100644 --- a/test/EFCore.SqlServer.HierarchyId.Tests/CSharpDbContextGeneratorTest.cs +++ b/test/EFCore.SqlServer.HierarchyId.Tests/CSharpDbContextGeneratorTest.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.EntityFrameworkCore.Scaffolding; -using Microsoft.Extensions.DependencyInjection; using Xunit; namespace Microsoft.EntityFrameworkCore.SqlServer; diff --git a/test/EFCore.SqlServer.HierarchyId.Tests/CSharpEntityTypeGeneratorTest.cs b/test/EFCore.SqlServer.HierarchyId.Tests/CSharpEntityTypeGeneratorTest.cs index b2d6a0c5f69..77c33b38c74 100644 --- a/test/EFCore.SqlServer.HierarchyId.Tests/CSharpEntityTypeGeneratorTest.cs +++ b/test/EFCore.SqlServer.HierarchyId.Tests/CSharpEntityTypeGeneratorTest.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.EntityFrameworkCore.Scaffolding; -using Microsoft.Extensions.DependencyInjection; using Xunit; namespace Microsoft.EntityFrameworkCore.SqlServer; diff --git a/test/EFCore.SqlServer.HierarchyId.Tests/QueryTests.cs b/test/EFCore.SqlServer.HierarchyId.Tests/QueryTests.cs index 8fd14580b84..b35d1e55c07 100644 --- a/test/EFCore.SqlServer.HierarchyId.Tests/QueryTests.cs +++ b/test/EFCore.SqlServer.HierarchyId.Tests/QueryTests.cs @@ -361,8 +361,8 @@ public void Contains_with_parameter_list_can_translate() { var ids = new[] { HierarchyId.Parse("/1/1/7/"), HierarchyId.Parse("/1/1/99/") }; var result = (from p in _db.Patriarchy - where ids.Contains(p.Id) - select p.Name).Single(); + where ids.Contains(p.Id) + select p.Name).Single(); Assert.Equal( """ diff --git a/test/EFCore.SqlServer.HierarchyId.Tests/SqlServerAbstractionsApiConsistencyTest.cs b/test/EFCore.SqlServer.HierarchyId.Tests/SqlServerAbstractionsApiConsistencyTest.cs index af369f1ecba..d4dad692047 100644 --- a/test/EFCore.SqlServer.HierarchyId.Tests/SqlServerAbstractionsApiConsistencyTest.cs +++ b/test/EFCore.SqlServer.HierarchyId.Tests/SqlServerAbstractionsApiConsistencyTest.cs @@ -6,7 +6,8 @@ namespace Microsoft.EntityFrameworkCore; -public class SqlServerAbstractionsApiConsistencyTest(SqlServerAbstractionsApiConsistencyTest.SqlServerAbstractionsApiConsistencyFixture fixture) : ApiConsistencyTestBase< +public class SqlServerAbstractionsApiConsistencyTest( + SqlServerAbstractionsApiConsistencyTest.SqlServerAbstractionsApiConsistencyFixture fixture) : ApiConsistencyTestBase< SqlServerAbstractionsApiConsistencyTest.SqlServerAbstractionsApiConsistencyFixture>(fixture) { protected override void AddServices(ServiceCollection serviceCollection) diff --git a/test/EFCore.SqlServer.HierarchyId.Tests/SqlServerHierarchyIdApiConsistencyTest.cs b/test/EFCore.SqlServer.HierarchyId.Tests/SqlServerHierarchyIdApiConsistencyTest.cs index f074ed04339..370d63b5169 100644 --- a/test/EFCore.SqlServer.HierarchyId.Tests/SqlServerHierarchyIdApiConsistencyTest.cs +++ b/test/EFCore.SqlServer.HierarchyId.Tests/SqlServerHierarchyIdApiConsistencyTest.cs @@ -6,7 +6,8 @@ namespace Microsoft.EntityFrameworkCore; -public class SqlServerHierarchyIdApiConsistencyTest(SqlServerHierarchyIdApiConsistencyTest.SqlServerHierarchyIdApiConsistencyFixture fixture) : ApiConsistencyTestBase< +public class SqlServerHierarchyIdApiConsistencyTest( + SqlServerHierarchyIdApiConsistencyTest.SqlServerHierarchyIdApiConsistencyFixture fixture) : ApiConsistencyTestBase< SqlServerHierarchyIdApiConsistencyTest.SqlServerHierarchyIdApiConsistencyFixture>(fixture) { protected override void AddServices(ServiceCollection serviceCollection) diff --git a/test/EFCore.SqlServer.HierarchyId.Tests/TestModels/Migrations/TypedArraySeedContext.cs b/test/EFCore.SqlServer.HierarchyId.Tests/TestModels/Migrations/TypedArraySeedContext.cs index 2a9d39e3006..6c48eb0a679 100644 --- a/test/EFCore.SqlServer.HierarchyId.Tests/TestModels/Migrations/TypedArraySeedContext.cs +++ b/test/EFCore.SqlServer.HierarchyId.Tests/TestModels/Migrations/TypedArraySeedContext.cs @@ -1,8 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.EntityFrameworkCore.SqlServer.TestModels; - namespace Microsoft.EntityFrameworkCore.SqlServer.TestModels.Migrations; internal sealed class TypedArraySeedContext : MigrationContext diff --git a/test/EFCore.SqlServer.HierarchyId.Tests/TestUtilities/FakeScaffoldingModelFactory.cs b/test/EFCore.SqlServer.HierarchyId.Tests/TestUtilities/FakeScaffoldingModelFactory.cs index df1aaf5111b..d7fd85b5bc1 100644 --- a/test/EFCore.SqlServer.HierarchyId.Tests/TestUtilities/FakeScaffoldingModelFactory.cs +++ b/test/EFCore.SqlServer.HierarchyId.Tests/TestUtilities/FakeScaffoldingModelFactory.cs @@ -18,8 +18,8 @@ public class FakeScaffoldingModelFactory( ICSharpUtilities cSharpUtilities, IScaffoldingTypeMapper scaffoldingTypeMapper, IModelRuntimeInitializer modelRuntimeInitializer) : RelationalScaffoldingModelFactory( - reporter, candidateNamingService, pluralizer, cSharpUtilities, scaffoldingTypeMapper, - modelRuntimeInitializer) + reporter, candidateNamingService, pluralizer, cSharpUtilities, scaffoldingTypeMapper, + modelRuntimeInitializer) { public override IModel Create(DatabaseModel databaseModel, ModelReverseEngineerOptions options) { @@ -129,9 +129,7 @@ public override IList ForeignKeys internal class DatabaseColumnRef : DatabaseColumn { public DatabaseColumnRef(string name) - { - Name = name; - } + => Name = name; public override DatabaseTable Table { diff --git a/test/EFCore.SqlServer.HierarchyId.Tests/WrapperTests.cs b/test/EFCore.SqlServer.HierarchyId.Tests/WrapperTests.cs index 02672cd176d..04ed59232af 100644 --- a/test/EFCore.SqlServer.HierarchyId.Tests/WrapperTests.cs +++ b/test/EFCore.SqlServer.HierarchyId.Tests/WrapperTests.cs @@ -42,7 +42,7 @@ public void Parse_overloads_works_when_parentId_is_simpleId() [ConditionalFact] public void Parse_overloads_works_when_parentId_is_dottedString() - => Assert.Equal(HierarchyId.Parse(_parent, 2,1), HierarchyId.Parse("/1/2.1/")); + => Assert.Equal(HierarchyId.Parse(_parent, 2, 1), HierarchyId.Parse("/1/2.1/")); [ConditionalFact] public void Parse_overloads_works_when_parentId_is_empty() @@ -50,7 +50,7 @@ public void Parse_overloads_works_when_parentId_is_empty() [ConditionalFact] public void Parse_overloads_works_when_parentHierarchy_is_root_and_parentId_is_simple() - => Assert.Equal(HierarchyId.Parse(HierarchyId.GetRoot(),1), HierarchyId.Parse("/1/")); + => Assert.Equal(HierarchyId.Parse(HierarchyId.GetRoot(), 1), HierarchyId.Parse("/1/")); [ConditionalFact] public void Parse_overloads_works_when_parentHierarchy_is_root_and_parentId_is_empty() @@ -58,7 +58,7 @@ public void Parse_overloads_works_when_parentHierarchy_is_root_and_parentId_is_e [ConditionalFact] public void Parse_overloads_works_when_parentHierarchy_is_null_and_parentId_is_empty() - => Assert.Equal(HierarchyId.Parse(null,[]), HierarchyId.Parse("/")); + => Assert.Equal(HierarchyId.Parse(null, []), HierarchyId.Parse("/")); private readonly HierarchyId _parent = HierarchyId.Parse("/1/"); } diff --git a/test/EFCore.SqlServer.Tests/Design/Internal/SqlServerAnnotationCodeGeneratorTest.cs b/test/EFCore.SqlServer.Tests/Design/Internal/SqlServerAnnotationCodeGeneratorTest.cs index 2a3f79be4b5..3f04c7606b9 100644 --- a/test/EFCore.SqlServer.Tests/Design/Internal/SqlServerAnnotationCodeGeneratorTest.cs +++ b/test/EFCore.SqlServer.Tests/Design/Internal/SqlServerAnnotationCodeGeneratorTest.cs @@ -90,9 +90,9 @@ public void GenerateFluentApi_IUniqueConstraint_works_with_fillfactor() { x.Property("Something"); x.Property("SomethingElse"); - x.HasAlternateKey(["Something", "SomethingElse"]).HasFillFactor(80); + x.HasAlternateKey("Something", "SomethingElse").HasFillFactor(80); }); - + var uniqueConstraint = (IKey)modelBuilder.Model.FindEntityType("Post")!.GetKeys().Single(); var result = generator.GenerateFluentApiCalls(uniqueConstraint, uniqueConstraint.GetAnnotations().ToDictionary(a => a.Name, a => a)) .Single(); diff --git a/test/EFCore.SqlServer.Tests/Diagnostics/SqlServerEventIdTest.cs b/test/EFCore.SqlServer.Tests/Diagnostics/SqlServerEventIdTest.cs index 58ecf35c6cd..cabca35ad48 100644 --- a/test/EFCore.SqlServer.Tests/Diagnostics/SqlServerEventIdTest.cs +++ b/test/EFCore.SqlServer.Tests/Diagnostics/SqlServerEventIdTest.cs @@ -22,6 +22,7 @@ public void Every_eventId_has_a_logger_method_and_logs_when_level_enabled() { { typeof(IList), () => new List { "Fake1", "Fake2" } }, { typeof(IProperty), () => property }, + { typeof(IEntityType), () => entityType }, { typeof(IReadOnlyProperty), () => property }, { typeof(string), () => "Fake" } }; diff --git a/test/EFCore.SqlServer.Tests/Extensions/SqlServerDatabaseFacadeExtensionsTest.cs b/test/EFCore.SqlServer.Tests/Extensions/SqlServerDatabaseFacadeExtensionsTest.cs index aacf3e5255f..3798e2013f3 100644 --- a/test/EFCore.SqlServer.Tests/Extensions/SqlServerDatabaseFacadeExtensionsTest.cs +++ b/test/EFCore.SqlServer.Tests/Extensions/SqlServerDatabaseFacadeExtensionsTest.cs @@ -91,9 +91,7 @@ public TimeoutContext() } public TimeoutContext(int? commandTimeout) - { - Database.SetCommandTimeout(commandTimeout); - } + => Database.SetCommandTimeout(commandTimeout); protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder @@ -240,9 +238,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) private class SqlServerConstructorContext : SqlServerOnConfiguringContext { public SqlServerConstructorContext() - { - IsSqlServerSet = Database.IsSqlServer(); - } + => IsSqlServerSet = Database.IsSqlServer(); } private class SqlServerUseInOnConfiguringContext : SqlServerOnConfiguringContext @@ -265,9 +261,7 @@ private class ProviderConstructorContext : ProviderContext { public ProviderConstructorContext(DbContextOptions options) : base(options) - { - IsSqlServerSet = Database.IsSqlServer(); - } + => IsSqlServerSet = Database.IsSqlServer(); } private class ProviderUseInOnConfiguringContext(DbContextOptions options) : ProviderContext(options) diff --git a/test/EFCore.SqlServer.Tests/Infrastructure/SqlServerModelValidatorTest.cs b/test/EFCore.SqlServer.Tests/Infrastructure/SqlServerModelValidatorTest.cs index f28a1271469..225dc8a64f8 100644 --- a/test/EFCore.SqlServer.Tests/Infrastructure/SqlServerModelValidatorTest.cs +++ b/test/EFCore.SqlServer.Tests/Infrastructure/SqlServerModelValidatorTest.cs @@ -11,6 +11,39 @@ namespace Microsoft.EntityFrameworkCore.Infrastructure; public class SqlServerModelValidatorTest : RelationalModelValidatorTest { + [ConditionalFact] + public void Detects_use_of_json_column() + { + var modelBuilder = CreateConventionModelBuilder(); + modelBuilder.Entity().Property(e => e.Name).HasColumnType("json"); + + VerifyWarning( + SqlServerResources.LogJsonTypeExperimental(new TestLogger()) + .GenerateMessage("Cheese"), modelBuilder); + } + + [ConditionalFact] + public void Detects_use_of_json_column_for_container() + { + var modelBuilder = CreateConventionModelBuilder(); + modelBuilder.Entity( + b => + { + b.OwnsOne( + x => x.OwnedReference, bb => + { + bb.ToJson().HasColumnType("json"); + bb.Ignore(x => x.NestedCollection); + bb.Ignore(x => x.NestedReference); + }); + b.Ignore(x => x.OwnedCollection); + }); + + VerifyWarning( + SqlServerResources.LogJsonTypeExperimental(new TestLogger()) + .GenerateMessage(nameof(ValidatorJsonOwnedRoot)), modelBuilder); + } + [ConditionalFact] // Issue #34324 public virtual void Throws_for_nested_primitive_collections() { @@ -128,7 +161,6 @@ public virtual void Throws_for_sequence_on_bad_type() modelBuilder); } - [ConditionalFact] public virtual void Throws_for_sequence_HiLo_on_bad_type() { diff --git a/test/EFCore.SqlServer.Tests/Metadata/Conventions/RelationalForeignKeyIndexConventionTest.cs b/test/EFCore.SqlServer.Tests/Metadata/Conventions/RelationalForeignKeyIndexConventionTest.cs index 9235db2b099..445e8583ed5 100644 --- a/test/EFCore.SqlServer.Tests/Metadata/Conventions/RelationalForeignKeyIndexConventionTest.cs +++ b/test/EFCore.SqlServer.Tests/Metadata/Conventions/RelationalForeignKeyIndexConventionTest.cs @@ -64,6 +64,7 @@ public void Removing_relationship_does_not_remove_conventional_index_if_in_use() Assert.Equal(Order.CustomerIdProperty.Name, dependentEntityBuilder.Metadata.GetIndexes().First().Properties.First().Name); Assert.Empty(dependentEntityBuilder.Metadata.GetForeignKeys()); } + private static TestLogger CreateTestLogger() => new() { EnabledFor = LogLevel.Warning }; diff --git a/test/EFCore.SqlServer.Tests/Metadata/Conventions/SqlServerOnDeleteConventionTest.cs b/test/EFCore.SqlServer.Tests/Metadata/Conventions/SqlServerOnDeleteConventionTest.cs index ee369699f25..d89e6071c06 100644 --- a/test/EFCore.SqlServer.Tests/Metadata/Conventions/SqlServerOnDeleteConventionTest.cs +++ b/test/EFCore.SqlServer.Tests/Metadata/Conventions/SqlServerOnDeleteConventionTest.cs @@ -18,7 +18,7 @@ public void Convention_does_not_assume_skip_navigations_have_non_null_FK() public class SkippyDbContext : DbContext { - public DbSet Areas { get; private set; } + public DbSet Areas { get; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder.UseSqlServer(); diff --git a/test/EFCore.SqlServer.Tests/Metadata/SqlServerMetadataBuilderExtensionsTest.cs b/test/EFCore.SqlServer.Tests/Metadata/SqlServerMetadataBuilderExtensionsTest.cs index f138a6465f4..c744b846c0d 100644 --- a/test/EFCore.SqlServer.Tests/Metadata/SqlServerMetadataBuilderExtensionsTest.cs +++ b/test/EFCore.SqlServer.Tests/Metadata/SqlServerMetadataBuilderExtensionsTest.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.EntityFrameworkCore.Metadata.Internal; -using Microsoft.EntityFrameworkCore.SqlServer.Internal; // ReSharper disable InconsistentNaming namespace Microsoft.EntityFrameworkCore.Metadata; @@ -257,7 +256,7 @@ public void Can_access_model_performance_level() } [ConditionalFact] - public void Can_access_entity_type() + public void Can_change_entity_type_IsMemoryOptimized() { var typeBuilder = CreateBuilder().Entity(typeof(Splot)); @@ -280,6 +279,50 @@ public void Can_access_entity_type() Assert.Null(typeBuilder.Metadata.GetIsMemoryOptimizedConfigurationSource()); } + [ConditionalFact] + public void Can_change_entity_type_UseSqlOutputClause() + { + var typeBuilder = CreateBuilder().Entity(typeof(Splot)); + + Assert.Null(typeBuilder.Metadata.GetUseSqlOutputClauseConfigurationSource()); + + Assert.NotNull(typeBuilder.UseSqlOutputClause(true)); + Assert.True(typeBuilder.Metadata.IsSqlOutputClauseUsed()); + Assert.Equal(ConfigurationSource.Convention, typeBuilder.Metadata.GetUseSqlOutputClauseConfigurationSource()); + + Assert.NotNull(typeBuilder.UseSqlOutputClause(false, fromDataAnnotation: true)); + Assert.False(typeBuilder.Metadata.IsSqlOutputClauseUsed()); + Assert.Equal(ConfigurationSource.DataAnnotation, typeBuilder.Metadata.GetUseSqlOutputClauseConfigurationSource()); + + Assert.Null(typeBuilder.UseSqlOutputClause(true)); + Assert.False(typeBuilder.Metadata.IsSqlOutputClauseUsed()); + Assert.NotNull(typeBuilder.UseSqlOutputClause(false)); + + Assert.NotNull(typeBuilder.UseSqlOutputClause(null, fromDataAnnotation: true)); + Assert.True(typeBuilder.Metadata.IsSqlOutputClauseUsed()); + Assert.Null(typeBuilder.Metadata.GetUseSqlOutputClauseConfigurationSource()); + + var fragmentId = StoreObjectIdentifier.Table("Split"); + + Assert.Null(typeBuilder.Metadata.GetUseSqlOutputClauseConfigurationSource(fragmentId)); + + Assert.NotNull(typeBuilder.UseSqlOutputClause(true, fragmentId)); + Assert.True(typeBuilder.Metadata.IsSqlOutputClauseUsed(fragmentId)); + Assert.Equal(ConfigurationSource.Convention, typeBuilder.Metadata.GetUseSqlOutputClauseConfigurationSource(fragmentId)); + + Assert.NotNull(typeBuilder.UseSqlOutputClause(false, fragmentId, fromDataAnnotation: true)); + Assert.False(typeBuilder.Metadata.IsSqlOutputClauseUsed(fragmentId)); + Assert.Equal(ConfigurationSource.DataAnnotation, typeBuilder.Metadata.GetUseSqlOutputClauseConfigurationSource(fragmentId)); + + Assert.Null(typeBuilder.UseSqlOutputClause(true, fragmentId)); + Assert.False(typeBuilder.Metadata.IsSqlOutputClauseUsed(fragmentId)); + Assert.NotNull(typeBuilder.UseSqlOutputClause(false, fragmentId)); + + Assert.NotNull(typeBuilder.UseSqlOutputClause(null, fragmentId, fromDataAnnotation: true)); + Assert.True(typeBuilder.Metadata.IsSqlOutputClauseUsed(fragmentId)); + Assert.Null(typeBuilder.Metadata.GetUseSqlOutputClauseConfigurationSource(fragmentId)); + } + [ConditionalFact] public void Can_access_property() { diff --git a/test/EFCore.SqlServer.Tests/Metadata/SqlServerMetadataExtensionsTest.cs b/test/EFCore.SqlServer.Tests/Metadata/SqlServerMetadataExtensionsTest.cs index b49eb7fe9d6..9c8b921cbfb 100644 --- a/test/EFCore.SqlServer.Tests/Metadata/SqlServerMetadataExtensionsTest.cs +++ b/test/EFCore.SqlServer.Tests/Metadata/SqlServerMetadataExtensionsTest.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable InconsistentNaming + namespace Microsoft.EntityFrameworkCore.Metadata; public class SqlServerMetadataExtensionsTest diff --git a/test/EFCore.SqlServer.Tests/SqlServerNTSApiConsistencyTest.cs b/test/EFCore.SqlServer.Tests/SqlServerNTSApiConsistencyTest.cs index b303d7eba2b..b2051cdf50f 100644 --- a/test/EFCore.SqlServer.Tests/SqlServerNTSApiConsistencyTest.cs +++ b/test/EFCore.SqlServer.Tests/SqlServerNTSApiConsistencyTest.cs @@ -3,7 +3,8 @@ namespace Microsoft.EntityFrameworkCore; -public class SqlServerNTSApiConsistencyTest(SqlServerNTSApiConsistencyTest.SqlServerNTSApiConsistencyFixture fixture) : ApiConsistencyTestBase(fixture) +public class SqlServerNTSApiConsistencyTest(SqlServerNTSApiConsistencyTest.SqlServerNTSApiConsistencyFixture fixture) + : ApiConsistencyTestBase(fixture) { protected override void AddServices(ServiceCollection serviceCollection) => serviceCollection.AddEntityFrameworkSqlServerNetTopologySuite(); diff --git a/test/EFCore.SqlServer.Tests/SqlServerOptionsExtensionTest.cs b/test/EFCore.SqlServer.Tests/SqlServerOptionsExtensionTest.cs index 38db2102555..a1b01398a35 100644 --- a/test/EFCore.SqlServer.Tests/SqlServerOptionsExtensionTest.cs +++ b/test/EFCore.SqlServer.Tests/SqlServerOptionsExtensionTest.cs @@ -37,7 +37,8 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) } [DbContext(typeof(EmptyContext))] - private class EmptyContextModel(bool skipDetectChanges, Guid modelId, int entityTypeCount, int typeConfigurationCount) : RuntimeModel(skipDetectChanges, modelId, entityTypeCount, typeConfigurationCount) + private class EmptyContextModel(bool skipDetectChanges, Guid modelId, int entityTypeCount, int typeConfigurationCount) : RuntimeModel( + skipDetectChanges, modelId, entityTypeCount, typeConfigurationCount) { static EmptyContextModel() { diff --git a/test/EFCore.SqlServer.Tests/Storage/Internal/SqlServerDatabaseCreatorTest.cs b/test/EFCore.SqlServer.Tests/Storage/Internal/SqlServerDatabaseCreatorTest.cs index 62041c88486..d23d3357c50 100644 --- a/test/EFCore.SqlServer.Tests/Storage/Internal/SqlServerDatabaseCreatorTest.cs +++ b/test/EFCore.SqlServer.Tests/Storage/Internal/SqlServerDatabaseCreatorTest.cs @@ -121,7 +121,8 @@ private async Task Create_checks_for_existence_and_ultimately_gives_up_waiting_t } } - private class FakeSqlServerConnection(IDbContextOptions options, RelationalConnectionDependencies dependencies) : SqlServerConnection(dependencies) + private class FakeSqlServerConnection(IDbContextOptions options, RelationalConnectionDependencies dependencies) + : SqlServerConnection(dependencies) { private readonly IDbContextOptions _options = options; diff --git a/test/EFCore.SqlServer.Tests/Storage/SqlServerTypeMappingTest.cs b/test/EFCore.SqlServer.Tests/Storage/SqlServerTypeMappingTest.cs index bbbc3b9b33c..e7c0d89a840 100644 --- a/test/EFCore.SqlServer.Tests/Storage/SqlServerTypeMappingTest.cs +++ b/test/EFCore.SqlServer.Tests/Storage/SqlServerTypeMappingTest.cs @@ -385,7 +385,7 @@ public virtual void Char_Utf8() [ConditionalFact] public virtual void DateOnly_code_literal_generated_correctly() { - var typeMapping = new DateOnlyTypeMapping("date", DbType.Date); + var typeMapping = new DateOnlyTypeMapping("date"); Test_GenerateCodeLiteral_helper(typeMapping, new DateOnly(2020, 3, 5), "new DateOnly(2020, 3, 5)"); } @@ -393,7 +393,7 @@ public virtual void DateOnly_code_literal_generated_correctly() [ConditionalFact] public virtual void TimeOnly_code_literal_generated_correctly() { - var typeMapping = new TimeOnlyTypeMapping("time", DbType.Time); + var typeMapping = new TimeOnlyTypeMapping("time"); Test_GenerateCodeLiteral_helper(typeMapping, new TimeOnly(12, 30, 10), "new TimeOnly(12, 30, 10)"); Test_GenerateCodeLiteral_helper(typeMapping, new TimeOnly(12, 30, 10, 500), "new TimeOnly(12, 30, 10, 500)"); diff --git a/test/EFCore.SqlServer.Tests/Update/SqlServerModificationCommandBatchTest.cs b/test/EFCore.SqlServer.Tests/Update/SqlServerModificationCommandBatchTest.cs index ab4d6b65cb1..1eb35674bee 100644 --- a/test/EFCore.SqlServer.Tests/Update/SqlServerModificationCommandBatchTest.cs +++ b/test/EFCore.SqlServer.Tests/Update/SqlServerModificationCommandBatchTest.cs @@ -162,7 +162,8 @@ private static INonTrackedModificationCommand CreateModificationCommand( => new ModificationCommandFactory().CreateNonTrackedModificationCommand( new NonTrackedModificationCommandParameters(name, schema, sensitiveLoggingEnabled)); - private class TestSqlServerModificationCommandBatch(ModificationCommandBatchFactoryDependencies dependencies, int maxBatchSize) : SqlServerModificationCommandBatch(dependencies, maxBatchSize) + private class TestSqlServerModificationCommandBatch(ModificationCommandBatchFactoryDependencies dependencies, int maxBatchSize) + : SqlServerModificationCommandBatch(dependencies, maxBatchSize) { public new Dictionary ParameterValues => base.ParameterValues; diff --git a/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/ComplexTypeBulkUpdatesSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/ComplexTypeBulkUpdatesSqliteTest.cs index 8b6bccba5b5..295042e20aa 100644 --- a/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/ComplexTypeBulkUpdatesSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/ComplexTypeBulkUpdatesSqliteTest.cs @@ -5,7 +5,9 @@ namespace Microsoft.EntityFrameworkCore.BulkUpdates; #nullable disable -public class ComplexTypeBulkUpdatesSqliteTest(ComplexTypeBulkUpdatesSqliteTest.ComplexTypeBulkUpdatesSqliteFixture fixture, ITestOutputHelper testOutputHelper) : ComplexTypeBulkUpdatesRelationalTestBase< +public class ComplexTypeBulkUpdatesSqliteTest( + ComplexTypeBulkUpdatesSqliteTest.ComplexTypeBulkUpdatesSqliteFixture fixture, + ITestOutputHelper testOutputHelper) : ComplexTypeBulkUpdatesRelationalTestBase< ComplexTypeBulkUpdatesSqliteTest.ComplexTypeBulkUpdatesSqliteFixture>(fixture, testOutputHelper) { public class ComplexTypeBulkUpdatesSqliteFixture : ComplexTypeBulkUpdatesRelationalFixtureBase diff --git a/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesSqliteTest.cs index 52763b754ae..a34eee7dfb4 100644 --- a/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesSqliteTest.cs @@ -193,6 +193,35 @@ SELECT COALESCE(SUM("o0"."Amount"), 0) """); } + public override async Task Delete_with_view_mapping(bool async) + { + await base.Delete_with_view_mapping(async); + + AssertSql( + """ +DELETE FROM "Blogs" AS "b" +"""); + } + + public override async Task Update_with_view_mapping(bool async) + { + await base.Update_with_view_mapping(async); + + AssertSql( + """ +UPDATE "Blogs" AS "b" +SET "Data" = 'Updated' +"""); + } + + public override async Task Update_complex_type_with_view_mapping(bool async) + { + await base.Update_complex_type_with_view_mapping(async); + + // #34706 + AssertSql(); + } + protected override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) => base.AddOptions(builder).ConfigureWarnings(wcb => wcb.Log(SqliteEventId.CompositeKeyWithValueGeneration)); diff --git a/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqliteTest.cs index b9d24ca7352..e5a45786588 100644 --- a/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqliteTest.cs @@ -9,7 +9,8 @@ namespace Microsoft.EntityFrameworkCore.BulkUpdates; public class NorthwindBulkUpdatesSqliteTest( NorthwindBulkUpdatesSqliteFixture fixture, - ITestOutputHelper testOutputHelper) : NorthwindBulkUpdatesRelationalTestBase>(fixture, testOutputHelper) + ITestOutputHelper testOutputHelper) + : NorthwindBulkUpdatesRelationalTestBase>(fixture, testOutputHelper) { [ConditionalFact] public virtual void Check_all_tests_overridden() diff --git a/test/EFCore.Sqlite.FunctionalTests/CommandConfigurationTest.cs b/test/EFCore.Sqlite.FunctionalTests/CommandConfigurationTest.cs index 7681a983c78..227d1c99021 100644 --- a/test/EFCore.Sqlite.FunctionalTests/CommandConfigurationTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/CommandConfigurationTest.cs @@ -7,7 +7,8 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class CommandConfigurationTest(CommandConfigurationTest.CommandConfigurationTestFixture fixture) : IClassFixture +public class CommandConfigurationTest(CommandConfigurationTest.CommandConfigurationTestFixture fixture) + : IClassFixture { protected CommandConfigurationTestFixture Fixture { get; } = fixture; diff --git a/test/EFCore.Sqlite.FunctionalTests/CommandInterceptionSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/CommandInterceptionSqliteTest.cs index 469bd833856..cfe84dc7768 100644 --- a/test/EFCore.Sqlite.FunctionalTests/CommandInterceptionSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/CommandInterceptionSqliteTest.cs @@ -65,7 +65,8 @@ protected override bool ShouldSubscribeToDiagnosticListener } } - public class CommandInterceptionWithDiagnosticsSqliteTest(CommandInterceptionWithDiagnosticsSqliteTest.InterceptionSqliteFixture fixture) + public class CommandInterceptionWithDiagnosticsSqliteTest( + CommandInterceptionWithDiagnosticsSqliteTest.InterceptionSqliteFixture fixture) : CommandInterceptionSqliteTestBase(fixture), IClassFixture { public class InterceptionSqliteFixture : InterceptionSqliteFixtureBase diff --git a/test/EFCore.Sqlite.FunctionalTests/CompositeKeyEndToEndSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/CompositeKeyEndToEndSqliteTest.cs index 591408f5a0b..d7dc5a96e75 100644 --- a/test/EFCore.Sqlite.FunctionalTests/CompositeKeyEndToEndSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/CompositeKeyEndToEndSqliteTest.cs @@ -5,8 +5,9 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class CompositeKeyEndToEndSqliteTest(CompositeKeyEndToEndSqliteTest.CompositeKeyEndToEndSqliteFixture fixture) : CompositeKeyEndToEndTestBase< - CompositeKeyEndToEndSqliteTest.CompositeKeyEndToEndSqliteFixture>(fixture) +public class CompositeKeyEndToEndSqliteTest(CompositeKeyEndToEndSqliteTest.CompositeKeyEndToEndSqliteFixture fixture) + : CompositeKeyEndToEndTestBase< + CompositeKeyEndToEndSqliteTest.CompositeKeyEndToEndSqliteFixture>(fixture) { public override Task Can_use_generated_values_in_composite_key_end_to_end() // Not supported on Sqlite diff --git a/test/EFCore.Sqlite.FunctionalTests/ConcurrencyDetectorDisabledSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/ConcurrencyDetectorDisabledSqliteTest.cs index 38380c80aef..dc298c68ebc 100644 --- a/test/EFCore.Sqlite.FunctionalTests/ConcurrencyDetectorDisabledSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/ConcurrencyDetectorDisabledSqliteTest.cs @@ -5,8 +5,9 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class ConcurrencyDetectorDisabledSqliteTest(ConcurrencyDetectorDisabledSqliteTest.ConcurrencyDetectorSqlServerFixture fixture) : ConcurrencyDetectorDisabledRelationalTestBase< - ConcurrencyDetectorDisabledSqliteTest.ConcurrencyDetectorSqlServerFixture>(fixture) +public class ConcurrencyDetectorDisabledSqliteTest(ConcurrencyDetectorDisabledSqliteTest.ConcurrencyDetectorSqlServerFixture fixture) + : ConcurrencyDetectorDisabledRelationalTestBase< + ConcurrencyDetectorDisabledSqliteTest.ConcurrencyDetectorSqlServerFixture>(fixture) { public class ConcurrencyDetectorSqlServerFixture : ConcurrencyDetectorFixtureBase, ITestSqlLoggerFactory { diff --git a/test/EFCore.Sqlite.FunctionalTests/ConcurrencyDetectorEnabledSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/ConcurrencyDetectorEnabledSqliteTest.cs index 7adb84708c6..2a7ada241f5 100644 --- a/test/EFCore.Sqlite.FunctionalTests/ConcurrencyDetectorEnabledSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/ConcurrencyDetectorEnabledSqliteTest.cs @@ -5,8 +5,9 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class ConcurrencyDetectorEnabledSqliteTest(ConcurrencyDetectorEnabledSqliteTest.ConcurrencyDetectorSqlServerFixture fixture) : ConcurrencyDetectorEnabledRelationalTestBase< - ConcurrencyDetectorEnabledSqliteTest.ConcurrencyDetectorSqlServerFixture>(fixture) +public class ConcurrencyDetectorEnabledSqliteTest(ConcurrencyDetectorEnabledSqliteTest.ConcurrencyDetectorSqlServerFixture fixture) + : ConcurrencyDetectorEnabledRelationalTestBase< + ConcurrencyDetectorEnabledSqliteTest.ConcurrencyDetectorSqlServerFixture>(fixture) { public class ConcurrencyDetectorSqlServerFixture : ConcurrencyDetectorFixtureBase, ITestSqlLoggerFactory { diff --git a/test/EFCore.Sqlite.FunctionalTests/ConferencePlannerSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/ConferencePlannerSqliteTest.cs index 079ecd8b599..3623dd58059 100644 --- a/test/EFCore.Sqlite.FunctionalTests/ConferencePlannerSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/ConferencePlannerSqliteTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class ConferencePlannerSqliteTest(ConferencePlannerSqliteTest.ConferencePlannerSqliteFixture fixture) : ConferencePlannerTestBase(fixture) +public class ConferencePlannerSqliteTest(ConferencePlannerSqliteTest.ConferencePlannerSqliteFixture fixture) + : ConferencePlannerTestBase(fixture) { protected override void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction) => facade.UseTransaction(transaction.GetDbTransaction()); diff --git a/test/EFCore.Sqlite.FunctionalTests/ConnectionInterceptionSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/ConnectionInterceptionSqliteTest.cs index ebd1b655da4..8fd4ec35b46 100644 --- a/test/EFCore.Sqlite.FunctionalTests/ConnectionInterceptionSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/ConnectionInterceptionSqliteTest.cs @@ -36,8 +36,10 @@ protected override bool ShouldSubscribeToDiagnosticListener } } - public class ConnectionInterceptionWithDiagnosticsSqliteTest(ConnectionInterceptionWithDiagnosticsSqliteTest.InterceptionSqliteFixture fixture) - : ConnectionInterceptionSqliteTestBase(fixture), IClassFixture + public class ConnectionInterceptionWithDiagnosticsSqliteTest( + ConnectionInterceptionWithDiagnosticsSqliteTest.InterceptionSqliteFixture fixture) + : ConnectionInterceptionSqliteTestBase(fixture), + IClassFixture { public class InterceptionSqliteFixture : InterceptionSqliteFixtureBase { diff --git a/test/EFCore.Sqlite.FunctionalTests/CustomConvertersSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/CustomConvertersSqliteTest.cs index 7571112cd34..67fc5d67ed5 100644 --- a/test/EFCore.Sqlite.FunctionalTests/CustomConvertersSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/CustomConvertersSqliteTest.cs @@ -9,9 +9,7 @@ public class CustomConvertersSqliteTest : CustomConvertersTestBase Fixture.TestSqlLoggerFactory.Clear(); // Disabled: SQLite database is case-sensitive public override Task Can_insert_and_read_back_with_case_insensitive_string_key() diff --git a/test/EFCore.Sqlite.FunctionalTests/DefaultValuesTest.cs b/test/EFCore.Sqlite.FunctionalTests/DefaultValuesTest.cs index b3a26062753..71aaf7eed22 100644 --- a/test/EFCore.Sqlite.FunctionalTests/DefaultValuesTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/DefaultValuesTest.cs @@ -45,7 +45,6 @@ private ChipsContext CreateChipsContext() private class ChipsContext(DbContextOptions options) : PoolableDbContext(options) { - // ReSharper disable once UnusedAutoPropertyAccessor.Local public DbSet Chips { get; set; } diff --git a/test/EFCore.Sqlite.FunctionalTests/DesignTimeSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/DesignTimeSqliteTest.cs index bc15df48613..df3993b67aa 100644 --- a/test/EFCore.Sqlite.FunctionalTests/DesignTimeSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/DesignTimeSqliteTest.cs @@ -7,7 +7,8 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class DesignTimeSqliteTest(DesignTimeSqliteTest.DesignTimeSqliteFixture fixture) : DesignTimeTestBase(fixture) +public class DesignTimeSqliteTest(DesignTimeSqliteTest.DesignTimeSqliteFixture fixture) + : DesignTimeTestBase(fixture) { protected override Assembly ProviderAssembly => typeof(SqliteDesignTimeServices).Assembly; diff --git a/test/EFCore.Sqlite.FunctionalTests/EFCore.Sqlite.FunctionalTests.csproj b/test/EFCore.Sqlite.FunctionalTests/EFCore.Sqlite.FunctionalTests.csproj index 29007bec732..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/FieldMappingSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/FieldMappingSqliteTest.cs index ce025e6c948..d43df20a56c 100644 --- a/test/EFCore.Sqlite.FunctionalTests/FieldMappingSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/FieldMappingSqliteTest.cs @@ -61,7 +61,6 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con public class EnforcePropertyTest(EnforcePropertyTest.EnforcePropertyFixture fixture) : FieldMappingSqliteTestBase(fixture) { - // Cannot force property access when properties missing getter/setter public override void Simple_query_read_only_props(bool tracking) { diff --git a/test/EFCore.Sqlite.FunctionalTests/FieldsOnlyLoadSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/FieldsOnlyLoadSqliteTest.cs index 1f68ac91529..2f37fed9f75 100644 --- a/test/EFCore.Sqlite.FunctionalTests/FieldsOnlyLoadSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/FieldsOnlyLoadSqliteTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class FieldsOnlyLoadSqliteTest(FieldsOnlyLoadSqliteTest.FieldsOnlyLoadSqliteFixture fixture) : FieldsOnlyLoadTestBase(fixture) +public class FieldsOnlyLoadSqliteTest(FieldsOnlyLoadSqliteTest.FieldsOnlyLoadSqliteFixture fixture) + : FieldsOnlyLoadTestBase(fixture) { public class FieldsOnlyLoadSqliteFixture : FieldsOnlyLoadFixtureBase { diff --git a/test/EFCore.Sqlite.FunctionalTests/GraphUpdates/GraphUpdatesSqliteFullWithOriginalsNotificationsTest.cs b/test/EFCore.Sqlite.FunctionalTests/GraphUpdates/GraphUpdatesSqliteFullWithOriginalsNotificationsTest.cs index 0a6f54e48d3..bfbd3247120 100644 --- a/test/EFCore.Sqlite.FunctionalTests/GraphUpdates/GraphUpdatesSqliteFullWithOriginalsNotificationsTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/GraphUpdates/GraphUpdatesSqliteFullWithOriginalsNotificationsTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class GraphUpdatesSqliteFullWithOriginalsNotificationsTest(GraphUpdatesSqliteFullWithOriginalsNotificationsTest.SqliteFixture fixture) +public class GraphUpdatesSqliteFullWithOriginalsNotificationsTest( + GraphUpdatesSqliteFullWithOriginalsNotificationsTest.SqliteFixture fixture) : GraphUpdatesSqliteTestBase(fixture) { protected override void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction) diff --git a/test/EFCore.Sqlite.FunctionalTests/JsonTypesSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/JsonTypesSqliteTest.cs index f56b95dab49..b3c437accc4 100644 --- a/test/EFCore.Sqlite.FunctionalTests/JsonTypesSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/JsonTypesSqliteTest.cs @@ -6,7 +6,8 @@ namespace Microsoft.EntityFrameworkCore; public class JsonTypesSqliteTest : JsonTypesRelationalTestBase { public override Task Can_read_write_array_of_list_of_GUID_JSON_values(string expected) - => base.Can_read_write_array_of_list_of_GUID_JSON_values("""{"Prop":[["00000000-0000-0000-0000-000000000000","8C44242F-8E3F-4A20-8BE8-98C7C1AADEBD"],[],["FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF"]]}"""); + => base.Can_read_write_array_of_list_of_GUID_JSON_values( + """{"Prop":[["00000000-0000-0000-0000-000000000000","8C44242F-8E3F-4A20-8BE8-98C7C1AADEBD"],[],["FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF"]]}"""); public override Task Can_read_write_array_of_list_of_binary_JSON_values(string expected) => base.Can_read_write_array_of_list_of_binary_JSON_values("""{"Prop":[["000102","01","4D"],[],["4E"]]}"""); @@ -15,13 +16,16 @@ public override Task Can_read_write_list_of_array_of_binary_JSON_values(string e => base.Can_read_write_list_of_array_of_binary_JSON_values("""{"Prop":[["000102","01","4D"],[],["4E"]]}"""); public override Task Can_read_write_list_of_array_of_GUID_JSON_values(string expected) - => base.Can_read_write_list_of_array_of_GUID_JSON_values("""{"Prop":[["00000000-0000-0000-0000-000000000000","8C44242F-8E3F-4A20-8BE8-98C7C1AADEBD"],[],["FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF"]]}"""); + => base.Can_read_write_list_of_array_of_GUID_JSON_values( + """{"Prop":[["00000000-0000-0000-0000-000000000000","8C44242F-8E3F-4A20-8BE8-98C7C1AADEBD"],[],["FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF"]]}"""); public override Task Can_read_write_list_of_array_of_list_of_array_of_binary_JSON_values(string expected) - => base.Can_read_write_list_of_array_of_list_of_array_of_binary_JSON_values("""{"Prop":[[[["000102","01","4D"]],[],[[],[]]],[],[[[]],[["000102","01","4D"]]]]}"""); + => base.Can_read_write_list_of_array_of_list_of_array_of_binary_JSON_values( + """{"Prop":[[[["000102","01","4D"]],[],[[],[]]],[],[[[]],[["000102","01","4D"]]]]}"""); public override Task Can_read_write_list_of_array_of_nullable_GUID_JSON_values(string expected) - => base.Can_read_write_list_of_array_of_nullable_GUID_JSON_values("""{"Prop":[["00000000-0000-0000-0000-000000000000",null,"8C44242F-8E3F-4A20-8BE8-98C7C1AADEBD"],[],["FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF"]]}"""); + => base.Can_read_write_list_of_array_of_nullable_GUID_JSON_values( + """{"Prop":[["00000000-0000-0000-0000-000000000000",null,"8C44242F-8E3F-4A20-8BE8-98C7C1AADEBD"],[],["FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF"]]}"""); public override Task Can_read_write_binary_JSON_values(string value, string json) => base.Can_read_write_binary_JSON_values( @@ -35,25 +39,31 @@ public override Task Can_read_write_binary_JSON_values(string value, string json }); public override Task Can_read_write_collection_of_decimal_JSON_values(string expected) - => base.Can_read_write_collection_of_decimal_JSON_values("""{"Prop":["-79228162514264337593543950335.0","0.0","79228162514264337593543950335.0"]}"""); + => base.Can_read_write_collection_of_decimal_JSON_values( + """{"Prop":["-79228162514264337593543950335.0","0.0","79228162514264337593543950335.0"]}"""); public override Task Can_read_write_collection_of_DateTime_JSON_values(string expected) - => base.Can_read_write_collection_of_DateTime_JSON_values("""{"Prop":["0001-01-01 00:00:00","2023-05-29 10:52:47","9999-12-31 23:59:59.9999999"]}"""); + => base.Can_read_write_collection_of_DateTime_JSON_values( + """{"Prop":["0001-01-01 00:00:00","2023-05-29 10:52:47","9999-12-31 23:59:59.9999999"]}"""); public override Task Can_read_write_collection_of_DateTimeOffset_JSON_values(string expected) - => base.Can_read_write_collection_of_DateTimeOffset_JSON_values("""{"Prop":["0001-01-01 00:00:00+00:00","2023-05-29 10:52:47-02:00","2023-05-29 10:52:47+00:00","2023-05-29 10:52:47+02:00","9999-12-31 23:59:59.9999999+00:00"]}"""); + => base.Can_read_write_collection_of_DateTimeOffset_JSON_values( + """{"Prop":["0001-01-01 00:00:00+00:00","2023-05-29 10:52:47-02:00","2023-05-29 10:52:47+00:00","2023-05-29 10:52:47+02:00","9999-12-31 23:59:59.9999999+00:00"]}"""); public override Task Can_read_write_collection_of_GUID_JSON_values(string expected) - => base.Can_read_write_collection_of_GUID_JSON_values("""{"Prop":["00000000-0000-0000-0000-000000000000","8C44242F-8E3F-4A20-8BE8-98C7C1AADEBD","FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF"]}"""); + => base.Can_read_write_collection_of_GUID_JSON_values( + """{"Prop":["00000000-0000-0000-0000-000000000000","8C44242F-8E3F-4A20-8BE8-98C7C1AADEBD","FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF"]}"""); public override Task Can_read_write_collection_of_binary_JSON_values(string expected) => base.Can_read_write_collection_of_binary_JSON_values("""{"Prop":["00000001","FFFFFFFF","","01020304"]}"""); public override Task Can_read_write_collection_of_decimal_with_precision_and_scale_JSON_values(string expected) - => base.Can_read_write_collection_of_decimal_with_precision_and_scale_JSON_values("""{"Prop":["-79228162514264337593543950335.0","0.0","79228162514264337593543950335.0"]}"""); + => base.Can_read_write_collection_of_decimal_with_precision_and_scale_JSON_values( + """{"Prop":["-79228162514264337593543950335.0","0.0","79228162514264337593543950335.0"]}"""); public override Task Can_read_write_collection_of_Guid_converted_to_bytes_JSON_values(string expected) - => base.Can_read_write_collection_of_Guid_converted_to_bytes_JSON_values("""{"Prop":["00000000000000000000000000000000","2F24448C3F8E204A8BE898C7C1AADEBD","FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"]}"""); + => base.Can_read_write_collection_of_Guid_converted_to_bytes_JSON_values( + """{"Prop":["00000000000000000000000000000000","2F24448C3F8E204A8BE898C7C1AADEBD","FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"]}"""); public override Task Can_read_write_DateTime_JSON_values(string value, string json) => base.Can_read_write_DateTime_JSON_values( @@ -159,16 +169,20 @@ public override Task Can_read_write_collection_of_nullable_binary_JSON_values(st => base.Can_read_write_collection_of_nullable_binary_JSON_values("""{"Prop":["00000001",null,"FFFFFFFF","","01020304"]}"""); public override Task Can_read_write_collection_of_nullable_DateTime_JSON_values(string expected) - => base.Can_read_write_collection_of_nullable_DateTime_JSON_values("""{"Prop":["0001-01-01 00:00:00",null,"2023-05-29 10:52:47","9999-12-31 23:59:59.9999999"]}"""); + => base.Can_read_write_collection_of_nullable_DateTime_JSON_values( + """{"Prop":["0001-01-01 00:00:00",null,"2023-05-29 10:52:47","9999-12-31 23:59:59.9999999"]}"""); public override Task Can_read_write_collection_of_nullable_DateTimeOffset_JSON_values(string expected) - => base.Can_read_write_collection_of_nullable_DateTimeOffset_JSON_values("""{"Prop":["0001-01-01 00:00:00+00:00","2023-05-29 10:52:47-02:00","2023-05-29 10:52:47+00:00",null,"2023-05-29 10:52:47+02:00","9999-12-31 23:59:59.9999999+00:00"]}"""); + => base.Can_read_write_collection_of_nullable_DateTimeOffset_JSON_values( + """{"Prop":["0001-01-01 00:00:00+00:00","2023-05-29 10:52:47-02:00","2023-05-29 10:52:47+00:00",null,"2023-05-29 10:52:47+02:00","9999-12-31 23:59:59.9999999+00:00"]}"""); public override Task Can_read_write_collection_of_nullable_decimal_JSON_values(string expected) - => base.Can_read_write_collection_of_nullable_decimal_JSON_values("""{"Prop":["-79228162514264337593543950335.0","0.0",null,"79228162514264337593543950335.0"]}"""); + => base.Can_read_write_collection_of_nullable_decimal_JSON_values( + """{"Prop":["-79228162514264337593543950335.0","0.0",null,"79228162514264337593543950335.0"]}"""); public override Task Can_read_write_collection_of_nullable_GUID_JSON_values(string expected) - => base.Can_read_write_collection_of_nullable_GUID_JSON_values("""{"Prop":["00000000-0000-0000-0000-000000000000",null,"8C44242F-8E3F-4A20-8BE8-98C7C1AADEBD","FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF"]}"""); + => base.Can_read_write_collection_of_nullable_GUID_JSON_values( + """{"Prop":["00000000-0000-0000-0000-000000000000",null,"8C44242F-8E3F-4A20-8BE8-98C7C1AADEBD","FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF"]}"""); public override Task Can_read_write_ulong_enum_JSON_values(EnumU64 value, string json) => Can_read_and_write_JSON_value(nameof(EnumU64Type.EnumU64), value, json); diff --git a/test/EFCore.Sqlite.FunctionalTests/KeysWithConvertersSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/KeysWithConvertersSqliteTest.cs index b22846d1da8..2b77e1726ce 100644 --- a/test/EFCore.Sqlite.FunctionalTests/KeysWithConvertersSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/KeysWithConvertersSqliteTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class KeysWithConvertersSqliteTest(KeysWithConvertersSqliteTest.KeysWithConvertersSqliteFixture fixture) : KeysWithConvertersTestBase(fixture) +public class KeysWithConvertersSqliteTest(KeysWithConvertersSqliteTest.KeysWithConvertersSqliteFixture fixture) + : KeysWithConvertersTestBase(fixture) { public class KeysWithConvertersSqliteFixture : KeysWithConvertersFixtureBase { diff --git a/test/EFCore.Sqlite.FunctionalTests/LazyLoadProxySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/LazyLoadProxySqliteTest.cs index 01fbd506d96..99d375a0cf5 100644 --- a/test/EFCore.Sqlite.FunctionalTests/LazyLoadProxySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/LazyLoadProxySqliteTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class LazyLoadProxySqliteTest(LazyLoadProxySqliteTest.LoadSqliteFixture fixture) : LazyLoadProxyTestBase(fixture) +public class LazyLoadProxySqliteTest(LazyLoadProxySqliteTest.LoadSqliteFixture fixture) + : LazyLoadProxyTestBase(fixture) { [ConditionalFact] public void IsLoaded_is_not_set_if_loading_principal_collection_fails() diff --git a/test/EFCore.Sqlite.FunctionalTests/Migrations/MigrationsInfrastructureSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Migrations/MigrationsInfrastructureSqliteTest.cs index 26799421608..44df35292fe 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Migrations/MigrationsInfrastructureSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Migrations/MigrationsInfrastructureSqliteTest.cs @@ -1,12 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable disable + using Identity30.Data; using Microsoft.EntityFrameworkCore.TestModels.AspNetIdentity; using ModelSnapshot22; -#nullable disable - namespace Microsoft.EntityFrameworkCore.Migrations { public class MigrationsInfrastructureSqliteTest(MigrationsInfrastructureSqliteTest.MigrationsInfrastructureSqliteFixture fixture) diff --git a/test/EFCore.Sqlite.FunctionalTests/Migrations/MigrationsSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Migrations/MigrationsSqliteTest.cs index ce333c2edef..79529ed9b1d 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Migrations/MigrationsSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Migrations/MigrationsSqliteTest.cs @@ -1102,16 +1102,16 @@ public override async Task Convert_json_entities_to_regular_owned() { await base.Convert_json_entities_to_regular_owned(); -AssertSql( + AssertSql( """ ALTER TABLE "Entity" RENAME COLUMN "OwnedReference" TO "OwnedReference_Date"; """, - // - """ + // + """ ALTER TABLE "Entity" ADD "OwnedReference_NestedReference_Number" INTEGER NULL; """, - // - """ + // + """ CREATE TABLE "Entity_NestedCollection" ( "OwnedEntityId" INTEGER NOT NULL, "Id" INTEGER NOT NULL, @@ -1120,8 +1120,8 @@ public override async Task Convert_json_entities_to_regular_owned() CONSTRAINT "FK_Entity_NestedCollection_Entity_OwnedEntityId" FOREIGN KEY ("OwnedEntityId") REFERENCES "Entity" ("Id") ON DELETE CASCADE ); """, - // - """ + // + """ CREATE TABLE "Entity_OwnedCollection" ( "EntityId" INTEGER NOT NULL, "Id" INTEGER NOT NULL, @@ -1131,8 +1131,8 @@ public override async Task Convert_json_entities_to_regular_owned() CONSTRAINT "FK_Entity_OwnedCollection_Entity_EntityId" FOREIGN KEY ("EntityId") REFERENCES "Entity" ("Id") ON DELETE CASCADE ); """, - // - """ + // + """ CREATE TABLE "Entity_OwnedCollection_NestedCollection2" ( "Owned2EntityId" INTEGER NOT NULL, "Owned2Id" INTEGER NOT NULL, @@ -1142,8 +1142,8 @@ public override async Task Convert_json_entities_to_regular_owned() CONSTRAINT "FK_Entity_OwnedCollection_NestedCollection2_Entity_OwnedCollection_Owned2EntityId_Owned2Id" FOREIGN KEY ("Owned2EntityId", "Owned2Id") REFERENCES "Entity_OwnedCollection" ("EntityId", "Id") ON DELETE CASCADE ); """, - // - """ + // + """ CREATE TABLE "ef_temp_Entity" ( "Id" INTEGER NOT NULL CONSTRAINT "PK_Entity" PRIMARY KEY AUTOINCREMENT, "Name" TEXT NULL, @@ -1151,26 +1151,26 @@ public override async Task Convert_json_entities_to_regular_owned() "OwnedReference_NestedReference_Number" INTEGER NULL ); """, - // - """ + // + """ INSERT INTO "ef_temp_Entity" ("Id", "Name", "OwnedReference_Date", "OwnedReference_NestedReference_Number") SELECT "Id", "Name", "OwnedReference_Date", "OwnedReference_NestedReference_Number" FROM "Entity"; """, - // - """ + // + """ PRAGMA foreign_keys = 0; """, - // - """ + // + """ DROP TABLE "Entity"; """, - // - """ + // + """ ALTER TABLE "ef_temp_Entity" RENAME TO "Entity"; """, - // - """ + // + """ PRAGMA foreign_keys = 1; """); } @@ -2027,7 +2027,7 @@ public override async Task Create_table_with_complex_type_with_required_properti await base.Create_table_with_complex_type_with_required_properties_on_derived_entity_in_TPH(); AssertSql( -""" + """ CREATE TABLE "Contacts" ( "Id" INTEGER NOT NULL CONSTRAINT "PK_Contacts" PRIMARY KEY AUTOINCREMENT, "Discriminator" TEXT NOT NULL, @@ -2076,7 +2076,7 @@ public override async Task Add_required_primitve_collection_to_existing_table() await base.Add_required_primitve_collection_to_existing_table(); AssertSql( -""" + """ ALTER TABLE "Customers" ADD "Numbers" TEXT NOT NULL DEFAULT '[]'; """); } @@ -2087,7 +2087,7 @@ public override async Task Add_required_primitve_collection_with_custom_default_ await base.Add_required_primitve_collection_with_custom_default_value_to_existing_table(); AssertSql( -""" + """ ALTER TABLE "Customers" ADD "Numbers" TEXT NOT NULL DEFAULT '[1,2,3]'; """); } @@ -2098,7 +2098,7 @@ public override async Task Add_required_primitve_collection_with_custom_default_ await base.Add_required_primitve_collection_with_custom_default_value_sql_to_existing_table_core("'[3, 2, 1]'"); AssertSql( -""" + """ ALTER TABLE "Customers" ADD "Numbers" TEXT NOT NULL DEFAULT ('[3, 2, 1]'); """); } @@ -2109,7 +2109,7 @@ public override async Task Add_required_primitve_collection_with_custom_converte await base.Add_required_primitve_collection_with_custom_converter_to_existing_table(); AssertSql( -""" + """ ALTER TABLE [Customers] ADD [Numbers] nvarchar(max) NOT NULL DEFAULT N'nothing'; """); } @@ -2120,7 +2120,7 @@ public override async Task Add_required_primitve_collection_with_custom_converte await base.Add_required_primitve_collection_with_custom_converter_and_custom_default_value_to_existing_table(); AssertSql( -""" + """ ALTER TABLE "Customers" ADD "Numbers" TEXT NOT NULL DEFAULT 'some numbers'; """); } @@ -2131,7 +2131,7 @@ public override async Task Add_required_primitive_collection_to_existing_table() await base.Add_required_primitive_collection_to_existing_table(); AssertSql( -""" + """ ALTER TABLE "Customers" ADD "Numbers" TEXT NOT NULL DEFAULT '[]'; """); } @@ -2142,7 +2142,7 @@ public override async Task Add_required_primitive_collection_with_custom_default await base.Add_required_primitive_collection_with_custom_default_value_to_existing_table(); AssertSql( -""" + """ ALTER TABLE "Customers" ADD "Numbers" TEXT NOT NULL DEFAULT '[1,2,3]'; """); } @@ -2153,7 +2153,7 @@ public override async Task Add_required_primitive_collection_with_custom_default await base.Add_required_primitive_collection_with_custom_default_value_sql_to_existing_table_core("'[3, 2, 1]'"); AssertSql( -""" + """ ALTER TABLE "Customers" ADD "Numbers" TEXT NOT NULL DEFAULT ('[3, 2, 1]'); """); } @@ -2164,7 +2164,7 @@ public override async Task Add_required_primitive_collection_with_custom_convert await base.Add_required_primitive_collection_with_custom_converter_to_existing_table(); AssertSql( -""" + """ ALTER TABLE [Customers] ADD [Numbers] nvarchar(max) NOT NULL DEFAULT N'nothing'; """); } @@ -2175,7 +2175,7 @@ public override async Task Add_required_primitive_collection_with_custom_convert await base.Add_required_primitive_collection_with_custom_converter_and_custom_default_value_to_existing_table(); AssertSql( -""" + """ ALTER TABLE "Customers" ADD "Numbers" TEXT NOT NULL DEFAULT 'some numbers'; """); } @@ -2186,7 +2186,7 @@ public override async Task Add_optional_primitive_collection_to_existing_table() await base.Add_optional_primitive_collection_to_existing_table(); AssertSql( -""" + """ ALTER TABLE "Customers" ADD "Numbers" TEXT NULL; """); } @@ -2197,7 +2197,7 @@ public override async Task Create_table_with_required_primitive_collection() await base.Create_table_with_required_primitive_collection(); AssertSql( -""" + """ CREATE TABLE "Customers" ( "Id" INTEGER NOT NULL CONSTRAINT "PK_Customers" PRIMARY KEY AUTOINCREMENT, "Name" TEXT NULL, @@ -2212,7 +2212,7 @@ public override async Task Create_table_with_optional_primitive_collection() await base.Create_table_with_optional_primitive_collection(); AssertSql( -""" + """ CREATE TABLE "Customers" ( "Id" INTEGER NOT NULL CONSTRAINT "PK_Customers" PRIMARY KEY AUTOINCREMENT, "Name" TEXT NULL, diff --git a/test/EFCore.Sqlite.FunctionalTests/ModelBuilding/SqliteModelBuilderGenericTest.cs b/test/EFCore.Sqlite.FunctionalTests/ModelBuilding/SqliteModelBuilderGenericTest.cs index d81996228cc..aeb872eefff 100644 --- a/test/EFCore.Sqlite.FunctionalTests/ModelBuilding/SqliteModelBuilderGenericTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/ModelBuilding/SqliteModelBuilderGenericTest.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // ReSharper disable InconsistentNaming + namespace Microsoft.EntityFrameworkCore.ModelBuilding; public class SqliteModelBuilderGenericTest : SqliteModelBuilderTestBase diff --git a/test/EFCore.Sqlite.FunctionalTests/ModelBuilding/SqliteModelBuilderTestBase.cs b/test/EFCore.Sqlite.FunctionalTests/ModelBuilding/SqliteModelBuilderTestBase.cs index 713c830c9eb..475f5d5a660 100644 --- a/test/EFCore.Sqlite.FunctionalTests/ModelBuilding/SqliteModelBuilderTestBase.cs +++ b/test/EFCore.Sqlite.FunctionalTests/ModelBuilding/SqliteModelBuilderTestBase.cs @@ -1,36 +1,45 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Sqlite.Internal; namespace Microsoft.EntityFrameworkCore.ModelBuilding; public class SqliteModelBuilderTestBase : RelationalModelBuilderTest { - public abstract class SqliteNonRelationship(SqliteModelBuilderFixture fixture) : RelationalNonRelationshipTestBase(fixture), IClassFixture; + public abstract class SqliteNonRelationship(SqliteModelBuilderFixture fixture) + : RelationalNonRelationshipTestBase(fixture), IClassFixture; - public abstract class SqliteComplexType(SqliteModelBuilderFixture fixture) : RelationalComplexTypeTestBase(fixture), IClassFixture; + public abstract class SqliteComplexType(SqliteModelBuilderFixture fixture) + : RelationalComplexTypeTestBase(fixture), IClassFixture; - public abstract class SqliteInheritance(SqliteModelBuilderFixture fixture) : RelationalInheritanceTestBase(fixture), IClassFixture; + public abstract class SqliteInheritance(SqliteModelBuilderFixture fixture) + : RelationalInheritanceTestBase(fixture), IClassFixture; - public abstract class SqliteOneToMany(SqliteModelBuilderFixture fixture) : RelationalOneToManyTestBase(fixture), IClassFixture; + public abstract class SqliteOneToMany(SqliteModelBuilderFixture fixture) + : RelationalOneToManyTestBase(fixture), IClassFixture; - public abstract class SqliteManyToOne(SqliteModelBuilderFixture fixture) : RelationalManyToOneTestBase(fixture), IClassFixture; + public abstract class SqliteManyToOne(SqliteModelBuilderFixture fixture) + : RelationalManyToOneTestBase(fixture), IClassFixture; - public abstract class SqliteOneToOne(SqliteModelBuilderFixture fixture) : RelationalOneToOneTestBase(fixture), IClassFixture; + public abstract class SqliteOneToOne(SqliteModelBuilderFixture fixture) + : RelationalOneToOneTestBase(fixture), IClassFixture; - public abstract class SqliteManyToMany(SqliteModelBuilderFixture fixture) : RelationalManyToManyTestBase(fixture), IClassFixture; + public abstract class SqliteManyToMany(SqliteModelBuilderFixture fixture) + : RelationalManyToManyTestBase(fixture), IClassFixture; - public abstract class SqliteOwnedTypes(SqliteModelBuilderFixture fixture) : RelationalOwnedTypesTestBase(fixture), IClassFixture + public abstract class SqliteOwnedTypes(SqliteModelBuilderFixture fixture) + : RelationalOwnedTypesTestBase(fixture), IClassFixture { public override void Can_use_sproc_mapping_with_owned_reference() - => Assert.Equal(SqliteStrings.StoredProceduresNotSupported("Book.Label#BookLabel"), + => Assert.Equal( + SqliteStrings.StoredProceduresNotSupported("Book.Label#BookLabel"), Assert.Throws(base.Can_use_sproc_mapping_with_owned_reference).Message); } public class SqliteModelBuilderFixture : RelationalModelBuilderFixture { - public override TestHelpers TestHelpers => SqliteTestHelpers.Instance; + public override TestHelpers TestHelpers + => SqliteTestHelpers.Instance; } } diff --git a/test/EFCore.Sqlite.FunctionalTests/MonsterFixupChangedOnlySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/MonsterFixupChangedOnlySqliteTest.cs index 0e2cfd05894..856a6f6db95 100644 --- a/test/EFCore.Sqlite.FunctionalTests/MonsterFixupChangedOnlySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/MonsterFixupChangedOnlySqliteTest.cs @@ -5,8 +5,9 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class MonsterFixupChangedOnlySqliteTest(MonsterFixupChangedOnlySqliteTest.MonsterFixupChangedOnlySqliteFixture fixture) : MonsterFixupTestBase< - MonsterFixupChangedOnlySqliteTest.MonsterFixupChangedOnlySqliteFixture>(fixture) +public class MonsterFixupChangedOnlySqliteTest(MonsterFixupChangedOnlySqliteTest.MonsterFixupChangedOnlySqliteFixture fixture) + : MonsterFixupTestBase< + MonsterFixupChangedOnlySqliteTest.MonsterFixupChangedOnlySqliteFixture>(fixture) { public class MonsterFixupChangedOnlySqliteFixture : MonsterFixupChangedOnlyFixtureBase { diff --git a/test/EFCore.Sqlite.FunctionalTests/MusicStoreSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/MusicStoreSqliteTest.cs index 06e703e2225..10dc7a646d8 100644 --- a/test/EFCore.Sqlite.FunctionalTests/MusicStoreSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/MusicStoreSqliteTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class MusicStoreSqliteTest(MusicStoreSqliteTest.MusicStoreSqliteFixture fixture) : MusicStoreTestBase(fixture) +public class MusicStoreSqliteTest(MusicStoreSqliteTest.MusicStoreSqliteFixture fixture) + : MusicStoreTestBase(fixture) { public class MusicStoreSqliteFixture : MusicStoreFixtureBase { diff --git a/test/EFCore.Sqlite.FunctionalTests/NonLoadingNavigationsManyToManyLoadSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/NonLoadingNavigationsManyToManyLoadSqliteTest.cs index 30780b3b29d..382ee1ce39e 100644 --- a/test/EFCore.Sqlite.FunctionalTests/NonLoadingNavigationsManyToManyLoadSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/NonLoadingNavigationsManyToManyLoadSqliteTest.cs @@ -7,7 +7,8 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class NonLoadingNavigationsManyToManyLoadSqliteTest(NonLoadingNavigationsManyToManyLoadSqliteTest.NonLoadingNavigationsManyToManyLoadSqliteFixture fixture) +public class NonLoadingNavigationsManyToManyLoadSqliteTest( + NonLoadingNavigationsManyToManyLoadSqliteTest.NonLoadingNavigationsManyToManyLoadSqliteFixture fixture) : ManyToManyLoadTestBase(fixture) { public class NonLoadingNavigationsManyToManyLoadSqliteFixture : ManyToManyLoadFixtureBase, ITestSqlLoggerFactory diff --git a/test/EFCore.Sqlite.FunctionalTests/NotificationEntitiesSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/NotificationEntitiesSqliteTest.cs index 1dea0ea8f39..b07ccf6367c 100644 --- a/test/EFCore.Sqlite.FunctionalTests/NotificationEntitiesSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/NotificationEntitiesSqliteTest.cs @@ -5,8 +5,9 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class NotificationEntitiesSqliteTest(NotificationEntitiesSqliteTest.NotificationEntitiesSqliteFixture fixture) : NotificationEntitiesTestBase< - NotificationEntitiesSqliteTest.NotificationEntitiesSqliteFixture>(fixture) +public class NotificationEntitiesSqliteTest(NotificationEntitiesSqliteTest.NotificationEntitiesSqliteFixture fixture) + : NotificationEntitiesTestBase< + NotificationEntitiesSqliteTest.NotificationEntitiesSqliteFixture>(fixture) { public class NotificationEntitiesSqliteFixture : NotificationEntitiesFixtureBase { diff --git a/test/EFCore.Sqlite.FunctionalTests/OptimisticConcurrencySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/OptimisticConcurrencySqliteTest.cs index eb39c58ea50..2631e9d0440 100644 --- a/test/EFCore.Sqlite.FunctionalTests/OptimisticConcurrencySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/OptimisticConcurrencySqliteTest.cs @@ -5,9 +5,11 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class OptimisticConcurrencyULongSqliteTest(F1ULongSqliteFixture fixture) : OptimisticConcurrencySqliteTestBase(fixture); +public class OptimisticConcurrencyULongSqliteTest(F1ULongSqliteFixture fixture) + : OptimisticConcurrencySqliteTestBase(fixture); -public class OptimisticConcurrencySqliteTest(F1SqliteFixture fixture) : OptimisticConcurrencySqliteTestBase(fixture); +public class OptimisticConcurrencySqliteTest(F1SqliteFixture fixture) + : OptimisticConcurrencySqliteTestBase(fixture); public abstract class OptimisticConcurrencySqliteTestBase(TFixture fixture) : OptimisticConcurrencyRelationalTestBase(fixture) diff --git a/test/EFCore.Sqlite.FunctionalTests/PropertyValuesSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/PropertyValuesSqliteTest.cs index c70c8064c0a..5c6f1a03ce8 100644 --- a/test/EFCore.Sqlite.FunctionalTests/PropertyValuesSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/PropertyValuesSqliteTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class PropertyValuesSqliteTest(PropertyValuesSqliteTest.PropertyValuesSqliteFixture fixture) : PropertyValuesTestBase(fixture) +public class PropertyValuesSqliteTest(PropertyValuesSqliteTest.PropertyValuesSqliteFixture fixture) + : PropertyValuesTestBase(fixture) { public class PropertyValuesSqliteFixture : PropertyValuesFixtureBase { diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/AdHocJsonQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/AdHocJsonQuerySqliteTest.cs index fcc06b5f823..c0e0a9b94a4 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/AdHocJsonQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/AdHocJsonQuerySqliteTest.cs @@ -10,7 +10,7 @@ public class AdHocJsonQuerySqliteTest : AdHocJsonQueryTestBase protected override ITestStoreFactory TestStoreFactory => SqliteTestStoreFactory.Instance; - protected override async Task Seed29219(MyContext29219 ctx) + protected override async Task Seed29219(DbContext ctx) { var entity1 = new MyEntity29219 { @@ -18,9 +18,9 @@ protected override async Task Seed29219(MyContext29219 ctx) Reference = new MyJsonEntity29219 { NonNullableScalar = 10, NullableScalar = 11 }, Collection = [ - new() { NonNullableScalar = 100, NullableScalar = 101 }, - new() { NonNullableScalar = 200, NullableScalar = 201 }, - new() { NonNullableScalar = 300, NullableScalar = null } + new MyJsonEntity29219 { NonNullableScalar = 100, NullableScalar = 101 }, + new MyJsonEntity29219 { NonNullableScalar = 200, NullableScalar = 201 }, + new MyJsonEntity29219 { NonNullableScalar = 300, NullableScalar = null } ] }; @@ -28,10 +28,10 @@ protected override async Task Seed29219(MyContext29219 ctx) { Id = 2, Reference = new MyJsonEntity29219 { NonNullableScalar = 20, NullableScalar = null }, - Collection = [new() { NonNullableScalar = 1001, NullableScalar = null }] + Collection = [new MyJsonEntity29219 { NonNullableScalar = 1001, NullableScalar = null }] }; - ctx.Entities.AddRange(entity1, entity2); + ctx.Set().AddRange(entity1, entity2); await ctx.SaveChangesAsync(); await ctx.Database.ExecuteSqlAsync( @@ -41,7 +41,7 @@ await ctx.Database.ExecuteSqlAsync( """); } - protected override async Task Seed30028(MyContext30028 ctx) + protected override async Task Seed30028(DbContext ctx) { // complete await ctx.Database.ExecuteSqlAsync( @@ -80,14 +80,14 @@ await ctx.Database.ExecuteSqlAsync( """); } - protected override async Task Seed33046(Context33046 ctx) + protected override async Task Seed33046(DbContext ctx) => await ctx.Database.ExecuteSqlAsync( $$""" INSERT INTO "Reviews" ("Rounds", "Id") VALUES('[{"RoundNumber":11,"SubRounds":[{"SubRoundNumber":111},{"SubRoundNumber":112}]}]', 1) """); - protected override Task SeedArrayOfPrimitives(MyContextArrayOfPrimitives ctx) + protected override Task SeedArrayOfPrimitives(DbContext ctx) { var entity1 = new MyEntityArrayOfPrimitives { @@ -104,8 +104,8 @@ protected override Task SeedArrayOfPrimitives(MyContextArrayOfPrimitives ctx) }, Collection = [ - new() { IntArray = [111, 112, 113], ListOfString = ["Foo11", "Bar11"] }, - new() { IntArray = [211, 212, 213], ListOfString = ["Foo12", "Bar12"] } + new MyJsonEntityArrayOfPrimitives { IntArray = [111, 112, 113], ListOfString = ["Foo11", "Bar11"] }, + new MyJsonEntityArrayOfPrimitives { IntArray = [211, 212, 213], ListOfString = ["Foo12", "Bar12"] } ] }; @@ -124,16 +124,16 @@ protected override Task SeedArrayOfPrimitives(MyContextArrayOfPrimitives ctx) }, Collection = [ - new() { IntArray = [110, 120, 130], ListOfString = ["A1", "Z1"] }, - new() { IntArray = [210, 220, 230], ListOfString = ["A2", "Z2"] } + new MyJsonEntityArrayOfPrimitives { IntArray = [110, 120, 130], ListOfString = ["A1", "Z1"] }, + new MyJsonEntityArrayOfPrimitives { IntArray = [210, 220, 230], ListOfString = ["A2", "Z2"] } ] }; - ctx.Entities.AddRange(entity1, entity2); + ctx.Set().AddRange(entity1, entity2); return ctx.SaveChangesAsync(); } - protected override Task SeedJunkInJson(MyContextJunkInJson ctx) + protected override Task SeedJunkInJson(DbContext ctx) => ctx.Database.ExecuteSqlAsync( $$$""" INSERT INTO "Entities" ("Collection", "CollectionWithCtor", "Reference", "ReferenceWithCtor", "Id") @@ -145,7 +145,7 @@ protected override Task SeedJunkInJson(MyContextJunkInJson ctx) 1) """); - protected override Task SeedTrickyBuffering(MyContextTrickyBuffering ctx) + protected override Task SeedTrickyBuffering(DbContext ctx) => ctx.Database.ExecuteSqlAsync( $$$""" INSERT INTO "Entities" ("Reference", "Id") @@ -153,7 +153,7 @@ protected override Task SeedTrickyBuffering(MyContextTrickyBuffering ctx) '{"Name": "r1", "Number": 7, "JunkReference":{"Something": "SomeValue" }, "JunkCollection": [{"Foo": "junk value"}], "NestedReference": {"DoB": "2000-01-01T00:00:00"}, "NestedCollection": [{"DoB": "2000-02-01T00:00:00", "JunkReference": {"Something": "SomeValue"}}, {"DoB": "2000-02-02T00:00:00"}]}',1) """); - protected override Task SeedShadowProperties(MyContextShadowProperties ctx) + protected override Task SeedShadowProperties(DbContext ctx) => ctx.Database.ExecuteSqlAsync( $$""" INSERT INTO "Entities" ("Collection", "CollectionWithCtor", "Reference", "ReferenceWithCtor", "Id", "Name") @@ -166,7 +166,7 @@ protected override Task SeedShadowProperties(MyContextShadowProperties ctx) 'e1') """); - protected override async Task SeedNotICollection(MyContextNotICollection ctx) + protected override async Task SeedNotICollection(DbContext ctx) { await ctx.Database.ExecuteSqlAsync( $$""" diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/AdHocMiscellaneousQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/AdHocMiscellaneousQuerySqliteTest.cs index 7d49ffdfb98..2fa464a2554 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/AdHocMiscellaneousQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/AdHocMiscellaneousQuerySqliteTest.cs @@ -1,8 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.EntityFrameworkCore.Sqlite.Internal; - namespace Microsoft.EntityFrameworkCore.Query; #nullable disable diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/AdHocQuerySplittingQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/AdHocQuerySplittingQuerySqliteTest.cs index 1f9a25e56dd..0889d679be4 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/AdHocQuerySplittingQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/AdHocQuerySplittingQuerySqliteTest.cs @@ -15,7 +15,9 @@ protected override ITestStoreFactory TestStoreFactory private static readonly FieldInfo _querySplittingBehaviorFieldInfo = typeof(RelationalOptionsExtension).GetField("_querySplittingBehavior", BindingFlags.NonPublic | BindingFlags.Instance); - protected override DbContextOptionsBuilder SetQuerySplittingBehavior(DbContextOptionsBuilder optionsBuilder, QuerySplittingBehavior splittingBehavior) + protected override DbContextOptionsBuilder SetQuerySplittingBehavior( + DbContextOptionsBuilder optionsBuilder, + QuerySplittingBehavior splittingBehavior) { new SqliteDbContextOptionsBuilder(optionsBuilder).UseQuerySplittingBehavior(splittingBehavior); diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/ComplexNavigationsQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/ComplexNavigationsQuerySqliteTest.cs index 5b2879e3b16..36810f7a589 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/ComplexNavigationsQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/ComplexNavigationsQuerySqliteTest.cs @@ -7,7 +7,8 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class ComplexNavigationsQuerySqliteTest(ComplexNavigationsQuerySqliteFixture fixture) : ComplexNavigationsQueryRelationalTestBase(fixture) +public class ComplexNavigationsQuerySqliteTest(ComplexNavigationsQuerySqliteFixture fixture) + : ComplexNavigationsQueryRelationalTestBase(fixture) { public override async Task Let_let_contains_from_outer_let(bool async) => Assert.Equal( diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/ComplexTypeQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/ComplexTypeQuerySqliteTest.cs index 066a3f2f22b..9a294ed5787 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/ComplexTypeQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/ComplexTypeQuerySqliteTest.cs @@ -481,7 +481,8 @@ public override async Task Filter_on_required_property_inside_required_struct_co // purpose of knowing that it's there. public override async Task Project_struct_complex_type_via_optional_navigation(bool async) { - var exception = await Assert.ThrowsAsync(() => base.Project_struct_complex_type_via_optional_navigation(async)); + var exception = + await Assert.ThrowsAsync(() => base.Project_struct_complex_type_via_optional_navigation(async)); Assert.Equal(RelationalStrings.CannotProjectNullableComplexType("ValuedCustomer.ShippingAddress#AddressStruct"), exception.Message); } @@ -751,7 +752,7 @@ public override async Task Project_same_entity_with_nested_complex_type_twice_wi await base.Project_same_entity_with_nested_complex_type_twice_with_pushdown(async); AssertSql( -""" + """ SELECT "s"."Id", "s"."Name", "s"."BillingAddress_AddressLine1", "s"."BillingAddress_AddressLine2", "s"."BillingAddress_Tags", "s"."BillingAddress_ZipCode", "s"."BillingAddress_Country_Code", "s"."BillingAddress_Country_FullName", "s"."ShippingAddress_AddressLine1", "s"."ShippingAddress_AddressLine2", "s"."ShippingAddress_Tags", "s"."ShippingAddress_ZipCode", "s"."ShippingAddress_Country_Code", "s"."ShippingAddress_Country_FullName", "s"."Id0", "s"."Name0", "s"."BillingAddress_AddressLine10", "s"."BillingAddress_AddressLine20", "s"."BillingAddress_Tags0", "s"."BillingAddress_ZipCode0", "s"."BillingAddress_Country_Code0", "s"."BillingAddress_Country_FullName0", "s"."ShippingAddress_AddressLine10", "s"."ShippingAddress_AddressLine20", "s"."ShippingAddress_Tags0", "s"."ShippingAddress_ZipCode0", "s"."ShippingAddress_Country_Code0", "s"."ShippingAddress_Country_FullName0" FROM ( SELECT DISTINCT "c"."Id", "c"."Name", "c"."BillingAddress_AddressLine1", "c"."BillingAddress_AddressLine2", "c"."BillingAddress_Tags", "c"."BillingAddress_ZipCode", "c"."BillingAddress_Country_Code", "c"."BillingAddress_Country_FullName", "c"."ShippingAddress_AddressLine1", "c"."ShippingAddress_AddressLine2", "c"."ShippingAddress_Tags", "c"."ShippingAddress_ZipCode", "c"."ShippingAddress_Country_Code", "c"."ShippingAddress_Country_FullName", "c0"."Id" AS "Id0", "c0"."Name" AS "Name0", "c0"."BillingAddress_AddressLine1" AS "BillingAddress_AddressLine10", "c0"."BillingAddress_AddressLine2" AS "BillingAddress_AddressLine20", "c0"."BillingAddress_Tags" AS "BillingAddress_Tags0", "c0"."BillingAddress_ZipCode" AS "BillingAddress_ZipCode0", "c0"."BillingAddress_Country_Code" AS "BillingAddress_Country_Code0", "c0"."BillingAddress_Country_FullName" AS "BillingAddress_Country_FullName0", "c0"."ShippingAddress_AddressLine1" AS "ShippingAddress_AddressLine10", "c0"."ShippingAddress_AddressLine2" AS "ShippingAddress_AddressLine20", "c0"."ShippingAddress_Tags" AS "ShippingAddress_Tags0", "c0"."ShippingAddress_ZipCode" AS "ShippingAddress_ZipCode0", "c0"."ShippingAddress_Country_Code" AS "ShippingAddress_Country_Code0", "c0"."ShippingAddress_Country_FullName" AS "ShippingAddress_Country_FullName0" @@ -766,7 +767,7 @@ public override async Task Project_same_nested_complex_type_twice_with_pushdown( await base.Project_same_nested_complex_type_twice_with_pushdown(async); AssertSql( -""" + """ SELECT "s"."BillingAddress_AddressLine1", "s"."BillingAddress_AddressLine2", "s"."BillingAddress_Tags", "s"."BillingAddress_ZipCode", "s"."BillingAddress_Country_Code", "s"."BillingAddress_Country_FullName", "s"."BillingAddress_AddressLine10", "s"."BillingAddress_AddressLine20", "s"."BillingAddress_Tags0", "s"."BillingAddress_ZipCode0", "s"."BillingAddress_Country_Code0", "s"."BillingAddress_Country_FullName0" FROM ( SELECT DISTINCT "c"."BillingAddress_AddressLine1", "c"."BillingAddress_AddressLine2", "c"."BillingAddress_Tags", "c"."BillingAddress_ZipCode", "c"."BillingAddress_Country_Code", "c"."BillingAddress_Country_FullName", "c0"."BillingAddress_AddressLine1" AS "BillingAddress_AddressLine10", "c0"."BillingAddress_AddressLine2" AS "BillingAddress_AddressLine20", "c0"."BillingAddress_Tags" AS "BillingAddress_Tags0", "c0"."BillingAddress_ZipCode" AS "BillingAddress_ZipCode0", "c0"."BillingAddress_Country_Code" AS "BillingAddress_Country_Code0", "c0"."BillingAddress_Country_FullName" AS "BillingAddress_Country_FullName0" @@ -781,7 +782,7 @@ public override async Task Project_same_entity_with_nested_complex_type_twice_wi await base.Project_same_entity_with_nested_complex_type_twice_with_double_pushdown(async); AssertSql( -""" + """ @__p_0='50' SELECT "s0"."Id", "s0"."Name", "s0"."BillingAddress_AddressLine1", "s0"."BillingAddress_AddressLine2", "s0"."BillingAddress_Tags", "s0"."BillingAddress_ZipCode", "s0"."BillingAddress_Country_Code", "s0"."BillingAddress_Country_FullName", "s0"."ShippingAddress_AddressLine1", "s0"."ShippingAddress_AddressLine2", "s0"."ShippingAddress_Tags", "s0"."ShippingAddress_ZipCode", "s0"."ShippingAddress_Country_Code", "s0"."ShippingAddress_Country_FullName", "s0"."Id0", "s0"."Name0", "s0"."BillingAddress_AddressLine10", "s0"."BillingAddress_AddressLine20", "s0"."BillingAddress_Tags0", "s0"."BillingAddress_ZipCode0", "s0"."BillingAddress_Country_Code0", "s0"."BillingAddress_Country_FullName0", "s0"."ShippingAddress_AddressLine10", "s0"."ShippingAddress_AddressLine20", "s0"."ShippingAddress_Tags0", "s0"."ShippingAddress_ZipCode0", "s0"."ShippingAddress_Country_Code0", "s0"."ShippingAddress_Country_FullName0" @@ -803,7 +804,7 @@ public override async Task Project_same_nested_complex_type_twice_with_double_pu await base.Project_same_nested_complex_type_twice_with_double_pushdown(async); AssertSql( -""" + """ @__p_0='50' SELECT "s0"."BillingAddress_AddressLine1", "s0"."BillingAddress_AddressLine2", "s0"."BillingAddress_Tags", "s0"."BillingAddress_ZipCode", "s0"."BillingAddress_Country_Code", "s0"."BillingAddress_Country_FullName", "s0"."BillingAddress_AddressLine10", "s0"."BillingAddress_AddressLine20", "s0"."BillingAddress_Tags0", "s0"."BillingAddress_ZipCode0", "s0"."BillingAddress_Country_Code0", "s0"."BillingAddress_Country_FullName0" @@ -825,7 +826,7 @@ public override async Task Project_same_entity_with_struct_nested_complex_type_t await base.Project_same_entity_with_struct_nested_complex_type_twice_with_pushdown(async); AssertSql( -""" + """ SELECT "s"."Id", "s"."Name", "s"."BillingAddress_AddressLine1", "s"."BillingAddress_AddressLine2", "s"."BillingAddress_ZipCode", "s"."BillingAddress_Country_Code", "s"."BillingAddress_Country_FullName", "s"."ShippingAddress_AddressLine1", "s"."ShippingAddress_AddressLine2", "s"."ShippingAddress_ZipCode", "s"."ShippingAddress_Country_Code", "s"."ShippingAddress_Country_FullName", "s"."Id0", "s"."Name0", "s"."BillingAddress_AddressLine10", "s"."BillingAddress_AddressLine20", "s"."BillingAddress_ZipCode0", "s"."BillingAddress_Country_Code0", "s"."BillingAddress_Country_FullName0", "s"."ShippingAddress_AddressLine10", "s"."ShippingAddress_AddressLine20", "s"."ShippingAddress_ZipCode0", "s"."ShippingAddress_Country_Code0", "s"."ShippingAddress_Country_FullName0" FROM ( SELECT DISTINCT "v"."Id", "v"."Name", "v"."BillingAddress_AddressLine1", "v"."BillingAddress_AddressLine2", "v"."BillingAddress_ZipCode", "v"."BillingAddress_Country_Code", "v"."BillingAddress_Country_FullName", "v"."ShippingAddress_AddressLine1", "v"."ShippingAddress_AddressLine2", "v"."ShippingAddress_ZipCode", "v"."ShippingAddress_Country_Code", "v"."ShippingAddress_Country_FullName", "v0"."Id" AS "Id0", "v0"."Name" AS "Name0", "v0"."BillingAddress_AddressLine1" AS "BillingAddress_AddressLine10", "v0"."BillingAddress_AddressLine2" AS "BillingAddress_AddressLine20", "v0"."BillingAddress_ZipCode" AS "BillingAddress_ZipCode0", "v0"."BillingAddress_Country_Code" AS "BillingAddress_Country_Code0", "v0"."BillingAddress_Country_FullName" AS "BillingAddress_Country_FullName0", "v0"."ShippingAddress_AddressLine1" AS "ShippingAddress_AddressLine10", "v0"."ShippingAddress_AddressLine2" AS "ShippingAddress_AddressLine20", "v0"."ShippingAddress_ZipCode" AS "ShippingAddress_ZipCode0", "v0"."ShippingAddress_Country_Code" AS "ShippingAddress_Country_Code0", "v0"."ShippingAddress_Country_FullName" AS "ShippingAddress_Country_FullName0" @@ -840,7 +841,7 @@ public override async Task Project_same_struct_nested_complex_type_twice_with_pu await base.Project_same_struct_nested_complex_type_twice_with_pushdown(async); AssertSql( -""" + """ SELECT "s"."BillingAddress_AddressLine1", "s"."BillingAddress_AddressLine2", "s"."BillingAddress_ZipCode", "s"."BillingAddress_Country_Code", "s"."BillingAddress_Country_FullName", "s"."BillingAddress_AddressLine10", "s"."BillingAddress_AddressLine20", "s"."BillingAddress_ZipCode0", "s"."BillingAddress_Country_Code0", "s"."BillingAddress_Country_FullName0" FROM ( SELECT DISTINCT "v"."BillingAddress_AddressLine1", "v"."BillingAddress_AddressLine2", "v"."BillingAddress_ZipCode", "v"."BillingAddress_Country_Code", "v"."BillingAddress_Country_FullName", "v0"."BillingAddress_AddressLine1" AS "BillingAddress_AddressLine10", "v0"."BillingAddress_AddressLine2" AS "BillingAddress_AddressLine20", "v0"."BillingAddress_ZipCode" AS "BillingAddress_ZipCode0", "v0"."BillingAddress_Country_Code" AS "BillingAddress_Country_Code0", "v0"."BillingAddress_Country_FullName" AS "BillingAddress_Country_FullName0" @@ -855,7 +856,7 @@ public override async Task Project_same_entity_with_struct_nested_complex_type_t await base.Project_same_entity_with_struct_nested_complex_type_twice_with_double_pushdown(async); AssertSql( -""" + """ @__p_0='50' SELECT "s0"."Id", "s0"."Name", "s0"."BillingAddress_AddressLine1", "s0"."BillingAddress_AddressLine2", "s0"."BillingAddress_ZipCode", "s0"."BillingAddress_Country_Code", "s0"."BillingAddress_Country_FullName", "s0"."ShippingAddress_AddressLine1", "s0"."ShippingAddress_AddressLine2", "s0"."ShippingAddress_ZipCode", "s0"."ShippingAddress_Country_Code", "s0"."ShippingAddress_Country_FullName", "s0"."Id0", "s0"."Name0", "s0"."BillingAddress_AddressLine10", "s0"."BillingAddress_AddressLine20", "s0"."BillingAddress_ZipCode0", "s0"."BillingAddress_Country_Code0", "s0"."BillingAddress_Country_FullName0", "s0"."ShippingAddress_AddressLine10", "s0"."ShippingAddress_AddressLine20", "s0"."ShippingAddress_ZipCode0", "s0"."ShippingAddress_Country_Code0", "s0"."ShippingAddress_Country_FullName0" @@ -877,7 +878,7 @@ public override async Task Project_same_struct_nested_complex_type_twice_with_do await base.Project_same_struct_nested_complex_type_twice_with_double_pushdown(async); AssertSql( -""" + """ @__p_0='50' SELECT "s0"."BillingAddress_AddressLine1", "s0"."BillingAddress_AddressLine2", "s0"."BillingAddress_ZipCode", "s0"."BillingAddress_Country_Code", "s0"."BillingAddress_Country_FullName", "s0"."BillingAddress_AddressLine10", "s0"."BillingAddress_AddressLine20", "s0"."BillingAddress_ZipCode0", "s0"."BillingAddress_Country_Code0", "s0"."BillingAddress_Country_FullName0" @@ -899,7 +900,7 @@ public override async Task Union_of_same_entity_with_nested_complex_type_project await base.Union_of_same_entity_with_nested_complex_type_projected_twice_with_pushdown(async); AssertSql( -""" + """ @__p_0='50' SELECT "u"."Id", "u"."Name", "u"."BillingAddress_AddressLine1", "u"."BillingAddress_AddressLine2", "u"."BillingAddress_Tags", "u"."BillingAddress_ZipCode", "u"."BillingAddress_Country_Code", "u"."BillingAddress_Country_FullName", "u"."ShippingAddress_AddressLine1", "u"."ShippingAddress_AddressLine2", "u"."ShippingAddress_Tags", "u"."ShippingAddress_ZipCode", "u"."ShippingAddress_Country_Code", "u"."ShippingAddress_Country_FullName", "u"."Id0", "u"."Name0", "u"."BillingAddress_AddressLine10", "u"."BillingAddress_AddressLine20", "u"."BillingAddress_Tags0", "u"."BillingAddress_ZipCode0", "u"."BillingAddress_Country_Code0", "u"."BillingAddress_Country_FullName0", "u"."ShippingAddress_AddressLine10", "u"."ShippingAddress_AddressLine20", "u"."ShippingAddress_Tags0", "u"."ShippingAddress_ZipCode0", "u"."ShippingAddress_Country_Code0", "u"."ShippingAddress_Country_FullName0" @@ -922,7 +923,7 @@ public override async Task Union_of_same_entity_with_nested_complex_type_project await base.Union_of_same_entity_with_nested_complex_type_projected_twice_with_double_pushdown(async); AssertSql( -""" + """ @__p_0='50' SELECT "u1"."Id", "u1"."Name", "u1"."BillingAddress_AddressLine1", "u1"."BillingAddress_AddressLine2", "u1"."BillingAddress_Tags", "u1"."BillingAddress_ZipCode", "u1"."BillingAddress_Country_Code", "u1"."BillingAddress_Country_FullName", "u1"."ShippingAddress_AddressLine1", "u1"."ShippingAddress_AddressLine2", "u1"."ShippingAddress_Tags", "u1"."ShippingAddress_ZipCode", "u1"."ShippingAddress_Country_Code", "u1"."ShippingAddress_Country_FullName", "u1"."Id0", "u1"."Name0", "u1"."BillingAddress_AddressLine10", "u1"."BillingAddress_AddressLine20", "u1"."BillingAddress_Tags0", "u1"."BillingAddress_ZipCode0", "u1"."BillingAddress_Country_Code0", "u1"."BillingAddress_Country_FullName0", "u1"."ShippingAddress_AddressLine10", "u1"."ShippingAddress_AddressLine20", "u1"."ShippingAddress_Tags0", "u1"."ShippingAddress_ZipCode0", "u1"."ShippingAddress_Country_Code0", "u1"."ShippingAddress_Country_FullName0" @@ -953,7 +954,7 @@ public override async Task Union_of_same_nested_complex_type_projected_twice_wit await base.Union_of_same_nested_complex_type_projected_twice_with_pushdown(async); AssertSql( -""" + """ @__p_0='50' SELECT "u"."BillingAddress_AddressLine1", "u"."BillingAddress_AddressLine2", "u"."BillingAddress_Tags", "u"."BillingAddress_ZipCode", "u"."BillingAddress_Country_Code", "u"."BillingAddress_Country_FullName", "u"."BillingAddress_AddressLine10", "u"."BillingAddress_AddressLine20", "u"."BillingAddress_Tags0", "u"."BillingAddress_ZipCode0", "u"."BillingAddress_Country_Code0", "u"."BillingAddress_Country_FullName0" @@ -976,7 +977,7 @@ public override async Task Union_of_same_nested_complex_type_projected_twice_wit await base.Union_of_same_nested_complex_type_projected_twice_with_double_pushdown(async); AssertSql( -""" + """ @__p_0='50' SELECT "u1"."BillingAddress_AddressLine1", "u1"."BillingAddress_AddressLine2", "u1"."BillingAddress_Tags", "u1"."BillingAddress_ZipCode", "u1"."BillingAddress_Country_Code", "u1"."BillingAddress_Country_FullName", "u1"."BillingAddress_AddressLine10", "u1"."BillingAddress_AddressLine20", "u1"."BillingAddress_Tags0", "u1"."BillingAddress_ZipCode0", "u1"."BillingAddress_Country_Code0", "u1"."BillingAddress_Country_FullName0" @@ -1082,7 +1083,7 @@ public override async Task Projecting_property_of_complex_type_using_left_join_w await base.Projecting_property_of_complex_type_using_left_join_with_pushdown(async); AssertSql( -""" + """ SELECT "c1"."BillingAddress_ZipCode" FROM "CustomerGroup" AS "c" LEFT JOIN ( @@ -1098,7 +1099,7 @@ public override async Task Projecting_complex_from_optional_navigation_using_con await base.Projecting_complex_from_optional_navigation_using_conditional(async); AssertSql( -""" + """ @__p_0='20' SELECT "s0"."ShippingAddress_ZipCode" @@ -1120,7 +1121,7 @@ public override async Task Project_entity_with_complex_type_pushdown_and_then_le await base.Project_entity_with_complex_type_pushdown_and_then_left_join(async); AssertSql( -""" + """ @__p_0='20' @__p_1='30' diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/FromSqlQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/FromSqlQuerySqliteTest.cs index 822b6326133..4205cf575f5 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/FromSqlQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/FromSqlQuerySqliteTest.cs @@ -9,9 +9,7 @@ public class FromSqlQuerySqliteTest : FromSqlQueryTestBase fixture, ITestOutputHelper testOutputHelper) : base(fixture) - { - Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); - } + => Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); public override async Task FromSqlRaw_queryable_composed(bool async) { diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarFromSqlQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarFromSqlQuerySqliteTest.cs index 563ba252b5d..dca636023dc 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarFromSqlQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarFromSqlQuerySqliteTest.cs @@ -5,4 +5,5 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class GearsOfWarFromSqlQuerySqliteTest(GearsOfWarQuerySqliteFixture fixture) : GearsOfWarFromSqlQueryTestBase(fixture); +public class GearsOfWarFromSqlQuerySqliteTest(GearsOfWarQuerySqliteFixture fixture) + : GearsOfWarFromSqlQueryTestBase(fixture); diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs index 0c822d8e003..328f42a797b 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs @@ -27,7 +27,7 @@ public override async Task Non_string_concat_uses_appropriate_type_mapping(bool await base.Non_string_concat_uses_appropriate_type_mapping(async); AssertSql( -""" + """ SELECT "m"."Duration" FROM "Missions" AS "m" """); @@ -751,7 +751,7 @@ public override async Task Where_DateOnly_FromDateTime_compared_to_property(bool await base.Where_DateOnly_FromDateTime_compared_to_property(async); AssertSql( -""" + """ SELECT "t"."Id" AS "TagId", "m"."Id" AS "MissionId" FROM "Tags" AS "t" CROSS JOIN "Missions" AS "m" @@ -764,7 +764,7 @@ public override async Task Where_DateOnly_FromDateTime_compared_to_constant_and_ await base.Where_DateOnly_FromDateTime_compared_to_constant_and_parameter(async); AssertSql( -""" + """ @__prm_0='10/11/0002' (DbType = Date) SELECT "t"."Id", "t"."GearNickName", "t"."GearSquadId", "t"."IssueDate", "t"."Note" @@ -2335,7 +2335,7 @@ public override async Task Where_subquery_distinct_singleordefault_boolean2(bool SELECT "g"."Nickname", "g"."SquadId", "g"."AssignedCityName", "g"."CityOfBirthName", "g"."Discriminator", "g"."FullName", "g"."HasSoulPatch", "g"."LeaderNickname", "g"."LeaderSquadId", "g"."Rank" FROM "Gears" AS "g" WHERE "g"."HasSoulPatch" AND COALESCE(( - SELECT DISTINCT "w"."IsAutomatic" + SELECT "w"."IsAutomatic" FROM "Weapons" AS "w" WHERE "g"."FullName" = "w"."OwnerFullName" AND instr("w"."Name", 'Lancer') > 0 LIMIT 1), 0) @@ -3448,7 +3448,7 @@ public override async Task ToString_nullable_enum_property_projection(bool async await base.ToString_nullable_enum_property_projection(async); AssertSql( -""" + """ SELECT CASE "w"."AmmunitionType" WHEN 1 THEN 'Cartridge' WHEN 2 THEN 'Shell' @@ -3463,7 +3463,7 @@ public override async Task ToString_enum_contains(bool async) await base.ToString_enum_contains(async); AssertSql( -""" + """ SELECT "m"."CodeName" FROM "Missions" AS "m" WHERE instr(CAST("m"."Difficulty" AS TEXT), 'Med') > 0 @@ -3475,7 +3475,7 @@ public override async Task ToString_nullable_enum_contains(bool async) await base.ToString_nullable_enum_contains(async); AssertSql( -""" + """ SELECT "w"."Name" FROM "Weapons" AS "w" WHERE instr(CASE "w"."AmmunitionType" @@ -4852,7 +4852,7 @@ public override async Task Select_subquery_distinct_singleordefault_boolean2(boo AssertSql( """ SELECT COALESCE(( - SELECT DISTINCT "w"."IsAutomatic" + SELECT "w"."IsAutomatic" FROM "Weapons" AS "w" WHERE "g"."FullName" = "w"."OwnerFullName" AND instr("w"."Name", 'Lancer') > 0 LIMIT 1), 0) @@ -7320,7 +7320,7 @@ public override async Task Select_subquery_distinct_singleordefault_boolean_empt AssertSql( """ SELECT COALESCE(( - SELECT DISTINCT "w"."IsAutomatic" + SELECT "w"."IsAutomatic" FROM "Weapons" AS "w" WHERE "g"."FullName" = "w"."OwnerFullName" AND "w"."Name" = 'BFG' LIMIT 1), 0) @@ -9743,7 +9743,7 @@ public override async Task Include_one_to_many_on_composite_key_then_orderby_key await base.Include_one_to_many_on_composite_key_then_orderby_key_properties(async); AssertSql( -""" + """ SELECT "g"."Nickname", "g"."SquadId", "g"."AssignedCityName", "g"."CityOfBirthName", "g"."Discriminator", "g"."FullName", "g"."HasSoulPatch", "g"."LeaderNickname", "g"."LeaderSquadId", "g"."Rank", "w"."Id", "w"."AmmunitionType", "w"."IsAutomatic", "w"."Name", "w"."OwnerFullName", "w"."SynergyWithId" FROM "Gears" AS "g" LEFT JOIN "Weapons" AS "w" ON "g"."FullName" = "w"."OwnerFullName" @@ -9772,23 +9772,23 @@ public override async Task Join_include_coalesce_simple(bool async) await base.Join_include_coalesce_simple(async); AssertSql( -""" + """ SELECT "g0"."Nickname", "g0"."SquadId", "g0"."AssignedCityName", "g0"."CityOfBirthName", "g0"."Discriminator", "g0"."FullName", "g0"."HasSoulPatch", "g0"."LeaderNickname", "g0"."LeaderSquadId", "g0"."Rank", "g"."Nickname", "g"."SquadId", "g"."AssignedCityName", "g"."CityOfBirthName", "g"."Discriminator", "g"."FullName", "g"."HasSoulPatch", "g"."LeaderNickname", "g"."LeaderSquadId", "g"."Rank", "w"."Id", "w"."AmmunitionType", "w"."IsAutomatic", "w"."Name", "w"."OwnerFullName", "w"."SynergyWithId", "g"."Nickname" = 'Marcus' FROM "Gears" AS "g" LEFT JOIN "Gears" AS "g0" ON "g"."LeaderNickname" = "g0"."Nickname" LEFT JOIN "Weapons" AS "w" ON "g"."FullName" = "w"."OwnerFullName" ORDER BY "g"."Nickname", "g"."SquadId", "g0"."Nickname", "g0"."SquadId" """, - // - """ + // + """ SELECT "g0"."Nickname", "g0"."SquadId", "g0"."AssignedCityName", "g0"."CityOfBirthName", "g0"."Discriminator", "g0"."FullName", "g0"."HasSoulPatch", "g0"."LeaderNickname", "g0"."LeaderSquadId", "g0"."Rank", "g"."Nickname", "g"."SquadId", "w"."Id", "w"."AmmunitionType", "w"."IsAutomatic", "w"."Name", "w"."OwnerFullName", "w"."SynergyWithId", "g"."AssignedCityName", "g"."CityOfBirthName", "g"."Discriminator", "g"."FullName", "g"."HasSoulPatch", "g"."LeaderNickname", "g"."LeaderSquadId", "g"."Rank" FROM "Gears" AS "g" LEFT JOIN "Gears" AS "g0" ON "g"."LeaderNickname" = "g0"."Nickname" LEFT JOIN "Weapons" AS "w" ON "g0"."FullName" = "w"."OwnerFullName" ORDER BY "g"."Nickname", "g"."SquadId", "g0"."Nickname", "g0"."SquadId" """, - // - """ + // + """ SELECT "g0"."Nickname", "g0"."SquadId", "g0"."AssignedCityName", "g0"."CityOfBirthName", "g0"."Discriminator", "g0"."FullName", "g0"."HasSoulPatch", "g0"."LeaderNickname", "g0"."LeaderSquadId", "g0"."Rank", "g"."Nickname", "g"."SquadId", "w"."Id", "w"."AmmunitionType", "w"."IsAutomatic", "w"."Name", "w"."OwnerFullName", "w"."SynergyWithId", "g"."AssignedCityName", "g"."CityOfBirthName", "g"."Discriminator", "g"."FullName", "g"."HasSoulPatch", "g"."LeaderNickname", "g"."LeaderSquadId", "g"."Rank", "w0"."Id", "w0"."AmmunitionType", "w0"."IsAutomatic", "w0"."Name", "w0"."OwnerFullName", "w0"."SynergyWithId" FROM "Gears" AS "g" LEFT JOIN "Gears" AS "g0" ON "g"."LeaderNickname" = "g0"."Nickname" @@ -9803,15 +9803,15 @@ public override async Task Join_include_coalesce_nested(bool async) await base.Join_include_coalesce_nested(async); AssertSql( -""" + """ SELECT "g0"."Nickname", "g0"."SquadId", "g0"."AssignedCityName", "g0"."CityOfBirthName", "g0"."Discriminator", "g0"."FullName", "g0"."HasSoulPatch", "g0"."LeaderNickname", "g0"."LeaderSquadId", "g0"."Rank", "g"."Nickname", "g"."SquadId", "g"."AssignedCityName", "g"."CityOfBirthName", "g"."Discriminator", "g"."FullName", "g"."HasSoulPatch", "g"."LeaderNickname", "g"."LeaderSquadId", "g"."Rank", "w"."Id", "w"."AmmunitionType", "w"."IsAutomatic", "w"."Name", "w"."OwnerFullName", "w"."SynergyWithId", "g"."Nickname" = 'Marcus' FROM "Gears" AS "g" LEFT JOIN "Gears" AS "g0" ON "g"."LeaderNickname" = "g0"."Nickname" LEFT JOIN "Weapons" AS "w" ON "g"."FullName" = "w"."OwnerFullName" ORDER BY "g"."Nickname", "g"."SquadId", "g0"."Nickname", "g0"."SquadId" """, - // - """ + // + """ SELECT "g0"."Nickname", "g0"."SquadId", "g0"."AssignedCityName", "g0"."CityOfBirthName", "g0"."Discriminator", "g0"."FullName", "g0"."HasSoulPatch", "g0"."LeaderNickname", "g0"."LeaderSquadId", "g0"."Rank", "g"."Nickname", "g"."SquadId", "w"."Id", "w"."AmmunitionType", "w"."IsAutomatic", "w"."Name", "w"."OwnerFullName", "w"."SynergyWithId", "w0"."Id", "w0"."AmmunitionType", "w0"."IsAutomatic", "w0"."Name", "w0"."OwnerFullName", "w0"."SynergyWithId", "g"."AssignedCityName", "g"."CityOfBirthName", "g"."Discriminator", "g"."FullName", "g"."HasSoulPatch", "g"."LeaderNickname", "g"."LeaderSquadId", "g"."Rank", "w1"."Id", "w1"."AmmunitionType", "w1"."IsAutomatic", "w1"."Name", "w1"."OwnerFullName", "w1"."SynergyWithId" FROM "Gears" AS "g" LEFT JOIN "Gears" AS "g0" ON "g"."LeaderNickname" = "g0"."Nickname" @@ -9827,7 +9827,7 @@ public override async Task Join_include_conditional(bool async) await base.Join_include_conditional(async); AssertSql( -""" + """ SELECT "g0"."Nickname" IS NOT NULL AND "g0"."SquadId" IS NOT NULL, "g0"."Nickname", "g0"."SquadId", "g0"."AssignedCityName", "g0"."CityOfBirthName", "g0"."Discriminator", "g0"."FullName", "g0"."HasSoulPatch", "g0"."LeaderNickname", "g0"."LeaderSquadId", "g0"."Rank", "g"."Nickname", "g"."SquadId", "g"."AssignedCityName", "g"."CityOfBirthName", "g"."Discriminator", "g"."FullName", "g"."HasSoulPatch", "g"."LeaderNickname", "g"."LeaderSquadId", "g"."Rank", "w"."Id", "w"."AmmunitionType", "w"."IsAutomatic", "w"."Name", "w"."OwnerFullName", "w"."SynergyWithId", "g"."Nickname" = 'Marcus' FROM "Gears" AS "g" LEFT JOIN "Gears" AS "g0" ON "g"."LeaderNickname" = "g0"."Nickname" @@ -9841,7 +9841,7 @@ public override async Task Derived_reference_is_skipped_when_base_type(bool asyn await base.Derived_reference_is_skipped_when_base_type(async); AssertSql( -""" + """ SELECT "l"."Name", "l"."Discriminator", "l"."LocustHordeId", "l"."ThreatLevel", "l"."ThreatLevelByte", "l"."ThreatLevelNullableByte", "l"."DefeatedByNickname", "l"."DefeatedBySquadId", "l"."HighCommandId", "l0"."Id", "l0"."IsOperational", "l0"."Name" FROM "LocustLeaders" AS "l" LEFT JOIN "LocustHighCommands" AS "l0" ON "l"."HighCommandId" = "l0"."Id" diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/IncludeOneToOneSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/IncludeOneToOneSqliteTest.cs index 0d31339197f..cf47b21fbab 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/IncludeOneToOneSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/IncludeOneToOneSqliteTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class IncludeOneToOneSqliteTest(IncludeOneToOneSqliteTest.OneToOneQuerySqliteFixture fixture) : IncludeOneToOneTestBase(fixture) +public class IncludeOneToOneSqliteTest(IncludeOneToOneSqliteTest.OneToOneQuerySqliteFixture fixture) + : IncludeOneToOneTestBase(fixture) { public class OneToOneQuerySqliteFixture : OneToOneQueryFixtureBase, ITestSqlLoggerFactory { diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/InheritanceQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/InheritanceQuerySqliteTest.cs index 4868abd1d02..b3d847c1f9d 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/InheritanceQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/InheritanceQuerySqliteTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class InheritanceQuerySqliteTest(TPHInheritanceQuerySqliteFixture fixture, ITestOutputHelper testOutputHelper) : TPHInheritanceQueryTestBase(fixture, testOutputHelper) +public class InheritanceQuerySqliteTest(TPHInheritanceQuerySqliteFixture fixture, ITestOutputHelper testOutputHelper) + : TPHInheritanceQueryTestBase(fixture, testOutputHelper) { protected override void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction) => facade.UseTransaction(transaction.GetDbTransaction()); diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/InheritanceRelationshipsQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/InheritanceRelationshipsQuerySqliteTest.cs index 7436bf8d93e..143c10781d2 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/InheritanceRelationshipsQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/InheritanceRelationshipsQuerySqliteTest.cs @@ -5,8 +5,10 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class InheritanceRelationshipsQuerySqliteTest(InheritanceRelationshipsQuerySqliteTest.InheritanceRelationshipsQuerySqliteFixture fixture) : - InheritanceRelationshipsQueryRelationalTestBase(fixture) +public class InheritanceRelationshipsQuerySqliteTest( + InheritanceRelationshipsQuerySqliteTest.InheritanceRelationshipsQuerySqliteFixture fixture) : + InheritanceRelationshipsQueryRelationalTestBase( + fixture) { public class InheritanceRelationshipsQuerySqliteFixture : InheritanceRelationshipsQueryRelationalFixture { diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/JsonQuerySqliteFixture.cs b/test/EFCore.Sqlite.FunctionalTests/Query/JsonQuerySqliteFixture.cs index 691db31b098..fbbcc29d4a2 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/JsonQuerySqliteFixture.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/JsonQuerySqliteFixture.cs @@ -11,6 +11,7 @@ public class JsonQuerySqliteFixture : JsonQueryRelationalFixture { protected override ITestStoreFactory TestStoreFactory => SqliteTestStoreFactory.Instance; + protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) { base.OnModelCreating(modelBuilder, context); diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/JsonQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/JsonQuerySqliteTest.cs index d4340526ff2..13e953bf006 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/JsonQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/JsonQuerySqliteTest.cs @@ -99,7 +99,7 @@ public override async Task Json_collection_Where_ElementAt(bool async) WHERE ( SELECT "o0"."OwnedReferenceLeaf" ->> 'SomethingSomething' FROM ( - SELECT "o"."value" ->> 'Date' AS "Date", "o"."value" ->> 'Enum' AS "Enum", "o"."value" ->> 'Fraction' AS "Fraction", "o"."value" ->> 'OwnedReferenceLeaf' AS "OwnedReferenceLeaf", "o"."key" + SELECT "o"."value" ->> 'Date' AS "Date", "o"."value" ->> 'Enum' AS "Enum", "o"."value" ->> 'Fraction' AS "Fraction", "o"."value" ->> 'Id' AS "Id", "o"."value" ->> 'OwnedReferenceLeaf' AS "OwnedReferenceLeaf", "o"."key" FROM json_each("j"."OwnedReferenceRoot", '$.OwnedCollectionBranch') AS "o" ) AS "o0" WHERE "o0"."Enum" = -3 @@ -145,7 +145,7 @@ public override async Task Json_collection_OrderByDescending_Skip_ElementAt(bool FROM ( SELECT "o0"."OwnedReferenceLeaf" ->> 'SomethingSomething' AS "c", "o0"."Date" AS "c0" FROM ( - SELECT "o"."value" ->> 'Date' AS "Date", "o"."value" ->> 'Enum' AS "Enum", "o"."value" ->> 'Fraction' AS "Fraction", "o"."value" ->> 'OwnedReferenceLeaf' AS "OwnedReferenceLeaf" + SELECT "o"."value" ->> 'Date' AS "Date", "o"."value" ->> 'Enum' AS "Enum", "o"."value" ->> 'Fraction' AS "Fraction", "o"."value" ->> 'Id' AS "Id", "o"."value" ->> 'OwnedReferenceLeaf' AS "OwnedReferenceLeaf" FROM json_each("j"."OwnedReferenceRoot", '$.OwnedCollectionBranch') AS "o" ) AS "o0" ORDER BY "o0"."Date" DESC @@ -446,12 +446,13 @@ public override async Task Custom_naming_projection_owned_reference(bool async) """); } - public override async Task Json_nested_collection_anonymous_projection_of_primitives_in_projection_NoTrackingWithIdentityResolution(bool async) - => Assert.Equal( - SqliteStrings.ApplyNotSupported, - (await Assert.ThrowsAsync( - () => base.Json_nested_collection_anonymous_projection_of_primitives_in_projection_NoTrackingWithIdentityResolution(async))) - .Message); + public override async Task Json_nested_collection_anonymous_projection_of_primitives_in_projection_NoTrackingWithIdentityResolution( + bool async) + => Assert.Equal( + SqliteStrings.ApplyNotSupported, + (await Assert.ThrowsAsync( + () => base.Json_nested_collection_anonymous_projection_of_primitives_in_projection_NoTrackingWithIdentityResolution(async))) + .Message); // Sqlit throws APPLY error, but base expects different exception public override Task Json_branch_collection_distinct_and_other_collection_AsNoTrackingWithIdentityResolution(bool async) diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/ManyToManyNoTrackingQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/ManyToManyNoTrackingQuerySqliteTest.cs index 6ba6eed7e5f..00c3ee62cbb 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/ManyToManyNoTrackingQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/ManyToManyNoTrackingQuerySqliteTest.cs @@ -10,7 +10,6 @@ namespace Microsoft.EntityFrameworkCore.Query; public class ManyToManyNoTrackingQuerySqliteTest(ManyToManyQuerySqliteFixture fixture) : ManyToManyNoTrackingQueryRelationalTestBase(fixture) { - // Sqlite does not support Apply operations public override async Task Skip_navigation_order_by_single_or_default(bool async) diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/ManyToManyNoTrackingSplitQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/ManyToManyNoTrackingSplitQuerySqliteTest.cs index b1ca2b34fe0..4ea7fc9278f 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/ManyToManyNoTrackingSplitQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/ManyToManyNoTrackingSplitQuerySqliteTest.cs @@ -10,7 +10,6 @@ namespace Microsoft.EntityFrameworkCore.Query; public class ManyToManyNoTrackingSplitQuerySqliteTest(ManyToManySplitQuerySqliteFixture fixture) : ManyToManyNoTrackingQueryRelationalTestBase(fixture) { - // Sqlite does not support Apply operations public override async Task Skip_navigation_order_by_single_or_default(bool async) diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/ManyToManyQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/ManyToManyQuerySqliteTest.cs index a488d8dbe90..c8b39d88c06 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/ManyToManyQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/ManyToManyQuerySqliteTest.cs @@ -7,7 +7,8 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class ManyToManyQuerySqliteTest(ManyToManyQuerySqliteFixture fixture) : ManyToManyQueryRelationalTestBase(fixture) +public class ManyToManyQuerySqliteTest(ManyToManyQuerySqliteFixture fixture) + : ManyToManyQueryRelationalTestBase(fixture) { public override async Task Skip_navigation_order_by_single_or_default(bool async) => Assert.Equal( diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/ManyToManySplitQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/ManyToManySplitQuerySqliteTest.cs index 5f2b1d06462..7c4798693cd 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/ManyToManySplitQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/ManyToManySplitQuerySqliteTest.cs @@ -7,7 +7,8 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class ManyToManySplitQuerySqliteTest(ManyToManySplitQuerySqliteFixture fixture) : ManyToManyQueryRelationalTestBase(fixture) +public class ManyToManySplitQuerySqliteTest(ManyToManySplitQuerySqliteFixture fixture) + : ManyToManyQueryRelationalTestBase(fixture) { public override async Task Skip_navigation_order_by_single_or_default(bool async) => Assert.Equal( diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/MappingQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/MappingQuerySqliteTest.cs index 2ad51793417..7351435aa57 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/MappingQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/MappingQuerySqliteTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class MappingQuerySqliteTest(MappingQuerySqliteTest.MappingQuerySqliteFixture fixture) : MappingQueryTestBase(fixture) +public class MappingQuerySqliteTest(MappingQuerySqliteTest.MappingQuerySqliteFixture fixture) + : MappingQueryTestBase(fixture) { public override void All_customers() { diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/NonSharedPrimitiveCollectionsQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/NonSharedPrimitiveCollectionsQuerySqliteTest.cs index 8b2d2dc53f7..ae95f98db33 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/NonSharedPrimitiveCollectionsQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/NonSharedPrimitiveCollectionsQuerySqliteTest.cs @@ -7,6 +7,20 @@ namespace Microsoft.EntityFrameworkCore.Query; public class NonSharedPrimitiveCollectionsQuerySqliteTest : NonSharedPrimitiveCollectionsQueryRelationalTestBase { + protected override DbContextOptionsBuilder SetTranslateParameterizedCollectionsToConstants(DbContextOptionsBuilder optionsBuilder) + { + new SqliteDbContextOptionsBuilder(optionsBuilder).TranslateParameterizedCollectionsToConstants(); + + return optionsBuilder; + } + + protected override DbContextOptionsBuilder SetTranslateParameterizedCollectionsToParameters(DbContextOptionsBuilder optionsBuilder) + { + new SqliteDbContextOptionsBuilder(optionsBuilder).TranslateParameterizedCollectionsToParameters(); + + return optionsBuilder; + } + #region Support for specific element types public override async Task Array_of_int() @@ -322,6 +336,128 @@ LIMIT 2 """); } + public override async Task Parameter_collection_Count_with_column_predicate_with_default_constants() + { + await base.Parameter_collection_Count_with_column_predicate_with_default_constants(); + + AssertSql( + """ +SELECT "t"."Id" +FROM "TestEntity" AS "t" +WHERE ( + SELECT COUNT(*) + FROM (SELECT 2 AS "Value" UNION ALL VALUES (999)) AS "i" + WHERE "i"."Value" > "t"."Id") = 1 +"""); + } + + public override async Task Parameter_collection_of_ints_Contains_int_with_default_constants() + { + await base.Parameter_collection_of_ints_Contains_int_with_default_constants(); + + AssertSql( + """ +SELECT "t"."Id" +FROM "TestEntity" AS "t" +WHERE "t"."Id" IN (2, 999) +"""); + } + + public override async Task Parameter_collection_Count_with_column_predicate_with_default_constants_EF_Parameter() + { + await base.Parameter_collection_Count_with_column_predicate_with_default_constants_EF_Parameter(); + + AssertSql( + """ +@__ids_0='[2,999]' (Size = 7) + +SELECT "t"."Id" +FROM "TestEntity" AS "t" +WHERE ( + SELECT COUNT(*) + FROM json_each(@__ids_0) AS "i" + WHERE "i"."value" > "t"."Id") = 1 +"""); + } + + public override async Task Parameter_collection_of_ints_Contains_int_with_default_constants_EF_Parameter() + { + await base.Parameter_collection_of_ints_Contains_int_with_default_constants_EF_Parameter(); + + AssertSql( + """ +@__ints_0='[2,999]' (Size = 7) + +SELECT "t"."Id" +FROM "TestEntity" AS "t" +WHERE "t"."Id" IN ( + SELECT "i"."value" + FROM json_each(@__ints_0) AS "i" +) +"""); + } + + public override async Task Parameter_collection_Count_with_column_predicate_with_default_parameters() + { + await base.Parameter_collection_Count_with_column_predicate_with_default_parameters(); + + AssertSql( + """ +@__ids_0='[2,999]' (Size = 7) + +SELECT "t"."Id" +FROM "TestEntity" AS "t" +WHERE ( + SELECT COUNT(*) + FROM json_each(@__ids_0) AS "i" + WHERE "i"."value" > "t"."Id") = 1 +"""); + } + + public override async Task Parameter_collection_of_ints_Contains_int_with_default_parameters() + { + await base.Parameter_collection_of_ints_Contains_int_with_default_parameters(); + + AssertSql( + """ +@__ints_0='[2,999]' (Size = 7) + +SELECT "t"."Id" +FROM "TestEntity" AS "t" +WHERE "t"."Id" IN ( + SELECT "i"."value" + FROM json_each(@__ints_0) AS "i" +) +"""); + } + + public override async Task Parameter_collection_Count_with_column_predicate_with_default_parameters_EF_Constant() + { + await base.Parameter_collection_Count_with_column_predicate_with_default_parameters_EF_Constant(); + + AssertSql( + """ +SELECT "t"."Id" +FROM "TestEntity" AS "t" +WHERE ( + SELECT COUNT(*) + FROM (SELECT 2 AS "Value" UNION ALL VALUES (999)) AS "i" + WHERE "i"."Value" > "t"."Id") = 1 +"""); + } + + public override async Task Parameter_collection_of_ints_Contains_int_with_default_parameters_EF_Constant() + { + await base.Parameter_collection_of_ints_Contains_int_with_default_parameters_EF_Constant(); + + AssertSql( + """ +SELECT "t"."Id" +FROM "TestEntity" AS "t" +WHERE "t"."Id" IN (2, 999) +"""); + } + protected override ITestStoreFactory TestStoreFactory => SqliteTestStoreFactory.Instance; } diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindAggregateOperatorsQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindAggregateOperatorsQuerySqliteTest.cs index b60bc64d9ea..4f5c029aa42 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindAggregateOperatorsQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindAggregateOperatorsQuerySqliteTest.cs @@ -63,8 +63,6 @@ SELECT ef_avg(ef_divide(CAST("o"."Quantity" AS TEXT), '2.0')) """); } - - public override async Task Average_over_max_subquery(bool async) { await base.Average_over_max_subquery(async); diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindAsNoTrackingQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindAsNoTrackingQuerySqliteTest.cs index e2fe510cad3..592ac1f807c 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindAsNoTrackingQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindAsNoTrackingQuerySqliteTest.cs @@ -5,4 +5,5 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class NorthwindAsNoTrackingQuerySqliteTest(NorthwindQuerySqliteFixture fixture) : NorthwindAsNoTrackingQueryTestBase>(fixture); +public class NorthwindAsNoTrackingQuerySqliteTest(NorthwindQuerySqliteFixture fixture) + : NorthwindAsNoTrackingQueryTestBase>(fixture); diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindAsTrackingQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindAsTrackingQuerySqliteTest.cs index db5a1f6bd44..5331f1d6491 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindAsTrackingQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindAsTrackingQuerySqliteTest.cs @@ -5,4 +5,5 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class NorthwindAsTrackingQuerySqliteTest(NorthwindQuerySqliteFixture fixture) : NorthwindAsTrackingQueryTestBase>(fixture); +public class NorthwindAsTrackingQuerySqliteTest(NorthwindQuerySqliteFixture fixture) + : NorthwindAsTrackingQueryTestBase>(fixture); diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindChangeTrackingQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindChangeTrackingQuerySqliteTest.cs index ec1d09c5ae7..6cdf6312fcc 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindChangeTrackingQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindChangeTrackingQuerySqliteTest.cs @@ -7,8 +7,9 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class NorthwindChangeTrackingQuerySqliteTest(NorthwindQuerySqliteFixture fixture) : NorthwindChangeTrackingQueryTestBase< - NorthwindQuerySqliteFixture>(fixture) +public class NorthwindChangeTrackingQuerySqliteTest(NorthwindQuerySqliteFixture fixture) + : NorthwindChangeTrackingQueryTestBase< + NorthwindQuerySqliteFixture>(fixture) { protected override NorthwindContext CreateNoTrackingContext() => new NorthwindSqliteContext( diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindCompiledQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindCompiledQuerySqliteTest.cs index a0edaa6c372..eda573f3af1 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindCompiledQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindCompiledQuerySqliteTest.cs @@ -5,4 +5,5 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class NorthwindCompiledQuerySqliteTest(NorthwindQuerySqliteFixture fixture) : NorthwindCompiledQueryTestBase>(fixture); +public class NorthwindCompiledQuerySqliteTest(NorthwindQuerySqliteFixture fixture) + : NorthwindCompiledQueryTestBase>(fixture); diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindDbFunctionsQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindDbFunctionsQuerySqliteTest.cs index f409eff864f..aa552d1c51b 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindDbFunctionsQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindDbFunctionsQuerySqliteTest.cs @@ -14,9 +14,7 @@ public NorthwindDbFunctionsQuerySqliteTest( NorthwindQuerySqliteFixture fixture, ITestOutputHelper testOutputHelper) : base(fixture) - { - Fixture.TestSqlLoggerFactory.Clear(); - } + => Fixture.TestSqlLoggerFactory.Clear(); [ConditionalTheory] [MemberData(nameof(IsAsyncData))] diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindNavigationsQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindNavigationsQuerySqliteTest.cs index a1ddf661606..a5fb3a81226 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindNavigationsQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindNavigationsQuerySqliteTest.cs @@ -5,5 +5,6 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class NorthwindNavigationsQuerySqliteTest(NorthwindQuerySqliteFixture fixture) : NorthwindNavigationsQueryRelationalTestBase< - NorthwindQuerySqliteFixture>(fixture); +public class NorthwindNavigationsQuerySqliteTest(NorthwindQuerySqliteFixture fixture) + : NorthwindNavigationsQueryRelationalTestBase< + NorthwindQuerySqliteFixture>(fixture); diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindSqlQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindSqlQuerySqliteTest.cs index 7a9f6cd369d..4748094b687 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindSqlQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindSqlQuerySqliteTest.cs @@ -11,9 +11,7 @@ public class NorthwindSqlQuerySqliteTest : NorthwindSqlQueryTestBase fixture, ITestOutputHelper testOutputHelper) : base(fixture) - { - Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); - } + => Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); protected override DbParameter CreateDbParameter(string name, object value) => new SqliteParameter { ParameterName = name, Value = value }; diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/NullKeysSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/NullKeysSqliteTest.cs index 4b4c7510770..fabd6ef8820 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/NullKeysSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/NullKeysSqliteTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class NullKeysSqliteTest(NullKeysSqliteTest.NullKeysSqliteFixture fixture) : NullKeysTestBase(fixture) +public class NullKeysSqliteTest(NullKeysSqliteTest.NullKeysSqliteFixture fixture) + : NullKeysTestBase(fixture) { public class NullKeysSqliteFixture : NullKeysFixtureBase { diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/NullSemanticsQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/NullSemanticsQuerySqliteTest.cs index 5018e8481a7..e47b0c32c65 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/NullSemanticsQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/NullSemanticsQuerySqliteTest.cs @@ -12,11 +12,9 @@ public class NullSemanticsQuerySqliteTest : NullSemanticsQueryTestBase Fixture.TestSqlLoggerFactory.Clear(); + //Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); public override async Task Rewrite_compare_int_with_int(bool async) { await base.Rewrite_compare_int_with_int(async); @@ -1089,8 +1087,8 @@ SELECT 1 FROM "Entities2" AS "e0" WHERE "e0"."NullableStringA" = "e"."NullableStringB" OR ("e0"."NullableStringA" IS NULL AND "e"."NullableStringB" IS NULL)) """, - // - """ + // + """ SELECT "e"."Id" FROM "Entities1" AS "e" WHERE NOT EXISTS ( diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/OwnedQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/OwnedQuerySqliteTest.cs index 6b09cd15870..2e1fc0c3790 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/OwnedQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/OwnedQuerySqliteTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class OwnedQuerySqliteTest(OwnedQuerySqliteTest.OwnedQuerySqliteFixture fixture) : OwnedQueryRelationalTestBase(fixture) +public class OwnedQuerySqliteTest(OwnedQuerySqliteTest.OwnedQuerySqliteFixture fixture) + : OwnedQueryRelationalTestBase(fixture) { public class OwnedQuerySqliteFixture : RelationalOwnedQueryFixture { diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/PrecompiledQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/PrecompiledQuerySqliteTest.cs index f124247ed7f..6accbe38fd6 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/PrecompiledQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/PrecompiledQuerySqliteTest.cs @@ -27,6 +27,7 @@ public class PrecompiledQuerySqliteFixture : PrecompiledQueryRelationalFixture protected override ITestStoreFactory TestStoreFactory => SqliteTestStoreFactory.Instance; - public override PrecompiledQueryTestHelpers PrecompiledQueryTestHelpers => SqlitePrecompiledQueryTestHelpers.Instance; + public override PrecompiledQueryTestHelpers PrecompiledQueryTestHelpers + => SqlitePrecompiledQueryTestHelpers.Instance; } } diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/PrecompiledSqlPregenerationQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/PrecompiledSqlPregenerationQuerySqliteTest.cs index 072134128f5..03176c25504 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/PrecompiledSqlPregenerationQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/PrecompiledSqlPregenerationQuerySqliteTest.cs @@ -17,6 +17,7 @@ public class PrecompiledSqlPregenerationQuerySqliteFixture : PrecompiledSqlPrege protected override ITestStoreFactory TestStoreFactory => SqliteTestStoreFactory.Instance; - public override PrecompiledQueryTestHelpers PrecompiledQueryTestHelpers => SqlitePrecompiledQueryTestHelpers.Instance; + public override PrecompiledQueryTestHelpers PrecompiledQueryTestHelpers + => SqlitePrecompiledQueryTestHelpers.Instance; } } diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs index 641a258fd1b..ce27814d118 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs @@ -431,6 +431,40 @@ SELECT COUNT(*) """); } + public override async Task Inline_collection_Contains_with_EF_Parameter(bool async) + { + await base.Inline_collection_Contains_with_EF_Parameter(async); + + AssertSql( + """ +@__p_0='[2,999,1000]' (Size = 12) + +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" +WHERE "p"."Id" IN ( + SELECT "p0"."value" + FROM json_each(@__p_0) AS "p0" +) +"""); + } + + public override async Task Inline_collection_Count_with_column_predicate_with_EF_Parameter(bool async) + { + await base.Inline_collection_Count_with_column_predicate_with_EF_Parameter(async); + + AssertSql( + """ +@__p_0='[2,999,1000]' (Size = 12) + +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" +WHERE ( + SELECT COUNT(*) + FROM json_each(@__p_0) AS "p0" + WHERE "p0"."value" > "p"."Id") = 2 +"""); + } + public override async Task Parameter_collection_Count(bool async) { await base.Parameter_collection_Count(async); @@ -491,8 +525,8 @@ public override async Task Parameter_collection_HashSet_of_ints_Contains_int(boo FROM json_each(@__ints_0) AS "i" ) """, - // - """ + // + """ @__ints_0='[10,999]' (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" @@ -1455,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); @@ -1921,7 +1971,8 @@ public async Task Empty_string_used_for_primitive_collection_throws(bool async) public class SimpleContext(SqliteConnection connection) : DbContext { - public DbSet SimpleEntities => Set(); + public DbSet SimpleEntities + => Set(); protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder.UseSqlite(connection); diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/QueryNoClientEvalSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/QueryNoClientEvalSqliteTest.cs index f86ae7892f7..6fc630baf15 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/QueryNoClientEvalSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/QueryNoClientEvalSqliteTest.cs @@ -5,4 +5,5 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class QueryNoClientEvalSqliteTest(QueryNoClientEvalSqliteFixture fixture) : QueryNoClientEvalTestBase(fixture); +public class QueryNoClientEvalSqliteTest(QueryNoClientEvalSqliteFixture fixture) + : QueryNoClientEvalTestBase(fixture); diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/SqlQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/SqlQuerySqliteTest.cs index 8a80cba557a..2614a5786fd 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/SqlQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/SqlQuerySqliteTest.cs @@ -11,9 +11,7 @@ public class SqlQuerySqliteTest : SqlQueryTestBase fixture, ITestOutputHelper testOutputHelper) : base(fixture) - { - Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); - } + => Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); public override async Task SqlQueryRaw_queryable_composed(bool async) { diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/TPCFiltersInheritanceQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/TPCFiltersInheritanceQuerySqliteTest.cs index 5c2b7e47f64..8617b19de0e 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/TPCFiltersInheritanceQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/TPCFiltersInheritanceQuerySqliteTest.cs @@ -5,4 +5,5 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class TPCFiltersInheritanceQuerySqliteTest(TPCFiltersInheritanceQuerySqliteFixture fixture) : TPCFiltersInheritanceQueryTestBase(fixture); +public class TPCFiltersInheritanceQuerySqliteTest(TPCFiltersInheritanceQuerySqliteFixture fixture) + : TPCFiltersInheritanceQueryTestBase(fixture); diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/TPCGearsOfWarQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/TPCGearsOfWarQuerySqliteTest.cs index 9fe95d394df..07174a52b7b 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/TPCGearsOfWarQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/TPCGearsOfWarQuerySqliteTest.cs @@ -414,7 +414,7 @@ public override async Task Where_DateOnly_FromDateTime_compared_to_property(bool await base.Where_DateOnly_FromDateTime_compared_to_property(async); AssertSql( -""" + """ SELECT "t"."Id" AS "TagId", "m"."Id" AS "MissionId" FROM "Tags" AS "t" CROSS JOIN "Missions" AS "m" @@ -427,7 +427,7 @@ public override async Task Where_DateOnly_FromDateTime_compared_to_constant_and_ await base.Where_DateOnly_FromDateTime_compared_to_constant_and_parameter(async); AssertSql( -""" + """ @__prm_0='10/11/0002' (DbType = Date) SELECT "t"."Id", "t"."GearNickName", "t"."GearSquadId", "t"."IssueDate", "t"."Note" diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/TPCInheritanceQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/TPCInheritanceQuerySqliteTest.cs index 5c5286a8daf..635b05f6158 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/TPCInheritanceQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/TPCInheritanceQuerySqliteTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class TPCInheritanceQuerySqliteTest(TPCInheritanceQuerySqliteFixture fixture, ITestOutputHelper testOutputHelper) : TPCInheritanceQueryTestBase(fixture, testOutputHelper) +public class TPCInheritanceQuerySqliteTest(TPCInheritanceQuerySqliteFixture fixture, ITestOutputHelper testOutputHelper) + : TPCInheritanceQueryTestBase(fixture, testOutputHelper) { protected override void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction) => facade.UseTransaction(transaction.GetDbTransaction()); diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/TPCManyToManyNoTrackingQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/TPCManyToManyNoTrackingQuerySqliteTest.cs index 5cc7a930dfd..bbfee8c56b8 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/TPCManyToManyNoTrackingQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/TPCManyToManyNoTrackingQuerySqliteTest.cs @@ -7,7 +7,8 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class TPCManyToManyNoTrackingQuerySqliteTest(TPCManyToManyQuerySqliteFixture fixture) : TPCManyToManyNoTrackingQueryRelationalTestBase(fixture) +public class TPCManyToManyNoTrackingQuerySqliteTest(TPCManyToManyQuerySqliteFixture fixture) + : TPCManyToManyNoTrackingQueryRelationalTestBase(fixture) { public override async Task Skip_navigation_order_by_single_or_default(bool async) => Assert.Equal( diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/TPCManyToManyQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/TPCManyToManyQuerySqliteTest.cs index 799f133093d..b601dc89656 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/TPCManyToManyQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/TPCManyToManyQuerySqliteTest.cs @@ -7,7 +7,8 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class TPCManyToManyQuerySqliteTest(TPCManyToManyQuerySqliteFixture fixture) : TPCManyToManyQueryRelationalTestBase(fixture) +public class TPCManyToManyQuerySqliteTest(TPCManyToManyQuerySqliteFixture fixture) + : TPCManyToManyQueryRelationalTestBase(fixture) { public override async Task Skip_navigation_order_by_single_or_default(bool async) => Assert.Equal( diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/TPHFiltersInheritanceQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/TPHFiltersInheritanceQuerySqliteTest.cs index 7a39fe9b968..87cd8b67fe2 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/TPHFiltersInheritanceQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/TPHFiltersInheritanceQuerySqliteTest.cs @@ -5,4 +5,5 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class TPHFiltersInheritanceQuerySqliteTest(TPHFiltersInheritanceQuerySqliteFixture fixture) : FiltersInheritanceQueryTestBase(fixture); +public class TPHFiltersInheritanceQuerySqliteTest(TPHFiltersInheritanceQuerySqliteFixture fixture) + : FiltersInheritanceQueryTestBase(fixture); diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/TPTFiltersInheritanceQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/TPTFiltersInheritanceQuerySqliteTest.cs index 208b7c7258a..441f5532588 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/TPTFiltersInheritanceQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/TPTFiltersInheritanceQuerySqliteTest.cs @@ -5,4 +5,5 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class TPTFiltersInheritanceQuerySqliteTest(TPTFiltersInheritanceQuerySqliteFixture fixture) : TPTFiltersInheritanceQueryTestBase(fixture); +public class TPTFiltersInheritanceQuerySqliteTest(TPTFiltersInheritanceQuerySqliteFixture fixture) + : TPTFiltersInheritanceQueryTestBase(fixture); diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/TPTGearsOfWarQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/TPTGearsOfWarQuerySqliteTest.cs index 3b05ecd09e3..bef3059af39 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/TPTGearsOfWarQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/TPTGearsOfWarQuerySqliteTest.cs @@ -414,7 +414,7 @@ public override async Task Where_DateOnly_FromDateTime_compared_to_property(bool await base.Where_DateOnly_FromDateTime_compared_to_property(async); AssertSql( -""" + """ SELECT "t"."Id" AS "TagId", "m"."Id" AS "MissionId" FROM "Tags" AS "t" CROSS JOIN "Missions" AS "m" @@ -427,7 +427,7 @@ public override async Task Where_DateOnly_FromDateTime_compared_to_constant_and_ await base.Where_DateOnly_FromDateTime_compared_to_constant_and_parameter(async); AssertSql( -""" + """ @__prm_0='10/11/0002' (DbType = Date) SELECT "t"."Id", "t"."GearNickName", "t"."GearSquadId", "t"."IssueDate", "t"."Note" diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/TPTInheritanceQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/TPTInheritanceQuerySqliteTest.cs index d7c8336ec69..beb7e8261a1 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/TPTInheritanceQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/TPTInheritanceQuerySqliteTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class TPTInheritanceQuerySqliteTest(TPTInheritanceQuerySqliteFixture fixture, ITestOutputHelper testOutputHelper) : TPTInheritanceQueryTestBase(fixture, testOutputHelper) +public class TPTInheritanceQuerySqliteTest(TPTInheritanceQuerySqliteFixture fixture, ITestOutputHelper testOutputHelper) + : TPTInheritanceQueryTestBase(fixture, testOutputHelper) { protected override void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction) => facade.UseTransaction(transaction.GetDbTransaction()); diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/TPTManyToManyNoTrackingQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/TPTManyToManyNoTrackingQuerySqliteTest.cs index ccd93dc16d2..fed2ba01166 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/TPTManyToManyNoTrackingQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/TPTManyToManyNoTrackingQuerySqliteTest.cs @@ -7,7 +7,8 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class TPTManyToManyNoTrackingQuerySqliteTest(TPTManyToManyQuerySqliteFixture fixture) : TPTManyToManyNoTrackingQueryRelationalTestBase(fixture) +public class TPTManyToManyNoTrackingQuerySqliteTest(TPTManyToManyQuerySqliteFixture fixture) + : TPTManyToManyNoTrackingQueryRelationalTestBase(fixture) { public override async Task Skip_navigation_order_by_single_or_default(bool async) => Assert.Equal( diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/TPTManyToManyQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/TPTManyToManyQuerySqliteTest.cs index bf85cb75e25..78a619f8dfa 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/TPTManyToManyQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/TPTManyToManyQuerySqliteTest.cs @@ -7,7 +7,8 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class TPTManyToManyQuerySqliteTest(TPTManyToManyQuerySqliteFixture fixture) : TPTManyToManyQueryRelationalTestBase(fixture) +public class TPTManyToManyQuerySqliteTest(TPTManyToManyQuerySqliteFixture fixture) + : TPTManyToManyQueryRelationalTestBase(fixture) { public override async Task Skip_navigation_order_by_single_or_default(bool async) => Assert.Equal( diff --git a/test/EFCore.Sqlite.FunctionalTests/QueryExpressionInterceptionSqliteTestBase.cs b/test/EFCore.Sqlite.FunctionalTests/QueryExpressionInterceptionSqliteTestBase.cs index 4338cba3ca1..dd91b2f023b 100644 --- a/test/EFCore.Sqlite.FunctionalTests/QueryExpressionInterceptionSqliteTestBase.cs +++ b/test/EFCore.Sqlite.FunctionalTests/QueryExpressionInterceptionSqliteTestBase.cs @@ -33,7 +33,8 @@ protected override bool ShouldSubscribeToDiagnosticListener } } - public class QueryExpressionInterceptionWithDiagnosticsSqliteTest(QueryExpressionInterceptionWithDiagnosticsSqliteTest.InterceptionSqliteFixture fixture) + public class QueryExpressionInterceptionWithDiagnosticsSqliteTest( + QueryExpressionInterceptionWithDiagnosticsSqliteTest.InterceptionSqliteFixture fixture) : QueryExpressionInterceptionSqliteTestBase(fixture), IClassFixture { diff --git a/test/EFCore.Sqlite.FunctionalTests/SaveChangesInterceptionSqliteTestBase.cs b/test/EFCore.Sqlite.FunctionalTests/SaveChangesInterceptionSqliteTestBase.cs index b6d547e3e1c..23caea566db 100644 --- a/test/EFCore.Sqlite.FunctionalTests/SaveChangesInterceptionSqliteTestBase.cs +++ b/test/EFCore.Sqlite.FunctionalTests/SaveChangesInterceptionSqliteTestBase.cs @@ -32,7 +32,8 @@ protected override bool ShouldSubscribeToDiagnosticListener } } - public class SaveChangesInterceptionWithDiagnosticsSqliteTest(SaveChangesInterceptionWithDiagnosticsSqliteTest.InterceptionSqliteFixture fixture) + public class SaveChangesInterceptionWithDiagnosticsSqliteTest( + SaveChangesInterceptionWithDiagnosticsSqliteTest.InterceptionSqliteFixture fixture) : SaveChangesInterceptionSqliteTestBase(fixture), IClassFixture { diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/DataEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/DataEntityType.cs index 8d744e4fa5b..696109a79b5 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/DataEntityType.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/DataEntityType.cs @@ -134,9 +134,9 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var blob = runtimeEntityType.FindProperty("Blob")!; - var point = runtimeEntityType.FindProperty("Point")!; + var id = runtimeEntityType.FindProperty("Id"); + var blob = runtimeEntityType.FindProperty("Blob"); + var point = runtimeEntityType.FindProperty("Point"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/DependentBaseEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/DependentBaseEntityType.cs index c9b0612784f..6d4b258a858 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/DependentBaseEntityType.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/DependentBaseEntityType.cs @@ -176,8 +176,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas byte (byte v) => v), mappingInfo: new RelationalTypeMappingInfo( storeTypeName: "INTEGER")); - id.SetValueComparer(new NullableValueComparer(id.TypeMapping.Comparer)); - id.SetKeyValueComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); + id.SetComparer(new NullableValueComparer(id.TypeMapping.Comparer)); + id.SetKeyComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); var key = runtimeEntityType.AddKey( new[] { principalId, principalAlternateId }); @@ -274,14 +274,14 @@ public static RuntimeForeignKey CreateForeignKey2(RuntimeEntityType declaringEnt public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var principalId = runtimeEntityType.FindProperty("PrincipalId")!; - var principalAlternateId = runtimeEntityType.FindProperty("PrincipalAlternateId")!; - var enumDiscriminator = runtimeEntityType.FindProperty("EnumDiscriminator")!; - var id = runtimeEntityType.FindProperty("Id")!; + var principalId = runtimeEntityType.FindProperty("PrincipalId"); + var principalAlternateId = runtimeEntityType.FindProperty("PrincipalAlternateId"); + var enumDiscriminator = runtimeEntityType.FindProperty("EnumDiscriminator"); + var id = runtimeEntityType.FindProperty("Id"); var key = runtimeEntityType.FindKey(new[] { principalId, principalAlternateId }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateCompositeFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory>(key)); - var principal = runtimeEntityType.FindNavigation("Principal")!; + var principal = runtimeEntityType.FindNavigation("Principal"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/DependentDerivedEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/DependentDerivedEntityType.cs index 1c44b3fa269..20abdabdfbd 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/DependentDerivedEntityType.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/DependentDerivedEntityType.cs @@ -86,13 +86,13 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var principalId = runtimeEntityType.FindProperty("PrincipalId")!; - var principalAlternateId = runtimeEntityType.FindProperty("PrincipalAlternateId")!; - var enumDiscriminator = runtimeEntityType.FindProperty("EnumDiscriminator")!; - var id = runtimeEntityType.FindProperty("Id")!; - var data = runtimeEntityType.FindProperty("Data")!; - var money = runtimeEntityType.FindProperty("Money")!; - var principal = runtimeEntityType.FindNavigation("Principal")!; + var principalId = runtimeEntityType.FindProperty("PrincipalId"); + var principalAlternateId = runtimeEntityType.FindProperty("PrincipalAlternateId"); + var enumDiscriminator = runtimeEntityType.FindProperty("EnumDiscriminator"); + var id = runtimeEntityType.FindProperty("Id"); + var data = runtimeEntityType.FindProperty("Data"); + var money = runtimeEntityType.FindProperty("Money"); + var principal = runtimeEntityType.FindNavigation("Principal"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/ManyTypesEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/ManyTypesEntityType.cs index b126fa0b69b..af1a40407f3 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/ManyTypesEntityType.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/ManyTypesEntityType.cs @@ -5958,8 +5958,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (bool v) => v), mappingInfo: new RelationalTypeMappingInfo( storeTypeName: "INTEGER")); - nullableBool.SetValueComparer(new NullableValueComparer(nullableBool.TypeMapping.Comparer)); - nullableBool.SetKeyValueComparer(new NullableValueComparer(nullableBool.TypeMapping.KeyComparer)); + nullableBool.SetComparer(new NullableValueComparer(nullableBool.TypeMapping.Comparer)); + nullableBool.SetKeyComparer(new NullableValueComparer(nullableBool.TypeMapping.KeyComparer)); var nullableBoolArray = runtimeEntityType.AddProperty( "NullableBoolArray", @@ -6160,8 +6160,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas char (char v) => v), mappingInfo: new RelationalTypeMappingInfo( storeTypeName: "TEXT")); - nullableChar.SetValueComparer(new NullableValueComparer(nullableChar.TypeMapping.Comparer)); - nullableChar.SetKeyValueComparer(new NullableValueComparer(nullableChar.TypeMapping.KeyComparer)); + nullableChar.SetComparer(new NullableValueComparer(nullableChar.TypeMapping.Comparer)); + nullableChar.SetKeyComparer(new NullableValueComparer(nullableChar.TypeMapping.KeyComparer)); var nullableCharArray = runtimeEntityType.AddProperty( "NullableCharArray", @@ -6250,8 +6250,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas relationshipIndex: -1, storeGenerationIndex: -1); nullableDateOnly.TypeMapping = SqliteDateOnlyTypeMapping.Default; - nullableDateOnly.SetValueComparer(new NullableValueComparer(nullableDateOnly.TypeMapping.Comparer)); - nullableDateOnly.SetKeyValueComparer(new NullableValueComparer(nullableDateOnly.TypeMapping.KeyComparer)); + nullableDateOnly.SetComparer(new NullableValueComparer(nullableDateOnly.TypeMapping.Comparer)); + nullableDateOnly.SetKeyComparer(new NullableValueComparer(nullableDateOnly.TypeMapping.KeyComparer)); var nullableDateOnlyArray = runtimeEntityType.AddProperty( "NullableDateOnlyArray", @@ -6326,8 +6326,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas relationshipIndex: -1, storeGenerationIndex: -1); nullableDateTime.TypeMapping = SqliteDateTimeTypeMapping.Default; - nullableDateTime.SetValueComparer(new NullableValueComparer(nullableDateTime.TypeMapping.Comparer)); - nullableDateTime.SetKeyValueComparer(new NullableValueComparer(nullableDateTime.TypeMapping.KeyComparer)); + nullableDateTime.SetComparer(new NullableValueComparer(nullableDateTime.TypeMapping.Comparer)); + nullableDateTime.SetKeyComparer(new NullableValueComparer(nullableDateTime.TypeMapping.KeyComparer)); var nullableDateTimeArray = runtimeEntityType.AddProperty( "NullableDateTimeArray", @@ -6402,8 +6402,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas relationshipIndex: -1, storeGenerationIndex: -1); nullableDecimal.TypeMapping = SqliteDecimalTypeMapping.Default; - nullableDecimal.SetValueComparer(new NullableValueComparer(nullableDecimal.TypeMapping.Comparer)); - nullableDecimal.SetKeyValueComparer(new NullableValueComparer(nullableDecimal.TypeMapping.KeyComparer)); + nullableDecimal.SetComparer(new NullableValueComparer(nullableDecimal.TypeMapping.Comparer)); + nullableDecimal.SetKeyComparer(new NullableValueComparer(nullableDecimal.TypeMapping.KeyComparer)); var nullableDecimalArray = runtimeEntityType.AddProperty( "NullableDecimalArray", @@ -6492,8 +6492,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas double (double v) => v), mappingInfo: new RelationalTypeMappingInfo( storeTypeName: "REAL")); - nullableDouble.SetValueComparer(new NullableValueComparer(nullableDouble.TypeMapping.Comparer)); - nullableDouble.SetKeyValueComparer(new NullableValueComparer(nullableDouble.TypeMapping.KeyComparer)); + nullableDouble.SetComparer(new NullableValueComparer(nullableDouble.TypeMapping.Comparer)); + nullableDouble.SetKeyComparer(new NullableValueComparer(nullableDouble.TypeMapping.KeyComparer)); var nullableDoubleArray = runtimeEntityType.AddProperty( "NullableDoubleArray", @@ -6604,8 +6604,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( short (CompiledModelTestBase.Enum16 value) => ((short)(value)), CompiledModelTestBase.Enum16 (short value) => ((CompiledModelTestBase.Enum16)(value))))); - nullableEnum16.SetValueComparer(new NullableValueComparer(nullableEnum16.TypeMapping.Comparer)); - nullableEnum16.SetKeyValueComparer(new NullableValueComparer(nullableEnum16.TypeMapping.KeyComparer)); + nullableEnum16.SetComparer(new NullableValueComparer(nullableEnum16.TypeMapping.Comparer)); + nullableEnum16.SetKeyComparer(new NullableValueComparer(nullableEnum16.TypeMapping.KeyComparer)); var nullableEnum16Array = runtimeEntityType.AddProperty( "NullableEnum16Array", @@ -6732,8 +6732,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( short (CompiledModelTestBase.Enum16 value) => ((short)(value)), CompiledModelTestBase.Enum16 (short value) => ((CompiledModelTestBase.Enum16)(value))))); - nullableEnum16AsString.SetValueComparer(new NullableValueComparer(nullableEnum16AsString.TypeMapping.Comparer)); - nullableEnum16AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnum16AsString.TypeMapping.KeyComparer)); + nullableEnum16AsString.SetComparer(new NullableValueComparer(nullableEnum16AsString.TypeMapping.Comparer)); + nullableEnum16AsString.SetKeyComparer(new NullableValueComparer(nullableEnum16AsString.TypeMapping.KeyComparer)); var nullableEnum16AsStringArray = runtimeEntityType.AddProperty( "NullableEnum16AsStringArray", @@ -7010,8 +7010,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( int (CompiledModelTestBase.Enum32 value) => ((int)(value)), CompiledModelTestBase.Enum32 (int value) => ((CompiledModelTestBase.Enum32)(value))))); - nullableEnum32.SetValueComparer(new NullableValueComparer(nullableEnum32.TypeMapping.Comparer)); - nullableEnum32.SetKeyValueComparer(new NullableValueComparer(nullableEnum32.TypeMapping.KeyComparer)); + nullableEnum32.SetComparer(new NullableValueComparer(nullableEnum32.TypeMapping.Comparer)); + nullableEnum32.SetKeyComparer(new NullableValueComparer(nullableEnum32.TypeMapping.KeyComparer)); var nullableEnum32Array = runtimeEntityType.AddProperty( "NullableEnum32Array", @@ -7138,8 +7138,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( int (CompiledModelTestBase.Enum32 value) => ((int)(value)), CompiledModelTestBase.Enum32 (int value) => ((CompiledModelTestBase.Enum32)(value))))); - nullableEnum32AsString.SetValueComparer(new NullableValueComparer(nullableEnum32AsString.TypeMapping.Comparer)); - nullableEnum32AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnum32AsString.TypeMapping.KeyComparer)); + nullableEnum32AsString.SetComparer(new NullableValueComparer(nullableEnum32AsString.TypeMapping.Comparer)); + nullableEnum32AsString.SetKeyComparer(new NullableValueComparer(nullableEnum32AsString.TypeMapping.KeyComparer)); var nullableEnum32AsStringArray = runtimeEntityType.AddProperty( "NullableEnum32AsStringArray", @@ -7416,8 +7416,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( long (CompiledModelTestBase.Enum64 value) => ((long)(value)), CompiledModelTestBase.Enum64 (long value) => ((CompiledModelTestBase.Enum64)(value))))); - nullableEnum64.SetValueComparer(new NullableValueComparer(nullableEnum64.TypeMapping.Comparer)); - nullableEnum64.SetKeyValueComparer(new NullableValueComparer(nullableEnum64.TypeMapping.KeyComparer)); + nullableEnum64.SetComparer(new NullableValueComparer(nullableEnum64.TypeMapping.Comparer)); + nullableEnum64.SetKeyComparer(new NullableValueComparer(nullableEnum64.TypeMapping.KeyComparer)); var nullableEnum64Array = runtimeEntityType.AddProperty( "NullableEnum64Array", @@ -7544,8 +7544,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( long (CompiledModelTestBase.Enum64 value) => ((long)(value)), CompiledModelTestBase.Enum64 (long value) => ((CompiledModelTestBase.Enum64)(value))))); - nullableEnum64AsString.SetValueComparer(new NullableValueComparer(nullableEnum64AsString.TypeMapping.Comparer)); - nullableEnum64AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnum64AsString.TypeMapping.KeyComparer)); + nullableEnum64AsString.SetComparer(new NullableValueComparer(nullableEnum64AsString.TypeMapping.Comparer)); + nullableEnum64AsString.SetKeyComparer(new NullableValueComparer(nullableEnum64AsString.TypeMapping.KeyComparer)); var nullableEnum64AsStringArray = runtimeEntityType.AddProperty( "NullableEnum64AsStringArray", @@ -7822,8 +7822,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( sbyte (CompiledModelTestBase.Enum8 value) => ((sbyte)(value)), CompiledModelTestBase.Enum8 (sbyte value) => ((CompiledModelTestBase.Enum8)(value))))); - nullableEnum8.SetValueComparer(new NullableValueComparer(nullableEnum8.TypeMapping.Comparer)); - nullableEnum8.SetKeyValueComparer(new NullableValueComparer(nullableEnum8.TypeMapping.KeyComparer)); + nullableEnum8.SetComparer(new NullableValueComparer(nullableEnum8.TypeMapping.Comparer)); + nullableEnum8.SetKeyComparer(new NullableValueComparer(nullableEnum8.TypeMapping.KeyComparer)); var nullableEnum8Array = runtimeEntityType.AddProperty( "NullableEnum8Array", @@ -7950,8 +7950,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( sbyte (CompiledModelTestBase.Enum8 value) => ((sbyte)(value)), CompiledModelTestBase.Enum8 (sbyte value) => ((CompiledModelTestBase.Enum8)(value))))); - nullableEnum8AsString.SetValueComparer(new NullableValueComparer(nullableEnum8AsString.TypeMapping.Comparer)); - nullableEnum8AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnum8AsString.TypeMapping.KeyComparer)); + nullableEnum8AsString.SetComparer(new NullableValueComparer(nullableEnum8AsString.TypeMapping.Comparer)); + nullableEnum8AsString.SetKeyComparer(new NullableValueComparer(nullableEnum8AsString.TypeMapping.KeyComparer)); var nullableEnum8AsStringArray = runtimeEntityType.AddProperty( "NullableEnum8AsStringArray", @@ -8228,8 +8228,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( ushort (CompiledModelTestBase.EnumU16 value) => ((ushort)(value)), CompiledModelTestBase.EnumU16 (ushort value) => ((CompiledModelTestBase.EnumU16)(value))))); - nullableEnumU16.SetValueComparer(new NullableValueComparer(nullableEnumU16.TypeMapping.Comparer)); - nullableEnumU16.SetKeyValueComparer(new NullableValueComparer(nullableEnumU16.TypeMapping.KeyComparer)); + nullableEnumU16.SetComparer(new NullableValueComparer(nullableEnumU16.TypeMapping.Comparer)); + nullableEnumU16.SetKeyComparer(new NullableValueComparer(nullableEnumU16.TypeMapping.KeyComparer)); var nullableEnumU16Array = runtimeEntityType.AddProperty( "NullableEnumU16Array", @@ -8356,8 +8356,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( ushort (CompiledModelTestBase.EnumU16 value) => ((ushort)(value)), CompiledModelTestBase.EnumU16 (ushort value) => ((CompiledModelTestBase.EnumU16)(value))))); - nullableEnumU16AsString.SetValueComparer(new NullableValueComparer(nullableEnumU16AsString.TypeMapping.Comparer)); - nullableEnumU16AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnumU16AsString.TypeMapping.KeyComparer)); + nullableEnumU16AsString.SetComparer(new NullableValueComparer(nullableEnumU16AsString.TypeMapping.Comparer)); + nullableEnumU16AsString.SetKeyComparer(new NullableValueComparer(nullableEnumU16AsString.TypeMapping.KeyComparer)); var nullableEnumU16AsStringArray = runtimeEntityType.AddProperty( "NullableEnumU16AsStringArray", @@ -8634,8 +8634,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( uint (CompiledModelTestBase.EnumU32 value) => ((uint)(value)), CompiledModelTestBase.EnumU32 (uint value) => ((CompiledModelTestBase.EnumU32)(value))))); - nullableEnumU32.SetValueComparer(new NullableValueComparer(nullableEnumU32.TypeMapping.Comparer)); - nullableEnumU32.SetKeyValueComparer(new NullableValueComparer(nullableEnumU32.TypeMapping.KeyComparer)); + nullableEnumU32.SetComparer(new NullableValueComparer(nullableEnumU32.TypeMapping.Comparer)); + nullableEnumU32.SetKeyComparer(new NullableValueComparer(nullableEnumU32.TypeMapping.KeyComparer)); var nullableEnumU32Array = runtimeEntityType.AddProperty( "NullableEnumU32Array", @@ -8762,8 +8762,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( uint (CompiledModelTestBase.EnumU32 value) => ((uint)(value)), CompiledModelTestBase.EnumU32 (uint value) => ((CompiledModelTestBase.EnumU32)(value))))); - nullableEnumU32AsString.SetValueComparer(new NullableValueComparer(nullableEnumU32AsString.TypeMapping.Comparer)); - nullableEnumU32AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnumU32AsString.TypeMapping.KeyComparer)); + nullableEnumU32AsString.SetComparer(new NullableValueComparer(nullableEnumU32AsString.TypeMapping.Comparer)); + nullableEnumU32AsString.SetKeyComparer(new NullableValueComparer(nullableEnumU32AsString.TypeMapping.KeyComparer)); var nullableEnumU32AsStringArray = runtimeEntityType.AddProperty( "NullableEnumU32AsStringArray", @@ -9038,8 +9038,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( ulong (CompiledModelTestBase.EnumU64 value) => ((ulong)(value)), CompiledModelTestBase.EnumU64 (ulong value) => ((CompiledModelTestBase.EnumU64)(value))))); - nullableEnumU64.SetValueComparer(new NullableValueComparer(nullableEnumU64.TypeMapping.Comparer)); - nullableEnumU64.SetKeyValueComparer(new NullableValueComparer(nullableEnumU64.TypeMapping.KeyComparer)); + nullableEnumU64.SetComparer(new NullableValueComparer(nullableEnumU64.TypeMapping.Comparer)); + nullableEnumU64.SetKeyComparer(new NullableValueComparer(nullableEnumU64.TypeMapping.KeyComparer)); var nullableEnumU64Array = runtimeEntityType.AddProperty( "NullableEnumU64Array", @@ -9162,8 +9162,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( ulong (CompiledModelTestBase.EnumU64 value) => ((ulong)(value)), CompiledModelTestBase.EnumU64 (ulong value) => ((CompiledModelTestBase.EnumU64)(value))))); - nullableEnumU64AsString.SetValueComparer(new NullableValueComparer(nullableEnumU64AsString.TypeMapping.Comparer)); - nullableEnumU64AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnumU64AsString.TypeMapping.KeyComparer)); + nullableEnumU64AsString.SetComparer(new NullableValueComparer(nullableEnumU64AsString.TypeMapping.Comparer)); + nullableEnumU64AsString.SetKeyComparer(new NullableValueComparer(nullableEnumU64AsString.TypeMapping.KeyComparer)); var nullableEnumU64AsStringArray = runtimeEntityType.AddProperty( "NullableEnumU64AsStringArray", @@ -9434,8 +9434,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( byte (CompiledModelTestBase.EnumU8 value) => ((byte)(value)), CompiledModelTestBase.EnumU8 (byte value) => ((CompiledModelTestBase.EnumU8)(value))))); - nullableEnumU8.SetValueComparer(new NullableValueComparer(nullableEnumU8.TypeMapping.Comparer)); - nullableEnumU8.SetKeyValueComparer(new NullableValueComparer(nullableEnumU8.TypeMapping.KeyComparer)); + nullableEnumU8.SetComparer(new NullableValueComparer(nullableEnumU8.TypeMapping.Comparer)); + nullableEnumU8.SetKeyComparer(new NullableValueComparer(nullableEnumU8.TypeMapping.KeyComparer)); var nullableEnumU8Array = runtimeEntityType.AddProperty( "NullableEnumU8Array", @@ -9562,8 +9562,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( byte (CompiledModelTestBase.EnumU8 value) => ((byte)(value)), CompiledModelTestBase.EnumU8 (byte value) => ((CompiledModelTestBase.EnumU8)(value))))); - nullableEnumU8AsString.SetValueComparer(new NullableValueComparer(nullableEnumU8AsString.TypeMapping.Comparer)); - nullableEnumU8AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnumU8AsString.TypeMapping.KeyComparer)); + nullableEnumU8AsString.SetComparer(new NullableValueComparer(nullableEnumU8AsString.TypeMapping.Comparer)); + nullableEnumU8AsString.SetKeyComparer(new NullableValueComparer(nullableEnumU8AsString.TypeMapping.KeyComparer)); var nullableEnumU8AsStringArray = runtimeEntityType.AddProperty( "NullableEnumU8AsStringArray", @@ -9832,8 +9832,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas float (float v) => v), mappingInfo: new RelationalTypeMappingInfo( storeTypeName: "REAL")); - nullableFloat.SetValueComparer(new NullableValueComparer(nullableFloat.TypeMapping.Comparer)); - nullableFloat.SetKeyValueComparer(new NullableValueComparer(nullableFloat.TypeMapping.KeyComparer)); + nullableFloat.SetComparer(new NullableValueComparer(nullableFloat.TypeMapping.Comparer)); + nullableFloat.SetKeyComparer(new NullableValueComparer(nullableFloat.TypeMapping.KeyComparer)); var nullableFloatArray = runtimeEntityType.AddProperty( "NullableFloatArray", @@ -9922,8 +9922,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas relationshipIndex: -1, storeGenerationIndex: -1); nullableGuid.TypeMapping = SqliteGuidTypeMapping.Default; - nullableGuid.SetValueComparer(new NullableValueComparer(nullableGuid.TypeMapping.Comparer)); - nullableGuid.SetKeyValueComparer(new NullableValueComparer(nullableGuid.TypeMapping.KeyComparer)); + nullableGuid.SetComparer(new NullableValueComparer(nullableGuid.TypeMapping.Comparer)); + nullableGuid.SetKeyComparer(new NullableValueComparer(nullableGuid.TypeMapping.KeyComparer)); var nullableGuidArray = runtimeEntityType.AddProperty( "NullableGuidArray", @@ -10138,8 +10138,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas short (short v) => v), mappingInfo: new RelationalTypeMappingInfo( storeTypeName: "INTEGER")); - nullableInt16.SetValueComparer(new NullableValueComparer(nullableInt16.TypeMapping.Comparer)); - nullableInt16.SetKeyValueComparer(new NullableValueComparer(nullableInt16.TypeMapping.KeyComparer)); + nullableInt16.SetComparer(new NullableValueComparer(nullableInt16.TypeMapping.Comparer)); + nullableInt16.SetKeyComparer(new NullableValueComparer(nullableInt16.TypeMapping.KeyComparer)); var nullableInt16Array = runtimeEntityType.AddProperty( "NullableInt16Array", @@ -10242,8 +10242,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas int (int v) => v), mappingInfo: new RelationalTypeMappingInfo( storeTypeName: "INTEGER")); - nullableInt32.SetValueComparer(new NullableValueComparer(nullableInt32.TypeMapping.Comparer)); - nullableInt32.SetKeyValueComparer(new NullableValueComparer(nullableInt32.TypeMapping.KeyComparer)); + nullableInt32.SetComparer(new NullableValueComparer(nullableInt32.TypeMapping.Comparer)); + nullableInt32.SetKeyComparer(new NullableValueComparer(nullableInt32.TypeMapping.KeyComparer)); var nullableInt32Array = runtimeEntityType.AddProperty( "NullableInt32Array", @@ -10346,8 +10346,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas long (long v) => v), mappingInfo: new RelationalTypeMappingInfo( storeTypeName: "INTEGER")); - nullableInt64.SetValueComparer(new NullableValueComparer(nullableInt64.TypeMapping.Comparer)); - nullableInt64.SetKeyValueComparer(new NullableValueComparer(nullableInt64.TypeMapping.KeyComparer)); + nullableInt64.SetComparer(new NullableValueComparer(nullableInt64.TypeMapping.Comparer)); + nullableInt64.SetKeyComparer(new NullableValueComparer(nullableInt64.TypeMapping.KeyComparer)); var nullableInt64Array = runtimeEntityType.AddProperty( "NullableInt64Array", @@ -10450,8 +10450,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas sbyte (sbyte v) => v), mappingInfo: new RelationalTypeMappingInfo( storeTypeName: "INTEGER")); - nullableInt8.SetValueComparer(new NullableValueComparer(nullableInt8.TypeMapping.Comparer)); - nullableInt8.SetKeyValueComparer(new NullableValueComparer(nullableInt8.TypeMapping.KeyComparer)); + nullableInt8.SetComparer(new NullableValueComparer(nullableInt8.TypeMapping.Comparer)); + nullableInt8.SetKeyComparer(new NullableValueComparer(nullableInt8.TypeMapping.KeyComparer)); var nullableInt8Array = runtimeEntityType.AddProperty( "NullableInt8Array", @@ -10740,8 +10740,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas relationshipIndex: -1, storeGenerationIndex: -1); nullableTimeOnly.TypeMapping = SqliteTimeOnlyTypeMapping.Default; - nullableTimeOnly.SetValueComparer(new NullableValueComparer(nullableTimeOnly.TypeMapping.Comparer)); - nullableTimeOnly.SetKeyValueComparer(new NullableValueComparer(nullableTimeOnly.TypeMapping.KeyComparer)); + nullableTimeOnly.SetComparer(new NullableValueComparer(nullableTimeOnly.TypeMapping.Comparer)); + nullableTimeOnly.SetKeyComparer(new NullableValueComparer(nullableTimeOnly.TypeMapping.KeyComparer)); var nullableTimeOnlyArray = runtimeEntityType.AddProperty( "NullableTimeOnlyArray", @@ -10830,8 +10830,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas TimeSpan (TimeSpan v) => v), mappingInfo: new RelationalTypeMappingInfo( storeTypeName: "TEXT")); - nullableTimeSpan.SetValueComparer(new NullableValueComparer(nullableTimeSpan.TypeMapping.Comparer)); - nullableTimeSpan.SetKeyValueComparer(new NullableValueComparer(nullableTimeSpan.TypeMapping.KeyComparer)); + nullableTimeSpan.SetComparer(new NullableValueComparer(nullableTimeSpan.TypeMapping.Comparer)); + nullableTimeSpan.SetKeyComparer(new NullableValueComparer(nullableTimeSpan.TypeMapping.KeyComparer)); var nullableTimeSpanArray = runtimeEntityType.AddProperty( "NullableTimeSpanArray", @@ -10934,8 +10934,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas ushort (ushort v) => v), mappingInfo: new RelationalTypeMappingInfo( storeTypeName: "INTEGER")); - nullableUInt16.SetValueComparer(new NullableValueComparer(nullableUInt16.TypeMapping.Comparer)); - nullableUInt16.SetKeyValueComparer(new NullableValueComparer(nullableUInt16.TypeMapping.KeyComparer)); + nullableUInt16.SetComparer(new NullableValueComparer(nullableUInt16.TypeMapping.Comparer)); + nullableUInt16.SetKeyComparer(new NullableValueComparer(nullableUInt16.TypeMapping.KeyComparer)); var nullableUInt16Array = runtimeEntityType.AddProperty( "NullableUInt16Array", @@ -11038,8 +11038,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas uint (uint v) => v), mappingInfo: new RelationalTypeMappingInfo( storeTypeName: "INTEGER")); - nullableUInt32.SetValueComparer(new NullableValueComparer(nullableUInt32.TypeMapping.Comparer)); - nullableUInt32.SetKeyValueComparer(new NullableValueComparer(nullableUInt32.TypeMapping.KeyComparer)); + nullableUInt32.SetComparer(new NullableValueComparer(nullableUInt32.TypeMapping.Comparer)); + nullableUInt32.SetKeyComparer(new NullableValueComparer(nullableUInt32.TypeMapping.KeyComparer)); var nullableUInt32Array = runtimeEntityType.AddProperty( "NullableUInt32Array", @@ -11128,8 +11128,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas relationshipIndex: -1, storeGenerationIndex: -1); nullableUInt64.TypeMapping = SqliteULongTypeMapping.Default; - nullableUInt64.SetValueComparer(new NullableValueComparer(nullableUInt64.TypeMapping.Comparer)); - nullableUInt64.SetKeyValueComparer(new NullableValueComparer(nullableUInt64.TypeMapping.KeyComparer)); + nullableUInt64.SetComparer(new NullableValueComparer(nullableUInt64.TypeMapping.Comparer)); + nullableUInt64.SetKeyComparer(new NullableValueComparer(nullableUInt64.TypeMapping.KeyComparer)); var nullableUInt64Array = runtimeEntityType.AddProperty( "NullableUInt64Array", @@ -11218,8 +11218,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas byte (byte v) => v), mappingInfo: new RelationalTypeMappingInfo( storeTypeName: "INTEGER")); - nullableUInt8.SetValueComparer(new NullableValueComparer(nullableUInt8.TypeMapping.Comparer)); - nullableUInt8.SetKeyValueComparer(new NullableValueComparer(nullableUInt8.TypeMapping.KeyComparer)); + nullableUInt8.SetComparer(new NullableValueComparer(nullableUInt8.TypeMapping.Comparer)); + nullableUInt8.SetKeyComparer(new NullableValueComparer(nullableUInt8.TypeMapping.KeyComparer)); var nullableUInt8Array = runtimeEntityType.AddProperty( "NullableUInt8Array", @@ -13317,242 +13317,242 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var @bool = runtimeEntityType.FindProperty("Bool")!; - var boolArray = runtimeEntityType.FindProperty("BoolArray")!; - var boolToStringConverterProperty = runtimeEntityType.FindProperty("BoolToStringConverterProperty")!; - var boolToTwoValuesConverterProperty = runtimeEntityType.FindProperty("BoolToTwoValuesConverterProperty")!; - var boolToZeroOneConverterProperty = runtimeEntityType.FindProperty("BoolToZeroOneConverterProperty")!; - var bytes = runtimeEntityType.FindProperty("Bytes")!; - var bytesArray = runtimeEntityType.FindProperty("BytesArray")!; - var bytesToStringConverterProperty = runtimeEntityType.FindProperty("BytesToStringConverterProperty")!; - var castingConverterProperty = runtimeEntityType.FindProperty("CastingConverterProperty")!; - var @char = runtimeEntityType.FindProperty("Char")!; - var charArray = runtimeEntityType.FindProperty("CharArray")!; - var charToStringConverterProperty = runtimeEntityType.FindProperty("CharToStringConverterProperty")!; - var dateOnly = runtimeEntityType.FindProperty("DateOnly")!; - var dateOnlyArray = runtimeEntityType.FindProperty("DateOnlyArray")!; - var dateOnlyToStringConverterProperty = runtimeEntityType.FindProperty("DateOnlyToStringConverterProperty")!; - var dateTime = runtimeEntityType.FindProperty("DateTime")!; - var dateTimeArray = runtimeEntityType.FindProperty("DateTimeArray")!; - var dateTimeOffsetToBinaryConverterProperty = runtimeEntityType.FindProperty("DateTimeOffsetToBinaryConverterProperty")!; - var dateTimeOffsetToBytesConverterProperty = runtimeEntityType.FindProperty("DateTimeOffsetToBytesConverterProperty")!; - var dateTimeOffsetToStringConverterProperty = runtimeEntityType.FindProperty("DateTimeOffsetToStringConverterProperty")!; - var dateTimeToBinaryConverterProperty = runtimeEntityType.FindProperty("DateTimeToBinaryConverterProperty")!; - var dateTimeToStringConverterProperty = runtimeEntityType.FindProperty("DateTimeToStringConverterProperty")!; - var dateTimeToTicksConverterProperty = runtimeEntityType.FindProperty("DateTimeToTicksConverterProperty")!; - var @decimal = runtimeEntityType.FindProperty("Decimal")!; - var decimalArray = runtimeEntityType.FindProperty("DecimalArray")!; - var decimalNumberToBytesConverterProperty = runtimeEntityType.FindProperty("DecimalNumberToBytesConverterProperty")!; - var decimalNumberToStringConverterProperty = runtimeEntityType.FindProperty("DecimalNumberToStringConverterProperty")!; - var @double = runtimeEntityType.FindProperty("Double")!; - var doubleArray = runtimeEntityType.FindProperty("DoubleArray")!; - var doubleNumberToBytesConverterProperty = runtimeEntityType.FindProperty("DoubleNumberToBytesConverterProperty")!; - var doubleNumberToStringConverterProperty = runtimeEntityType.FindProperty("DoubleNumberToStringConverterProperty")!; - var enum16 = runtimeEntityType.FindProperty("Enum16")!; - var enum16Array = runtimeEntityType.FindProperty("Enum16Array")!; - var enum16AsString = runtimeEntityType.FindProperty("Enum16AsString")!; - var enum16AsStringArray = runtimeEntityType.FindProperty("Enum16AsStringArray")!; - var enum16AsStringCollection = runtimeEntityType.FindProperty("Enum16AsStringCollection")!; - var enum16Collection = runtimeEntityType.FindProperty("Enum16Collection")!; - var enum32 = runtimeEntityType.FindProperty("Enum32")!; - var enum32Array = runtimeEntityType.FindProperty("Enum32Array")!; - var enum32AsString = runtimeEntityType.FindProperty("Enum32AsString")!; - var enum32AsStringArray = runtimeEntityType.FindProperty("Enum32AsStringArray")!; - var enum32AsStringCollection = runtimeEntityType.FindProperty("Enum32AsStringCollection")!; - var enum32Collection = runtimeEntityType.FindProperty("Enum32Collection")!; - var enum64 = runtimeEntityType.FindProperty("Enum64")!; - var enum64Array = runtimeEntityType.FindProperty("Enum64Array")!; - var enum64AsString = runtimeEntityType.FindProperty("Enum64AsString")!; - var enum64AsStringArray = runtimeEntityType.FindProperty("Enum64AsStringArray")!; - var enum64AsStringCollection = runtimeEntityType.FindProperty("Enum64AsStringCollection")!; - var enum64Collection = runtimeEntityType.FindProperty("Enum64Collection")!; - var enum8 = runtimeEntityType.FindProperty("Enum8")!; - var enum8Array = runtimeEntityType.FindProperty("Enum8Array")!; - var enum8AsString = runtimeEntityType.FindProperty("Enum8AsString")!; - var enum8AsStringArray = runtimeEntityType.FindProperty("Enum8AsStringArray")!; - var enum8AsStringCollection = runtimeEntityType.FindProperty("Enum8AsStringCollection")!; - var enum8Collection = runtimeEntityType.FindProperty("Enum8Collection")!; - var enumToNumberConverterProperty = runtimeEntityType.FindProperty("EnumToNumberConverterProperty")!; - var enumToStringConverterProperty = runtimeEntityType.FindProperty("EnumToStringConverterProperty")!; - var enumU16 = runtimeEntityType.FindProperty("EnumU16")!; - var enumU16Array = runtimeEntityType.FindProperty("EnumU16Array")!; - var enumU16AsString = runtimeEntityType.FindProperty("EnumU16AsString")!; - var enumU16AsStringArray = runtimeEntityType.FindProperty("EnumU16AsStringArray")!; - var enumU16AsStringCollection = runtimeEntityType.FindProperty("EnumU16AsStringCollection")!; - var enumU16Collection = runtimeEntityType.FindProperty("EnumU16Collection")!; - var enumU32 = runtimeEntityType.FindProperty("EnumU32")!; - var enumU32Array = runtimeEntityType.FindProperty("EnumU32Array")!; - var enumU32AsString = runtimeEntityType.FindProperty("EnumU32AsString")!; - var enumU32AsStringArray = runtimeEntityType.FindProperty("EnumU32AsStringArray")!; - var enumU32AsStringCollection = runtimeEntityType.FindProperty("EnumU32AsStringCollection")!; - var enumU32Collection = runtimeEntityType.FindProperty("EnumU32Collection")!; - var enumU64 = runtimeEntityType.FindProperty("EnumU64")!; - var enumU64Array = runtimeEntityType.FindProperty("EnumU64Array")!; - var enumU64AsString = runtimeEntityType.FindProperty("EnumU64AsString")!; - var enumU64AsStringArray = runtimeEntityType.FindProperty("EnumU64AsStringArray")!; - var enumU64AsStringCollection = runtimeEntityType.FindProperty("EnumU64AsStringCollection")!; - var enumU64Collection = runtimeEntityType.FindProperty("EnumU64Collection")!; - var enumU8 = runtimeEntityType.FindProperty("EnumU8")!; - var enumU8Array = runtimeEntityType.FindProperty("EnumU8Array")!; - var enumU8AsString = runtimeEntityType.FindProperty("EnumU8AsString")!; - var enumU8AsStringArray = runtimeEntityType.FindProperty("EnumU8AsStringArray")!; - var enumU8AsStringCollection = runtimeEntityType.FindProperty("EnumU8AsStringCollection")!; - var enumU8Collection = runtimeEntityType.FindProperty("EnumU8Collection")!; - var @float = runtimeEntityType.FindProperty("Float")!; - var floatArray = runtimeEntityType.FindProperty("FloatArray")!; - var guid = runtimeEntityType.FindProperty("Guid")!; - var guidArray = runtimeEntityType.FindProperty("GuidArray")!; - var guidToBytesConverterProperty = runtimeEntityType.FindProperty("GuidToBytesConverterProperty")!; - var guidToStringConverterProperty = runtimeEntityType.FindProperty("GuidToStringConverterProperty")!; - var iPAddress = runtimeEntityType.FindProperty("IPAddress")!; - var iPAddressArray = runtimeEntityType.FindProperty("IPAddressArray")!; - var iPAddressToBytesConverterProperty = runtimeEntityType.FindProperty("IPAddressToBytesConverterProperty")!; - var iPAddressToStringConverterProperty = runtimeEntityType.FindProperty("IPAddressToStringConverterProperty")!; - var int16 = runtimeEntityType.FindProperty("Int16")!; - var int16Array = runtimeEntityType.FindProperty("Int16Array")!; - var int32 = runtimeEntityType.FindProperty("Int32")!; - var int32Array = runtimeEntityType.FindProperty("Int32Array")!; - var int64 = runtimeEntityType.FindProperty("Int64")!; - var int64Array = runtimeEntityType.FindProperty("Int64Array")!; - var int8 = runtimeEntityType.FindProperty("Int8")!; - var int8Array = runtimeEntityType.FindProperty("Int8Array")!; - var intNumberToBytesConverterProperty = runtimeEntityType.FindProperty("IntNumberToBytesConverterProperty")!; - var intNumberToStringConverterProperty = runtimeEntityType.FindProperty("IntNumberToStringConverterProperty")!; - var nullIntToNullStringConverterProperty = runtimeEntityType.FindProperty("NullIntToNullStringConverterProperty")!; - var nullableBool = runtimeEntityType.FindProperty("NullableBool")!; - var nullableBoolArray = runtimeEntityType.FindProperty("NullableBoolArray")!; - var nullableBytes = runtimeEntityType.FindProperty("NullableBytes")!; - var nullableBytesArray = runtimeEntityType.FindProperty("NullableBytesArray")!; - var nullableChar = runtimeEntityType.FindProperty("NullableChar")!; - var nullableCharArray = runtimeEntityType.FindProperty("NullableCharArray")!; - var nullableDateOnly = runtimeEntityType.FindProperty("NullableDateOnly")!; - var nullableDateOnlyArray = runtimeEntityType.FindProperty("NullableDateOnlyArray")!; - var nullableDateTime = runtimeEntityType.FindProperty("NullableDateTime")!; - var nullableDateTimeArray = runtimeEntityType.FindProperty("NullableDateTimeArray")!; - var nullableDecimal = runtimeEntityType.FindProperty("NullableDecimal")!; - var nullableDecimalArray = runtimeEntityType.FindProperty("NullableDecimalArray")!; - var nullableDouble = runtimeEntityType.FindProperty("NullableDouble")!; - var nullableDoubleArray = runtimeEntityType.FindProperty("NullableDoubleArray")!; - var nullableEnum16 = runtimeEntityType.FindProperty("NullableEnum16")!; - var nullableEnum16Array = runtimeEntityType.FindProperty("NullableEnum16Array")!; - var nullableEnum16AsString = runtimeEntityType.FindProperty("NullableEnum16AsString")!; - var nullableEnum16AsStringArray = runtimeEntityType.FindProperty("NullableEnum16AsStringArray")!; - var nullableEnum16AsStringCollection = runtimeEntityType.FindProperty("NullableEnum16AsStringCollection")!; - var nullableEnum16Collection = runtimeEntityType.FindProperty("NullableEnum16Collection")!; - var nullableEnum32 = runtimeEntityType.FindProperty("NullableEnum32")!; - var nullableEnum32Array = runtimeEntityType.FindProperty("NullableEnum32Array")!; - var nullableEnum32AsString = runtimeEntityType.FindProperty("NullableEnum32AsString")!; - var nullableEnum32AsStringArray = runtimeEntityType.FindProperty("NullableEnum32AsStringArray")!; - var nullableEnum32AsStringCollection = runtimeEntityType.FindProperty("NullableEnum32AsStringCollection")!; - var nullableEnum32Collection = runtimeEntityType.FindProperty("NullableEnum32Collection")!; - var nullableEnum64 = runtimeEntityType.FindProperty("NullableEnum64")!; - var nullableEnum64Array = runtimeEntityType.FindProperty("NullableEnum64Array")!; - var nullableEnum64AsString = runtimeEntityType.FindProperty("NullableEnum64AsString")!; - var nullableEnum64AsStringArray = runtimeEntityType.FindProperty("NullableEnum64AsStringArray")!; - var nullableEnum64AsStringCollection = runtimeEntityType.FindProperty("NullableEnum64AsStringCollection")!; - var nullableEnum64Collection = runtimeEntityType.FindProperty("NullableEnum64Collection")!; - var nullableEnum8 = runtimeEntityType.FindProperty("NullableEnum8")!; - var nullableEnum8Array = runtimeEntityType.FindProperty("NullableEnum8Array")!; - var nullableEnum8AsString = runtimeEntityType.FindProperty("NullableEnum8AsString")!; - var nullableEnum8AsStringArray = runtimeEntityType.FindProperty("NullableEnum8AsStringArray")!; - var nullableEnum8AsStringCollection = runtimeEntityType.FindProperty("NullableEnum8AsStringCollection")!; - var nullableEnum8Collection = runtimeEntityType.FindProperty("NullableEnum8Collection")!; - var nullableEnumU16 = runtimeEntityType.FindProperty("NullableEnumU16")!; - var nullableEnumU16Array = runtimeEntityType.FindProperty("NullableEnumU16Array")!; - var nullableEnumU16AsString = runtimeEntityType.FindProperty("NullableEnumU16AsString")!; - var nullableEnumU16AsStringArray = runtimeEntityType.FindProperty("NullableEnumU16AsStringArray")!; - var nullableEnumU16AsStringCollection = runtimeEntityType.FindProperty("NullableEnumU16AsStringCollection")!; - var nullableEnumU16Collection = runtimeEntityType.FindProperty("NullableEnumU16Collection")!; - var nullableEnumU32 = runtimeEntityType.FindProperty("NullableEnumU32")!; - var nullableEnumU32Array = runtimeEntityType.FindProperty("NullableEnumU32Array")!; - var nullableEnumU32AsString = runtimeEntityType.FindProperty("NullableEnumU32AsString")!; - var nullableEnumU32AsStringArray = runtimeEntityType.FindProperty("NullableEnumU32AsStringArray")!; - var nullableEnumU32AsStringCollection = runtimeEntityType.FindProperty("NullableEnumU32AsStringCollection")!; - var nullableEnumU32Collection = runtimeEntityType.FindProperty("NullableEnumU32Collection")!; - var nullableEnumU64 = runtimeEntityType.FindProperty("NullableEnumU64")!; - var nullableEnumU64Array = runtimeEntityType.FindProperty("NullableEnumU64Array")!; - var nullableEnumU64AsString = runtimeEntityType.FindProperty("NullableEnumU64AsString")!; - var nullableEnumU64AsStringArray = runtimeEntityType.FindProperty("NullableEnumU64AsStringArray")!; - var nullableEnumU64AsStringCollection = runtimeEntityType.FindProperty("NullableEnumU64AsStringCollection")!; - var nullableEnumU64Collection = runtimeEntityType.FindProperty("NullableEnumU64Collection")!; - var nullableEnumU8 = runtimeEntityType.FindProperty("NullableEnumU8")!; - var nullableEnumU8Array = runtimeEntityType.FindProperty("NullableEnumU8Array")!; - var nullableEnumU8AsString = runtimeEntityType.FindProperty("NullableEnumU8AsString")!; - var nullableEnumU8AsStringArray = runtimeEntityType.FindProperty("NullableEnumU8AsStringArray")!; - var nullableEnumU8AsStringCollection = runtimeEntityType.FindProperty("NullableEnumU8AsStringCollection")!; - var nullableEnumU8Collection = runtimeEntityType.FindProperty("NullableEnumU8Collection")!; - var nullableFloat = runtimeEntityType.FindProperty("NullableFloat")!; - var nullableFloatArray = runtimeEntityType.FindProperty("NullableFloatArray")!; - var nullableGuid = runtimeEntityType.FindProperty("NullableGuid")!; - var nullableGuidArray = runtimeEntityType.FindProperty("NullableGuidArray")!; - var nullableIPAddress = runtimeEntityType.FindProperty("NullableIPAddress")!; - var nullableIPAddressArray = runtimeEntityType.FindProperty("NullableIPAddressArray")!; - var nullableInt16 = runtimeEntityType.FindProperty("NullableInt16")!; - var nullableInt16Array = runtimeEntityType.FindProperty("NullableInt16Array")!; - var nullableInt32 = runtimeEntityType.FindProperty("NullableInt32")!; - var nullableInt32Array = runtimeEntityType.FindProperty("NullableInt32Array")!; - var nullableInt64 = runtimeEntityType.FindProperty("NullableInt64")!; - var nullableInt64Array = runtimeEntityType.FindProperty("NullableInt64Array")!; - var nullableInt8 = runtimeEntityType.FindProperty("NullableInt8")!; - var nullableInt8Array = runtimeEntityType.FindProperty("NullableInt8Array")!; - var nullablePhysicalAddress = runtimeEntityType.FindProperty("NullablePhysicalAddress")!; - var nullablePhysicalAddressArray = runtimeEntityType.FindProperty("NullablePhysicalAddressArray")!; - var nullableString = runtimeEntityType.FindProperty("NullableString")!; - var nullableStringArray = runtimeEntityType.FindProperty("NullableStringArray")!; - var nullableTimeOnly = runtimeEntityType.FindProperty("NullableTimeOnly")!; - var nullableTimeOnlyArray = runtimeEntityType.FindProperty("NullableTimeOnlyArray")!; - var nullableTimeSpan = runtimeEntityType.FindProperty("NullableTimeSpan")!; - var nullableTimeSpanArray = runtimeEntityType.FindProperty("NullableTimeSpanArray")!; - var nullableUInt16 = runtimeEntityType.FindProperty("NullableUInt16")!; - var nullableUInt16Array = runtimeEntityType.FindProperty("NullableUInt16Array")!; - var nullableUInt32 = runtimeEntityType.FindProperty("NullableUInt32")!; - var nullableUInt32Array = runtimeEntityType.FindProperty("NullableUInt32Array")!; - var nullableUInt64 = runtimeEntityType.FindProperty("NullableUInt64")!; - var nullableUInt64Array = runtimeEntityType.FindProperty("NullableUInt64Array")!; - var nullableUInt8 = runtimeEntityType.FindProperty("NullableUInt8")!; - var nullableUInt8Array = runtimeEntityType.FindProperty("NullableUInt8Array")!; - var nullableUri = runtimeEntityType.FindProperty("NullableUri")!; - var nullableUriArray = runtimeEntityType.FindProperty("NullableUriArray")!; - var physicalAddress = runtimeEntityType.FindProperty("PhysicalAddress")!; - var physicalAddressArray = runtimeEntityType.FindProperty("PhysicalAddressArray")!; - var physicalAddressToBytesConverterProperty = runtimeEntityType.FindProperty("PhysicalAddressToBytesConverterProperty")!; - var physicalAddressToStringConverterProperty = runtimeEntityType.FindProperty("PhysicalAddressToStringConverterProperty")!; - var @string = runtimeEntityType.FindProperty("String")!; - var stringArray = runtimeEntityType.FindProperty("StringArray")!; - var stringToBoolConverterProperty = runtimeEntityType.FindProperty("StringToBoolConverterProperty")!; - var stringToBytesConverterProperty = runtimeEntityType.FindProperty("StringToBytesConverterProperty")!; - var stringToCharConverterProperty = runtimeEntityType.FindProperty("StringToCharConverterProperty")!; - var stringToDateOnlyConverterProperty = runtimeEntityType.FindProperty("StringToDateOnlyConverterProperty")!; - var stringToDateTimeConverterProperty = runtimeEntityType.FindProperty("StringToDateTimeConverterProperty")!; - var stringToDateTimeOffsetConverterProperty = runtimeEntityType.FindProperty("StringToDateTimeOffsetConverterProperty")!; - var stringToDecimalNumberConverterProperty = runtimeEntityType.FindProperty("StringToDecimalNumberConverterProperty")!; - var stringToDoubleNumberConverterProperty = runtimeEntityType.FindProperty("StringToDoubleNumberConverterProperty")!; - var stringToEnumConverterProperty = runtimeEntityType.FindProperty("StringToEnumConverterProperty")!; - var stringToGuidConverterProperty = runtimeEntityType.FindProperty("StringToGuidConverterProperty")!; - var stringToIntNumberConverterProperty = runtimeEntityType.FindProperty("StringToIntNumberConverterProperty")!; - var stringToTimeOnlyConverterProperty = runtimeEntityType.FindProperty("StringToTimeOnlyConverterProperty")!; - var stringToTimeSpanConverterProperty = runtimeEntityType.FindProperty("StringToTimeSpanConverterProperty")!; - var stringToUriConverterProperty = runtimeEntityType.FindProperty("StringToUriConverterProperty")!; - var timeOnly = runtimeEntityType.FindProperty("TimeOnly")!; - var timeOnlyArray = runtimeEntityType.FindProperty("TimeOnlyArray")!; - var timeOnlyToStringConverterProperty = runtimeEntityType.FindProperty("TimeOnlyToStringConverterProperty")!; - var timeOnlyToTicksConverterProperty = runtimeEntityType.FindProperty("TimeOnlyToTicksConverterProperty")!; - var timeSpan = runtimeEntityType.FindProperty("TimeSpan")!; - var timeSpanArray = runtimeEntityType.FindProperty("TimeSpanArray")!; - var timeSpanToStringConverterProperty = runtimeEntityType.FindProperty("TimeSpanToStringConverterProperty")!; - var timeSpanToTicksConverterProperty = runtimeEntityType.FindProperty("TimeSpanToTicksConverterProperty")!; - var uInt16 = runtimeEntityType.FindProperty("UInt16")!; - var uInt16Array = runtimeEntityType.FindProperty("UInt16Array")!; - var uInt32 = runtimeEntityType.FindProperty("UInt32")!; - var uInt32Array = runtimeEntityType.FindProperty("UInt32Array")!; - var uInt64 = runtimeEntityType.FindProperty("UInt64")!; - var uInt64Array = runtimeEntityType.FindProperty("UInt64Array")!; - var uInt8 = runtimeEntityType.FindProperty("UInt8")!; - var uInt8Array = runtimeEntityType.FindProperty("UInt8Array")!; - var uri = runtimeEntityType.FindProperty("Uri")!; - var uriArray = runtimeEntityType.FindProperty("UriArray")!; - var uriToStringConverterProperty = runtimeEntityType.FindProperty("UriToStringConverterProperty")!; + var id = runtimeEntityType.FindProperty("Id"); + var @bool = runtimeEntityType.FindProperty("Bool"); + var boolArray = runtimeEntityType.FindProperty("BoolArray"); + var boolToStringConverterProperty = runtimeEntityType.FindProperty("BoolToStringConverterProperty"); + var boolToTwoValuesConverterProperty = runtimeEntityType.FindProperty("BoolToTwoValuesConverterProperty"); + var boolToZeroOneConverterProperty = runtimeEntityType.FindProperty("BoolToZeroOneConverterProperty"); + var bytes = runtimeEntityType.FindProperty("Bytes"); + var bytesArray = runtimeEntityType.FindProperty("BytesArray"); + var bytesToStringConverterProperty = runtimeEntityType.FindProperty("BytesToStringConverterProperty"); + var castingConverterProperty = runtimeEntityType.FindProperty("CastingConverterProperty"); + var @char = runtimeEntityType.FindProperty("Char"); + var charArray = runtimeEntityType.FindProperty("CharArray"); + var charToStringConverterProperty = runtimeEntityType.FindProperty("CharToStringConverterProperty"); + var dateOnly = runtimeEntityType.FindProperty("DateOnly"); + var dateOnlyArray = runtimeEntityType.FindProperty("DateOnlyArray"); + var dateOnlyToStringConverterProperty = runtimeEntityType.FindProperty("DateOnlyToStringConverterProperty"); + var dateTime = runtimeEntityType.FindProperty("DateTime"); + var dateTimeArray = runtimeEntityType.FindProperty("DateTimeArray"); + var dateTimeOffsetToBinaryConverterProperty = runtimeEntityType.FindProperty("DateTimeOffsetToBinaryConverterProperty"); + var dateTimeOffsetToBytesConverterProperty = runtimeEntityType.FindProperty("DateTimeOffsetToBytesConverterProperty"); + var dateTimeOffsetToStringConverterProperty = runtimeEntityType.FindProperty("DateTimeOffsetToStringConverterProperty"); + var dateTimeToBinaryConverterProperty = runtimeEntityType.FindProperty("DateTimeToBinaryConverterProperty"); + var dateTimeToStringConverterProperty = runtimeEntityType.FindProperty("DateTimeToStringConverterProperty"); + var dateTimeToTicksConverterProperty = runtimeEntityType.FindProperty("DateTimeToTicksConverterProperty"); + var @decimal = runtimeEntityType.FindProperty("Decimal"); + var decimalArray = runtimeEntityType.FindProperty("DecimalArray"); + var decimalNumberToBytesConverterProperty = runtimeEntityType.FindProperty("DecimalNumberToBytesConverterProperty"); + var decimalNumberToStringConverterProperty = runtimeEntityType.FindProperty("DecimalNumberToStringConverterProperty"); + var @double = runtimeEntityType.FindProperty("Double"); + var doubleArray = runtimeEntityType.FindProperty("DoubleArray"); + var doubleNumberToBytesConverterProperty = runtimeEntityType.FindProperty("DoubleNumberToBytesConverterProperty"); + var doubleNumberToStringConverterProperty = runtimeEntityType.FindProperty("DoubleNumberToStringConverterProperty"); + var enum16 = runtimeEntityType.FindProperty("Enum16"); + var enum16Array = runtimeEntityType.FindProperty("Enum16Array"); + var enum16AsString = runtimeEntityType.FindProperty("Enum16AsString"); + var enum16AsStringArray = runtimeEntityType.FindProperty("Enum16AsStringArray"); + var enum16AsStringCollection = runtimeEntityType.FindProperty("Enum16AsStringCollection"); + var enum16Collection = runtimeEntityType.FindProperty("Enum16Collection"); + var enum32 = runtimeEntityType.FindProperty("Enum32"); + var enum32Array = runtimeEntityType.FindProperty("Enum32Array"); + var enum32AsString = runtimeEntityType.FindProperty("Enum32AsString"); + var enum32AsStringArray = runtimeEntityType.FindProperty("Enum32AsStringArray"); + var enum32AsStringCollection = runtimeEntityType.FindProperty("Enum32AsStringCollection"); + var enum32Collection = runtimeEntityType.FindProperty("Enum32Collection"); + var enum64 = runtimeEntityType.FindProperty("Enum64"); + var enum64Array = runtimeEntityType.FindProperty("Enum64Array"); + var enum64AsString = runtimeEntityType.FindProperty("Enum64AsString"); + var enum64AsStringArray = runtimeEntityType.FindProperty("Enum64AsStringArray"); + var enum64AsStringCollection = runtimeEntityType.FindProperty("Enum64AsStringCollection"); + var enum64Collection = runtimeEntityType.FindProperty("Enum64Collection"); + var enum8 = runtimeEntityType.FindProperty("Enum8"); + var enum8Array = runtimeEntityType.FindProperty("Enum8Array"); + var enum8AsString = runtimeEntityType.FindProperty("Enum8AsString"); + var enum8AsStringArray = runtimeEntityType.FindProperty("Enum8AsStringArray"); + var enum8AsStringCollection = runtimeEntityType.FindProperty("Enum8AsStringCollection"); + var enum8Collection = runtimeEntityType.FindProperty("Enum8Collection"); + var enumToNumberConverterProperty = runtimeEntityType.FindProperty("EnumToNumberConverterProperty"); + var enumToStringConverterProperty = runtimeEntityType.FindProperty("EnumToStringConverterProperty"); + var enumU16 = runtimeEntityType.FindProperty("EnumU16"); + var enumU16Array = runtimeEntityType.FindProperty("EnumU16Array"); + var enumU16AsString = runtimeEntityType.FindProperty("EnumU16AsString"); + var enumU16AsStringArray = runtimeEntityType.FindProperty("EnumU16AsStringArray"); + var enumU16AsStringCollection = runtimeEntityType.FindProperty("EnumU16AsStringCollection"); + var enumU16Collection = runtimeEntityType.FindProperty("EnumU16Collection"); + var enumU32 = runtimeEntityType.FindProperty("EnumU32"); + var enumU32Array = runtimeEntityType.FindProperty("EnumU32Array"); + var enumU32AsString = runtimeEntityType.FindProperty("EnumU32AsString"); + var enumU32AsStringArray = runtimeEntityType.FindProperty("EnumU32AsStringArray"); + var enumU32AsStringCollection = runtimeEntityType.FindProperty("EnumU32AsStringCollection"); + var enumU32Collection = runtimeEntityType.FindProperty("EnumU32Collection"); + var enumU64 = runtimeEntityType.FindProperty("EnumU64"); + var enumU64Array = runtimeEntityType.FindProperty("EnumU64Array"); + var enumU64AsString = runtimeEntityType.FindProperty("EnumU64AsString"); + var enumU64AsStringArray = runtimeEntityType.FindProperty("EnumU64AsStringArray"); + var enumU64AsStringCollection = runtimeEntityType.FindProperty("EnumU64AsStringCollection"); + var enumU64Collection = runtimeEntityType.FindProperty("EnumU64Collection"); + var enumU8 = runtimeEntityType.FindProperty("EnumU8"); + var enumU8Array = runtimeEntityType.FindProperty("EnumU8Array"); + var enumU8AsString = runtimeEntityType.FindProperty("EnumU8AsString"); + var enumU8AsStringArray = runtimeEntityType.FindProperty("EnumU8AsStringArray"); + var enumU8AsStringCollection = runtimeEntityType.FindProperty("EnumU8AsStringCollection"); + var enumU8Collection = runtimeEntityType.FindProperty("EnumU8Collection"); + var @float = runtimeEntityType.FindProperty("Float"); + var floatArray = runtimeEntityType.FindProperty("FloatArray"); + var guid = runtimeEntityType.FindProperty("Guid"); + var guidArray = runtimeEntityType.FindProperty("GuidArray"); + var guidToBytesConverterProperty = runtimeEntityType.FindProperty("GuidToBytesConverterProperty"); + var guidToStringConverterProperty = runtimeEntityType.FindProperty("GuidToStringConverterProperty"); + var iPAddress = runtimeEntityType.FindProperty("IPAddress"); + var iPAddressArray = runtimeEntityType.FindProperty("IPAddressArray"); + var iPAddressToBytesConverterProperty = runtimeEntityType.FindProperty("IPAddressToBytesConverterProperty"); + var iPAddressToStringConverterProperty = runtimeEntityType.FindProperty("IPAddressToStringConverterProperty"); + var int16 = runtimeEntityType.FindProperty("Int16"); + var int16Array = runtimeEntityType.FindProperty("Int16Array"); + var int32 = runtimeEntityType.FindProperty("Int32"); + var int32Array = runtimeEntityType.FindProperty("Int32Array"); + var int64 = runtimeEntityType.FindProperty("Int64"); + var int64Array = runtimeEntityType.FindProperty("Int64Array"); + var int8 = runtimeEntityType.FindProperty("Int8"); + var int8Array = runtimeEntityType.FindProperty("Int8Array"); + var intNumberToBytesConverterProperty = runtimeEntityType.FindProperty("IntNumberToBytesConverterProperty"); + var intNumberToStringConverterProperty = runtimeEntityType.FindProperty("IntNumberToStringConverterProperty"); + var nullIntToNullStringConverterProperty = runtimeEntityType.FindProperty("NullIntToNullStringConverterProperty"); + var nullableBool = runtimeEntityType.FindProperty("NullableBool"); + var nullableBoolArray = runtimeEntityType.FindProperty("NullableBoolArray"); + var nullableBytes = runtimeEntityType.FindProperty("NullableBytes"); + var nullableBytesArray = runtimeEntityType.FindProperty("NullableBytesArray"); + var nullableChar = runtimeEntityType.FindProperty("NullableChar"); + var nullableCharArray = runtimeEntityType.FindProperty("NullableCharArray"); + var nullableDateOnly = runtimeEntityType.FindProperty("NullableDateOnly"); + var nullableDateOnlyArray = runtimeEntityType.FindProperty("NullableDateOnlyArray"); + var nullableDateTime = runtimeEntityType.FindProperty("NullableDateTime"); + var nullableDateTimeArray = runtimeEntityType.FindProperty("NullableDateTimeArray"); + var nullableDecimal = runtimeEntityType.FindProperty("NullableDecimal"); + var nullableDecimalArray = runtimeEntityType.FindProperty("NullableDecimalArray"); + var nullableDouble = runtimeEntityType.FindProperty("NullableDouble"); + var nullableDoubleArray = runtimeEntityType.FindProperty("NullableDoubleArray"); + var nullableEnum16 = runtimeEntityType.FindProperty("NullableEnum16"); + var nullableEnum16Array = runtimeEntityType.FindProperty("NullableEnum16Array"); + var nullableEnum16AsString = runtimeEntityType.FindProperty("NullableEnum16AsString"); + var nullableEnum16AsStringArray = runtimeEntityType.FindProperty("NullableEnum16AsStringArray"); + var nullableEnum16AsStringCollection = runtimeEntityType.FindProperty("NullableEnum16AsStringCollection"); + var nullableEnum16Collection = runtimeEntityType.FindProperty("NullableEnum16Collection"); + var nullableEnum32 = runtimeEntityType.FindProperty("NullableEnum32"); + var nullableEnum32Array = runtimeEntityType.FindProperty("NullableEnum32Array"); + var nullableEnum32AsString = runtimeEntityType.FindProperty("NullableEnum32AsString"); + var nullableEnum32AsStringArray = runtimeEntityType.FindProperty("NullableEnum32AsStringArray"); + var nullableEnum32AsStringCollection = runtimeEntityType.FindProperty("NullableEnum32AsStringCollection"); + var nullableEnum32Collection = runtimeEntityType.FindProperty("NullableEnum32Collection"); + var nullableEnum64 = runtimeEntityType.FindProperty("NullableEnum64"); + var nullableEnum64Array = runtimeEntityType.FindProperty("NullableEnum64Array"); + var nullableEnum64AsString = runtimeEntityType.FindProperty("NullableEnum64AsString"); + var nullableEnum64AsStringArray = runtimeEntityType.FindProperty("NullableEnum64AsStringArray"); + var nullableEnum64AsStringCollection = runtimeEntityType.FindProperty("NullableEnum64AsStringCollection"); + var nullableEnum64Collection = runtimeEntityType.FindProperty("NullableEnum64Collection"); + var nullableEnum8 = runtimeEntityType.FindProperty("NullableEnum8"); + var nullableEnum8Array = runtimeEntityType.FindProperty("NullableEnum8Array"); + var nullableEnum8AsString = runtimeEntityType.FindProperty("NullableEnum8AsString"); + var nullableEnum8AsStringArray = runtimeEntityType.FindProperty("NullableEnum8AsStringArray"); + var nullableEnum8AsStringCollection = runtimeEntityType.FindProperty("NullableEnum8AsStringCollection"); + var nullableEnum8Collection = runtimeEntityType.FindProperty("NullableEnum8Collection"); + var nullableEnumU16 = runtimeEntityType.FindProperty("NullableEnumU16"); + var nullableEnumU16Array = runtimeEntityType.FindProperty("NullableEnumU16Array"); + var nullableEnumU16AsString = runtimeEntityType.FindProperty("NullableEnumU16AsString"); + var nullableEnumU16AsStringArray = runtimeEntityType.FindProperty("NullableEnumU16AsStringArray"); + var nullableEnumU16AsStringCollection = runtimeEntityType.FindProperty("NullableEnumU16AsStringCollection"); + var nullableEnumU16Collection = runtimeEntityType.FindProperty("NullableEnumU16Collection"); + var nullableEnumU32 = runtimeEntityType.FindProperty("NullableEnumU32"); + var nullableEnumU32Array = runtimeEntityType.FindProperty("NullableEnumU32Array"); + var nullableEnumU32AsString = runtimeEntityType.FindProperty("NullableEnumU32AsString"); + var nullableEnumU32AsStringArray = runtimeEntityType.FindProperty("NullableEnumU32AsStringArray"); + var nullableEnumU32AsStringCollection = runtimeEntityType.FindProperty("NullableEnumU32AsStringCollection"); + var nullableEnumU32Collection = runtimeEntityType.FindProperty("NullableEnumU32Collection"); + var nullableEnumU64 = runtimeEntityType.FindProperty("NullableEnumU64"); + var nullableEnumU64Array = runtimeEntityType.FindProperty("NullableEnumU64Array"); + var nullableEnumU64AsString = runtimeEntityType.FindProperty("NullableEnumU64AsString"); + var nullableEnumU64AsStringArray = runtimeEntityType.FindProperty("NullableEnumU64AsStringArray"); + var nullableEnumU64AsStringCollection = runtimeEntityType.FindProperty("NullableEnumU64AsStringCollection"); + var nullableEnumU64Collection = runtimeEntityType.FindProperty("NullableEnumU64Collection"); + var nullableEnumU8 = runtimeEntityType.FindProperty("NullableEnumU8"); + var nullableEnumU8Array = runtimeEntityType.FindProperty("NullableEnumU8Array"); + var nullableEnumU8AsString = runtimeEntityType.FindProperty("NullableEnumU8AsString"); + var nullableEnumU8AsStringArray = runtimeEntityType.FindProperty("NullableEnumU8AsStringArray"); + var nullableEnumU8AsStringCollection = runtimeEntityType.FindProperty("NullableEnumU8AsStringCollection"); + var nullableEnumU8Collection = runtimeEntityType.FindProperty("NullableEnumU8Collection"); + var nullableFloat = runtimeEntityType.FindProperty("NullableFloat"); + var nullableFloatArray = runtimeEntityType.FindProperty("NullableFloatArray"); + var nullableGuid = runtimeEntityType.FindProperty("NullableGuid"); + var nullableGuidArray = runtimeEntityType.FindProperty("NullableGuidArray"); + var nullableIPAddress = runtimeEntityType.FindProperty("NullableIPAddress"); + var nullableIPAddressArray = runtimeEntityType.FindProperty("NullableIPAddressArray"); + var nullableInt16 = runtimeEntityType.FindProperty("NullableInt16"); + var nullableInt16Array = runtimeEntityType.FindProperty("NullableInt16Array"); + var nullableInt32 = runtimeEntityType.FindProperty("NullableInt32"); + var nullableInt32Array = runtimeEntityType.FindProperty("NullableInt32Array"); + var nullableInt64 = runtimeEntityType.FindProperty("NullableInt64"); + var nullableInt64Array = runtimeEntityType.FindProperty("NullableInt64Array"); + var nullableInt8 = runtimeEntityType.FindProperty("NullableInt8"); + var nullableInt8Array = runtimeEntityType.FindProperty("NullableInt8Array"); + var nullablePhysicalAddress = runtimeEntityType.FindProperty("NullablePhysicalAddress"); + var nullablePhysicalAddressArray = runtimeEntityType.FindProperty("NullablePhysicalAddressArray"); + var nullableString = runtimeEntityType.FindProperty("NullableString"); + var nullableStringArray = runtimeEntityType.FindProperty("NullableStringArray"); + var nullableTimeOnly = runtimeEntityType.FindProperty("NullableTimeOnly"); + var nullableTimeOnlyArray = runtimeEntityType.FindProperty("NullableTimeOnlyArray"); + var nullableTimeSpan = runtimeEntityType.FindProperty("NullableTimeSpan"); + var nullableTimeSpanArray = runtimeEntityType.FindProperty("NullableTimeSpanArray"); + var nullableUInt16 = runtimeEntityType.FindProperty("NullableUInt16"); + var nullableUInt16Array = runtimeEntityType.FindProperty("NullableUInt16Array"); + var nullableUInt32 = runtimeEntityType.FindProperty("NullableUInt32"); + var nullableUInt32Array = runtimeEntityType.FindProperty("NullableUInt32Array"); + var nullableUInt64 = runtimeEntityType.FindProperty("NullableUInt64"); + var nullableUInt64Array = runtimeEntityType.FindProperty("NullableUInt64Array"); + var nullableUInt8 = runtimeEntityType.FindProperty("NullableUInt8"); + var nullableUInt8Array = runtimeEntityType.FindProperty("NullableUInt8Array"); + var nullableUri = runtimeEntityType.FindProperty("NullableUri"); + var nullableUriArray = runtimeEntityType.FindProperty("NullableUriArray"); + var physicalAddress = runtimeEntityType.FindProperty("PhysicalAddress"); + var physicalAddressArray = runtimeEntityType.FindProperty("PhysicalAddressArray"); + var physicalAddressToBytesConverterProperty = runtimeEntityType.FindProperty("PhysicalAddressToBytesConverterProperty"); + var physicalAddressToStringConverterProperty = runtimeEntityType.FindProperty("PhysicalAddressToStringConverterProperty"); + var @string = runtimeEntityType.FindProperty("String"); + var stringArray = runtimeEntityType.FindProperty("StringArray"); + var stringToBoolConverterProperty = runtimeEntityType.FindProperty("StringToBoolConverterProperty"); + var stringToBytesConverterProperty = runtimeEntityType.FindProperty("StringToBytesConverterProperty"); + var stringToCharConverterProperty = runtimeEntityType.FindProperty("StringToCharConverterProperty"); + var stringToDateOnlyConverterProperty = runtimeEntityType.FindProperty("StringToDateOnlyConverterProperty"); + var stringToDateTimeConverterProperty = runtimeEntityType.FindProperty("StringToDateTimeConverterProperty"); + var stringToDateTimeOffsetConverterProperty = runtimeEntityType.FindProperty("StringToDateTimeOffsetConverterProperty"); + var stringToDecimalNumberConverterProperty = runtimeEntityType.FindProperty("StringToDecimalNumberConverterProperty"); + var stringToDoubleNumberConverterProperty = runtimeEntityType.FindProperty("StringToDoubleNumberConverterProperty"); + var stringToEnumConverterProperty = runtimeEntityType.FindProperty("StringToEnumConverterProperty"); + var stringToGuidConverterProperty = runtimeEntityType.FindProperty("StringToGuidConverterProperty"); + var stringToIntNumberConverterProperty = runtimeEntityType.FindProperty("StringToIntNumberConverterProperty"); + var stringToTimeOnlyConverterProperty = runtimeEntityType.FindProperty("StringToTimeOnlyConverterProperty"); + var stringToTimeSpanConverterProperty = runtimeEntityType.FindProperty("StringToTimeSpanConverterProperty"); + var stringToUriConverterProperty = runtimeEntityType.FindProperty("StringToUriConverterProperty"); + var timeOnly = runtimeEntityType.FindProperty("TimeOnly"); + var timeOnlyArray = runtimeEntityType.FindProperty("TimeOnlyArray"); + var timeOnlyToStringConverterProperty = runtimeEntityType.FindProperty("TimeOnlyToStringConverterProperty"); + var timeOnlyToTicksConverterProperty = runtimeEntityType.FindProperty("TimeOnlyToTicksConverterProperty"); + var timeSpan = runtimeEntityType.FindProperty("TimeSpan"); + var timeSpanArray = runtimeEntityType.FindProperty("TimeSpanArray"); + var timeSpanToStringConverterProperty = runtimeEntityType.FindProperty("TimeSpanToStringConverterProperty"); + var timeSpanToTicksConverterProperty = runtimeEntityType.FindProperty("TimeSpanToTicksConverterProperty"); + var uInt16 = runtimeEntityType.FindProperty("UInt16"); + var uInt16Array = runtimeEntityType.FindProperty("UInt16Array"); + var uInt32 = runtimeEntityType.FindProperty("UInt32"); + var uInt32Array = runtimeEntityType.FindProperty("UInt32Array"); + var uInt64 = runtimeEntityType.FindProperty("UInt64"); + var uInt64Array = runtimeEntityType.FindProperty("UInt64Array"); + var uInt8 = runtimeEntityType.FindProperty("UInt8"); + var uInt8Array = runtimeEntityType.FindProperty("UInt8Array"); + var uri = runtimeEntityType.FindProperty("Uri"); + var uriArray = runtimeEntityType.FindProperty("UriArray"); + var uriToStringConverterProperty = runtimeEntityType.FindProperty("UriToStringConverterProperty"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedType0EntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedType0EntityType.cs index 8aba6006bff..d63c8493182 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedType0EntityType.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedType0EntityType.cs @@ -733,19 +733,19 @@ public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEnt public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var principalDerivedId = runtimeEntityType.FindProperty("PrincipalDerivedId")!; - var principalDerivedAlternateId = runtimeEntityType.FindProperty("PrincipalDerivedAlternateId")!; - var id = runtimeEntityType.FindProperty("Id")!; - var details = runtimeEntityType.FindProperty("Details")!; - var number = runtimeEntityType.FindProperty("Number")!; - var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray")!; - var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable")!; - var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList")!; - var refTypeList = runtimeEntityType.FindProperty("RefTypeList")!; - var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList")!; - var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList")!; + var principalDerivedId = runtimeEntityType.FindProperty("PrincipalDerivedId"); + var principalDerivedAlternateId = runtimeEntityType.FindProperty("PrincipalDerivedAlternateId"); + var id = runtimeEntityType.FindProperty("Id"); + var details = runtimeEntityType.FindProperty("Details"); + var number = runtimeEntityType.FindProperty("Number"); + var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray"); + var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable"); + var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList"); + var refTypeList = runtimeEntityType.FindProperty("RefTypeList"); + var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList"); + var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList"); var key = runtimeEntityType.FindKey(new[] { principalDerivedId, principalDerivedAlternateId, id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateCompositeFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory>(key)); diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedTypeEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedTypeEntityType.cs index 0ec5f921fb4..f12a723509e 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedTypeEntityType.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/OwnedTypeEntityType.cs @@ -742,18 +742,18 @@ public static RuntimeForeignKey CreateForeignKey2(RuntimeEntityType declaringEnt public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var principalBaseId = runtimeEntityType.FindProperty("PrincipalBaseId")!; - var principalBaseAlternateId = runtimeEntityType.FindProperty("PrincipalBaseAlternateId")!; - var details = runtimeEntityType.FindProperty("Details")!; - var number = runtimeEntityType.FindProperty("Number")!; - var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray")!; - var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable")!; - var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList")!; - var refTypeList = runtimeEntityType.FindProperty("RefTypeList")!; - var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList")!; - var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList")!; + var principalBaseId = runtimeEntityType.FindProperty("PrincipalBaseId"); + var principalBaseAlternateId = runtimeEntityType.FindProperty("PrincipalBaseAlternateId"); + var details = runtimeEntityType.FindProperty("Details"); + var number = runtimeEntityType.FindProperty("Number"); + var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray"); + var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable"); + var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList"); + var refTypeList = runtimeEntityType.FindProperty("RefTypeList"); + var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList"); + var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList"); var key = runtimeEntityType.FindKey(new[] { principalBaseId, principalBaseAlternateId }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateCompositeFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory>(key)); diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBaseEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBaseEntityType.cs index c3fe998aeda..fc198d54d90 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBaseEntityType.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBaseEntityType.cs @@ -81,9 +81,9 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas long (long v) => v), mappingInfo: new RelationalTypeMappingInfo( storeTypeName: "INTEGER")); - id.SetValueComparer(new NullableValueComparer(id.TypeMapping.Comparer)); - id.SetKeyValueComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); id.SetCurrentValueComparer(new EntryCurrentValueComparer(id)); + id.SetComparer(new NullableValueComparer(id.TypeMapping.Comparer)); + id.SetKeyComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); var overrides = new StoreObjectDictionary(); var idPrincipalDerived = new RuntimeRelationalPropertyOverrides( @@ -228,8 +228,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( int (CompiledModelTestBase.AnEnum value) => ((int)(value)), CompiledModelTestBase.AnEnum (int value) => ((CompiledModelTestBase.AnEnum)(value))))); - enum2.SetValueComparer(new NullableValueComparer(enum2.TypeMapping.Comparer)); - enum2.SetKeyValueComparer(new NullableValueComparer(enum2.TypeMapping.KeyComparer)); + enum2.SetComparer(new NullableValueComparer(enum2.TypeMapping.Comparer)); + enum2.SetKeyComparer(new NullableValueComparer(enum2.TypeMapping.KeyComparer)); var flagsEnum1 = runtimeEntityType.AddProperty( "FlagsEnum1", @@ -896,28 +896,28 @@ public static RuntimeSkipNavigation CreateSkipNavigation1(RuntimeEntityType decl public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var alternateId = runtimeEntityType.FindProperty("AlternateId")!; - var enum1 = runtimeEntityType.FindProperty("Enum1")!; - var enum2 = runtimeEntityType.FindProperty("Enum2")!; - var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1")!; - var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2")!; - var point = runtimeEntityType.FindProperty("Point")!; - var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray")!; - var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable")!; - var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList")!; - var refTypeList = runtimeEntityType.FindProperty("RefTypeList")!; - var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList")!; - var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList")!; + var id = runtimeEntityType.FindProperty("Id"); + var alternateId = runtimeEntityType.FindProperty("AlternateId"); + var enum1 = runtimeEntityType.FindProperty("Enum1"); + var enum2 = runtimeEntityType.FindProperty("Enum2"); + var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1"); + var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2"); + var point = runtimeEntityType.FindProperty("Point"); + var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray"); + var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable"); + var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList"); + var refTypeList = runtimeEntityType.FindProperty("RefTypeList"); + var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList"); + var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); var key0 = runtimeEntityType.FindKey(new[] { id, alternateId }); key0.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateCompositeFactory(key0)); key0.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory>(key0)); - var owned = runtimeEntityType.FindNavigation("Owned")!; + var owned = runtimeEntityType.FindNavigation("Owned"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { @@ -936,7 +936,7 @@ public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) ISnapshot (InternalEntityEntry source) => { var entity7 = ((CompiledModelTestBase.PrincipalBase)(source.Entity)); - return ((ISnapshot)(new Snapshot((source.GetCurrentValue(id) == null ? null : ((ValueComparer)(((IProperty)id).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(id))), ((ValueComparer)(((IProperty)alternateId).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(alternateId)), PrincipalBaseUnsafeAccessors._ownedField(entity7), null))); + return ((ISnapshot)(new Snapshot((source.GetCurrentValue(id) == null ? null : ((ValueComparer)(((IProperty)id).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(id))), ((ValueComparer)(((IProperty)alternateId).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(alternateId)), PrincipalBaseUnsafeAccessors._ownedField(entity7), (object)(null)))); }); runtimeEntityType.Counts = new PropertyCounts( propertyCount: 15, diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs index ca2ae795a65..f2b9562ce0d 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs @@ -353,11 +353,11 @@ public static RuntimeForeignKey CreateForeignKey2(RuntimeEntityType declaringEnt public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var derivedsId = runtimeEntityType.FindProperty("DerivedsId")!; - var derivedsAlternateId = runtimeEntityType.FindProperty("DerivedsAlternateId")!; - var principalsId = runtimeEntityType.FindProperty("PrincipalsId")!; - var principalsAlternateId = runtimeEntityType.FindProperty("PrincipalsAlternateId")!; - var rowid = runtimeEntityType.FindProperty("rowid")!; + var derivedsId = runtimeEntityType.FindProperty("DerivedsId"); + var derivedsAlternateId = runtimeEntityType.FindProperty("DerivedsAlternateId"); + var principalsId = runtimeEntityType.FindProperty("PrincipalsId"); + var principalsAlternateId = runtimeEntityType.FindProperty("PrincipalsAlternateId"); + var rowid = runtimeEntityType.FindProperty("rowid"); var key = runtimeEntityType.FindKey(new[] { derivedsId, derivedsAlternateId, principalsId, principalsAlternateId }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateCompositeFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory>(key)); diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalDerivedEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalDerivedEntityType.cs index 69265cc9fdb..7100bcc554a 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalDerivedEntityType.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/PrincipalDerivedEntityType.cs @@ -101,24 +101,24 @@ public static RuntimeSkipNavigation CreateSkipNavigation1(RuntimeEntityType decl public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var alternateId = runtimeEntityType.FindProperty("AlternateId")!; - var enum1 = runtimeEntityType.FindProperty("Enum1")!; - var enum2 = runtimeEntityType.FindProperty("Enum2")!; - var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1")!; - var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2")!; - var point = runtimeEntityType.FindProperty("Point")!; - var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray")!; - var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable")!; - var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList")!; - var refTypeList = runtimeEntityType.FindProperty("RefTypeList")!; - var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList")!; - var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList")!; - var owned = runtimeEntityType.FindNavigation("Owned")!; - var dependent = runtimeEntityType.FindNavigation("Dependent")!; - var manyOwned = runtimeEntityType.FindNavigation("ManyOwned")!; + var id = runtimeEntityType.FindProperty("Id"); + var alternateId = runtimeEntityType.FindProperty("AlternateId"); + var enum1 = runtimeEntityType.FindProperty("Enum1"); + var enum2 = runtimeEntityType.FindProperty("Enum2"); + var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1"); + var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2"); + var point = runtimeEntityType.FindProperty("Point"); + var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray"); + var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable"); + var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList"); + var refTypeList = runtimeEntityType.FindProperty("RefTypeList"); + var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList"); + var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList"); + var owned = runtimeEntityType.FindNavigation("Owned"); + var dependent = runtimeEntityType.FindNavigation("Dependent"); + var manyOwned = runtimeEntityType.FindNavigation("ManyOwned"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { @@ -137,7 +137,7 @@ public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) ISnapshot (InternalEntityEntry source) => { var entity7 = ((CompiledModelTestBase.PrincipalDerived>)(source.Entity)); - return ((ISnapshot)(new Snapshot((source.GetCurrentValue(id) == null ? null : ((ValueComparer)(((IProperty)id).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(id))), ((ValueComparer)(((IProperty)alternateId).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(alternateId)), PrincipalBaseUnsafeAccessors._ownedField(entity7), null, PrincipalDerivedUnsafeAccessors>.Dependent(entity7), SnapshotFactoryFactory.SnapshotCollection(PrincipalDerivedUnsafeAccessors>.ManyOwned(entity7)), null))); + return ((ISnapshot)(new Snapshot((source.GetCurrentValue(id) == null ? null : ((ValueComparer)(((IProperty)id).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(id))), ((ValueComparer)(((IProperty)alternateId).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(alternateId)), PrincipalBaseUnsafeAccessors._ownedField(entity7), (object)(null), PrincipalDerivedUnsafeAccessors>.Dependent(entity7), SnapshotFactoryFactory.SnapshotCollection(PrincipalDerivedUnsafeAccessors>.ManyOwned(entity7)), (object)(null)))); }); runtimeEntityType.Counts = new PropertyCounts( propertyCount: 15, diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/DataEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/DataEntityType.cs index 8d744e4fa5b..696109a79b5 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/DataEntityType.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/DataEntityType.cs @@ -134,9 +134,9 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var blob = runtimeEntityType.FindProperty("Blob")!; - var point = runtimeEntityType.FindProperty("Point")!; + var id = runtimeEntityType.FindProperty("Id"); + var blob = runtimeEntityType.FindProperty("Blob"); + var point = runtimeEntityType.FindProperty("Point"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/DependentBaseEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/DependentBaseEntityType.cs index c9b0612784f..6d4b258a858 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/DependentBaseEntityType.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/DependentBaseEntityType.cs @@ -176,8 +176,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas byte (byte v) => v), mappingInfo: new RelationalTypeMappingInfo( storeTypeName: "INTEGER")); - id.SetValueComparer(new NullableValueComparer(id.TypeMapping.Comparer)); - id.SetKeyValueComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); + id.SetComparer(new NullableValueComparer(id.TypeMapping.Comparer)); + id.SetKeyComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); var key = runtimeEntityType.AddKey( new[] { principalId, principalAlternateId }); @@ -274,14 +274,14 @@ public static RuntimeForeignKey CreateForeignKey2(RuntimeEntityType declaringEnt public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var principalId = runtimeEntityType.FindProperty("PrincipalId")!; - var principalAlternateId = runtimeEntityType.FindProperty("PrincipalAlternateId")!; - var enumDiscriminator = runtimeEntityType.FindProperty("EnumDiscriminator")!; - var id = runtimeEntityType.FindProperty("Id")!; + var principalId = runtimeEntityType.FindProperty("PrincipalId"); + var principalAlternateId = runtimeEntityType.FindProperty("PrincipalAlternateId"); + var enumDiscriminator = runtimeEntityType.FindProperty("EnumDiscriminator"); + var id = runtimeEntityType.FindProperty("Id"); var key = runtimeEntityType.FindKey(new[] { principalId, principalAlternateId }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateCompositeFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory>(key)); - var principal = runtimeEntityType.FindNavigation("Principal")!; + var principal = runtimeEntityType.FindNavigation("Principal"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/DependentDerivedEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/DependentDerivedEntityType.cs index 1c44b3fa269..20abdabdfbd 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/DependentDerivedEntityType.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/DependentDerivedEntityType.cs @@ -86,13 +86,13 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var principalId = runtimeEntityType.FindProperty("PrincipalId")!; - var principalAlternateId = runtimeEntityType.FindProperty("PrincipalAlternateId")!; - var enumDiscriminator = runtimeEntityType.FindProperty("EnumDiscriminator")!; - var id = runtimeEntityType.FindProperty("Id")!; - var data = runtimeEntityType.FindProperty("Data")!; - var money = runtimeEntityType.FindProperty("Money")!; - var principal = runtimeEntityType.FindNavigation("Principal")!; + var principalId = runtimeEntityType.FindProperty("PrincipalId"); + var principalAlternateId = runtimeEntityType.FindProperty("PrincipalAlternateId"); + var enumDiscriminator = runtimeEntityType.FindProperty("EnumDiscriminator"); + var id = runtimeEntityType.FindProperty("Id"); + var data = runtimeEntityType.FindProperty("Data"); + var money = runtimeEntityType.FindProperty("Money"); + var principal = runtimeEntityType.FindNavigation("Principal"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/ManyTypesEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/ManyTypesEntityType.cs index b126fa0b69b..af1a40407f3 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/ManyTypesEntityType.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/ManyTypesEntityType.cs @@ -5958,8 +5958,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas bool (bool v) => v), mappingInfo: new RelationalTypeMappingInfo( storeTypeName: "INTEGER")); - nullableBool.SetValueComparer(new NullableValueComparer(nullableBool.TypeMapping.Comparer)); - nullableBool.SetKeyValueComparer(new NullableValueComparer(nullableBool.TypeMapping.KeyComparer)); + nullableBool.SetComparer(new NullableValueComparer(nullableBool.TypeMapping.Comparer)); + nullableBool.SetKeyComparer(new NullableValueComparer(nullableBool.TypeMapping.KeyComparer)); var nullableBoolArray = runtimeEntityType.AddProperty( "NullableBoolArray", @@ -6160,8 +6160,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas char (char v) => v), mappingInfo: new RelationalTypeMappingInfo( storeTypeName: "TEXT")); - nullableChar.SetValueComparer(new NullableValueComparer(nullableChar.TypeMapping.Comparer)); - nullableChar.SetKeyValueComparer(new NullableValueComparer(nullableChar.TypeMapping.KeyComparer)); + nullableChar.SetComparer(new NullableValueComparer(nullableChar.TypeMapping.Comparer)); + nullableChar.SetKeyComparer(new NullableValueComparer(nullableChar.TypeMapping.KeyComparer)); var nullableCharArray = runtimeEntityType.AddProperty( "NullableCharArray", @@ -6250,8 +6250,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas relationshipIndex: -1, storeGenerationIndex: -1); nullableDateOnly.TypeMapping = SqliteDateOnlyTypeMapping.Default; - nullableDateOnly.SetValueComparer(new NullableValueComparer(nullableDateOnly.TypeMapping.Comparer)); - nullableDateOnly.SetKeyValueComparer(new NullableValueComparer(nullableDateOnly.TypeMapping.KeyComparer)); + nullableDateOnly.SetComparer(new NullableValueComparer(nullableDateOnly.TypeMapping.Comparer)); + nullableDateOnly.SetKeyComparer(new NullableValueComparer(nullableDateOnly.TypeMapping.KeyComparer)); var nullableDateOnlyArray = runtimeEntityType.AddProperty( "NullableDateOnlyArray", @@ -6326,8 +6326,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas relationshipIndex: -1, storeGenerationIndex: -1); nullableDateTime.TypeMapping = SqliteDateTimeTypeMapping.Default; - nullableDateTime.SetValueComparer(new NullableValueComparer(nullableDateTime.TypeMapping.Comparer)); - nullableDateTime.SetKeyValueComparer(new NullableValueComparer(nullableDateTime.TypeMapping.KeyComparer)); + nullableDateTime.SetComparer(new NullableValueComparer(nullableDateTime.TypeMapping.Comparer)); + nullableDateTime.SetKeyComparer(new NullableValueComparer(nullableDateTime.TypeMapping.KeyComparer)); var nullableDateTimeArray = runtimeEntityType.AddProperty( "NullableDateTimeArray", @@ -6402,8 +6402,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas relationshipIndex: -1, storeGenerationIndex: -1); nullableDecimal.TypeMapping = SqliteDecimalTypeMapping.Default; - nullableDecimal.SetValueComparer(new NullableValueComparer(nullableDecimal.TypeMapping.Comparer)); - nullableDecimal.SetKeyValueComparer(new NullableValueComparer(nullableDecimal.TypeMapping.KeyComparer)); + nullableDecimal.SetComparer(new NullableValueComparer(nullableDecimal.TypeMapping.Comparer)); + nullableDecimal.SetKeyComparer(new NullableValueComparer(nullableDecimal.TypeMapping.KeyComparer)); var nullableDecimalArray = runtimeEntityType.AddProperty( "NullableDecimalArray", @@ -6492,8 +6492,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas double (double v) => v), mappingInfo: new RelationalTypeMappingInfo( storeTypeName: "REAL")); - nullableDouble.SetValueComparer(new NullableValueComparer(nullableDouble.TypeMapping.Comparer)); - nullableDouble.SetKeyValueComparer(new NullableValueComparer(nullableDouble.TypeMapping.KeyComparer)); + nullableDouble.SetComparer(new NullableValueComparer(nullableDouble.TypeMapping.Comparer)); + nullableDouble.SetKeyComparer(new NullableValueComparer(nullableDouble.TypeMapping.KeyComparer)); var nullableDoubleArray = runtimeEntityType.AddProperty( "NullableDoubleArray", @@ -6604,8 +6604,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( short (CompiledModelTestBase.Enum16 value) => ((short)(value)), CompiledModelTestBase.Enum16 (short value) => ((CompiledModelTestBase.Enum16)(value))))); - nullableEnum16.SetValueComparer(new NullableValueComparer(nullableEnum16.TypeMapping.Comparer)); - nullableEnum16.SetKeyValueComparer(new NullableValueComparer(nullableEnum16.TypeMapping.KeyComparer)); + nullableEnum16.SetComparer(new NullableValueComparer(nullableEnum16.TypeMapping.Comparer)); + nullableEnum16.SetKeyComparer(new NullableValueComparer(nullableEnum16.TypeMapping.KeyComparer)); var nullableEnum16Array = runtimeEntityType.AddProperty( "NullableEnum16Array", @@ -6732,8 +6732,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( short (CompiledModelTestBase.Enum16 value) => ((short)(value)), CompiledModelTestBase.Enum16 (short value) => ((CompiledModelTestBase.Enum16)(value))))); - nullableEnum16AsString.SetValueComparer(new NullableValueComparer(nullableEnum16AsString.TypeMapping.Comparer)); - nullableEnum16AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnum16AsString.TypeMapping.KeyComparer)); + nullableEnum16AsString.SetComparer(new NullableValueComparer(nullableEnum16AsString.TypeMapping.Comparer)); + nullableEnum16AsString.SetKeyComparer(new NullableValueComparer(nullableEnum16AsString.TypeMapping.KeyComparer)); var nullableEnum16AsStringArray = runtimeEntityType.AddProperty( "NullableEnum16AsStringArray", @@ -7010,8 +7010,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( int (CompiledModelTestBase.Enum32 value) => ((int)(value)), CompiledModelTestBase.Enum32 (int value) => ((CompiledModelTestBase.Enum32)(value))))); - nullableEnum32.SetValueComparer(new NullableValueComparer(nullableEnum32.TypeMapping.Comparer)); - nullableEnum32.SetKeyValueComparer(new NullableValueComparer(nullableEnum32.TypeMapping.KeyComparer)); + nullableEnum32.SetComparer(new NullableValueComparer(nullableEnum32.TypeMapping.Comparer)); + nullableEnum32.SetKeyComparer(new NullableValueComparer(nullableEnum32.TypeMapping.KeyComparer)); var nullableEnum32Array = runtimeEntityType.AddProperty( "NullableEnum32Array", @@ -7138,8 +7138,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( int (CompiledModelTestBase.Enum32 value) => ((int)(value)), CompiledModelTestBase.Enum32 (int value) => ((CompiledModelTestBase.Enum32)(value))))); - nullableEnum32AsString.SetValueComparer(new NullableValueComparer(nullableEnum32AsString.TypeMapping.Comparer)); - nullableEnum32AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnum32AsString.TypeMapping.KeyComparer)); + nullableEnum32AsString.SetComparer(new NullableValueComparer(nullableEnum32AsString.TypeMapping.Comparer)); + nullableEnum32AsString.SetKeyComparer(new NullableValueComparer(nullableEnum32AsString.TypeMapping.KeyComparer)); var nullableEnum32AsStringArray = runtimeEntityType.AddProperty( "NullableEnum32AsStringArray", @@ -7416,8 +7416,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( long (CompiledModelTestBase.Enum64 value) => ((long)(value)), CompiledModelTestBase.Enum64 (long value) => ((CompiledModelTestBase.Enum64)(value))))); - nullableEnum64.SetValueComparer(new NullableValueComparer(nullableEnum64.TypeMapping.Comparer)); - nullableEnum64.SetKeyValueComparer(new NullableValueComparer(nullableEnum64.TypeMapping.KeyComparer)); + nullableEnum64.SetComparer(new NullableValueComparer(nullableEnum64.TypeMapping.Comparer)); + nullableEnum64.SetKeyComparer(new NullableValueComparer(nullableEnum64.TypeMapping.KeyComparer)); var nullableEnum64Array = runtimeEntityType.AddProperty( "NullableEnum64Array", @@ -7544,8 +7544,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( long (CompiledModelTestBase.Enum64 value) => ((long)(value)), CompiledModelTestBase.Enum64 (long value) => ((CompiledModelTestBase.Enum64)(value))))); - nullableEnum64AsString.SetValueComparer(new NullableValueComparer(nullableEnum64AsString.TypeMapping.Comparer)); - nullableEnum64AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnum64AsString.TypeMapping.KeyComparer)); + nullableEnum64AsString.SetComparer(new NullableValueComparer(nullableEnum64AsString.TypeMapping.Comparer)); + nullableEnum64AsString.SetKeyComparer(new NullableValueComparer(nullableEnum64AsString.TypeMapping.KeyComparer)); var nullableEnum64AsStringArray = runtimeEntityType.AddProperty( "NullableEnum64AsStringArray", @@ -7822,8 +7822,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( sbyte (CompiledModelTestBase.Enum8 value) => ((sbyte)(value)), CompiledModelTestBase.Enum8 (sbyte value) => ((CompiledModelTestBase.Enum8)(value))))); - nullableEnum8.SetValueComparer(new NullableValueComparer(nullableEnum8.TypeMapping.Comparer)); - nullableEnum8.SetKeyValueComparer(new NullableValueComparer(nullableEnum8.TypeMapping.KeyComparer)); + nullableEnum8.SetComparer(new NullableValueComparer(nullableEnum8.TypeMapping.Comparer)); + nullableEnum8.SetKeyComparer(new NullableValueComparer(nullableEnum8.TypeMapping.KeyComparer)); var nullableEnum8Array = runtimeEntityType.AddProperty( "NullableEnum8Array", @@ -7950,8 +7950,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( sbyte (CompiledModelTestBase.Enum8 value) => ((sbyte)(value)), CompiledModelTestBase.Enum8 (sbyte value) => ((CompiledModelTestBase.Enum8)(value))))); - nullableEnum8AsString.SetValueComparer(new NullableValueComparer(nullableEnum8AsString.TypeMapping.Comparer)); - nullableEnum8AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnum8AsString.TypeMapping.KeyComparer)); + nullableEnum8AsString.SetComparer(new NullableValueComparer(nullableEnum8AsString.TypeMapping.Comparer)); + nullableEnum8AsString.SetKeyComparer(new NullableValueComparer(nullableEnum8AsString.TypeMapping.KeyComparer)); var nullableEnum8AsStringArray = runtimeEntityType.AddProperty( "NullableEnum8AsStringArray", @@ -8228,8 +8228,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( ushort (CompiledModelTestBase.EnumU16 value) => ((ushort)(value)), CompiledModelTestBase.EnumU16 (ushort value) => ((CompiledModelTestBase.EnumU16)(value))))); - nullableEnumU16.SetValueComparer(new NullableValueComparer(nullableEnumU16.TypeMapping.Comparer)); - nullableEnumU16.SetKeyValueComparer(new NullableValueComparer(nullableEnumU16.TypeMapping.KeyComparer)); + nullableEnumU16.SetComparer(new NullableValueComparer(nullableEnumU16.TypeMapping.Comparer)); + nullableEnumU16.SetKeyComparer(new NullableValueComparer(nullableEnumU16.TypeMapping.KeyComparer)); var nullableEnumU16Array = runtimeEntityType.AddProperty( "NullableEnumU16Array", @@ -8356,8 +8356,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( ushort (CompiledModelTestBase.EnumU16 value) => ((ushort)(value)), CompiledModelTestBase.EnumU16 (ushort value) => ((CompiledModelTestBase.EnumU16)(value))))); - nullableEnumU16AsString.SetValueComparer(new NullableValueComparer(nullableEnumU16AsString.TypeMapping.Comparer)); - nullableEnumU16AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnumU16AsString.TypeMapping.KeyComparer)); + nullableEnumU16AsString.SetComparer(new NullableValueComparer(nullableEnumU16AsString.TypeMapping.Comparer)); + nullableEnumU16AsString.SetKeyComparer(new NullableValueComparer(nullableEnumU16AsString.TypeMapping.KeyComparer)); var nullableEnumU16AsStringArray = runtimeEntityType.AddProperty( "NullableEnumU16AsStringArray", @@ -8634,8 +8634,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( uint (CompiledModelTestBase.EnumU32 value) => ((uint)(value)), CompiledModelTestBase.EnumU32 (uint value) => ((CompiledModelTestBase.EnumU32)(value))))); - nullableEnumU32.SetValueComparer(new NullableValueComparer(nullableEnumU32.TypeMapping.Comparer)); - nullableEnumU32.SetKeyValueComparer(new NullableValueComparer(nullableEnumU32.TypeMapping.KeyComparer)); + nullableEnumU32.SetComparer(new NullableValueComparer(nullableEnumU32.TypeMapping.Comparer)); + nullableEnumU32.SetKeyComparer(new NullableValueComparer(nullableEnumU32.TypeMapping.KeyComparer)); var nullableEnumU32Array = runtimeEntityType.AddProperty( "NullableEnumU32Array", @@ -8762,8 +8762,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( uint (CompiledModelTestBase.EnumU32 value) => ((uint)(value)), CompiledModelTestBase.EnumU32 (uint value) => ((CompiledModelTestBase.EnumU32)(value))))); - nullableEnumU32AsString.SetValueComparer(new NullableValueComparer(nullableEnumU32AsString.TypeMapping.Comparer)); - nullableEnumU32AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnumU32AsString.TypeMapping.KeyComparer)); + nullableEnumU32AsString.SetComparer(new NullableValueComparer(nullableEnumU32AsString.TypeMapping.Comparer)); + nullableEnumU32AsString.SetKeyComparer(new NullableValueComparer(nullableEnumU32AsString.TypeMapping.KeyComparer)); var nullableEnumU32AsStringArray = runtimeEntityType.AddProperty( "NullableEnumU32AsStringArray", @@ -9038,8 +9038,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( ulong (CompiledModelTestBase.EnumU64 value) => ((ulong)(value)), CompiledModelTestBase.EnumU64 (ulong value) => ((CompiledModelTestBase.EnumU64)(value))))); - nullableEnumU64.SetValueComparer(new NullableValueComparer(nullableEnumU64.TypeMapping.Comparer)); - nullableEnumU64.SetKeyValueComparer(new NullableValueComparer(nullableEnumU64.TypeMapping.KeyComparer)); + nullableEnumU64.SetComparer(new NullableValueComparer(nullableEnumU64.TypeMapping.Comparer)); + nullableEnumU64.SetKeyComparer(new NullableValueComparer(nullableEnumU64.TypeMapping.KeyComparer)); var nullableEnumU64Array = runtimeEntityType.AddProperty( "NullableEnumU64Array", @@ -9162,8 +9162,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( ulong (CompiledModelTestBase.EnumU64 value) => ((ulong)(value)), CompiledModelTestBase.EnumU64 (ulong value) => ((CompiledModelTestBase.EnumU64)(value))))); - nullableEnumU64AsString.SetValueComparer(new NullableValueComparer(nullableEnumU64AsString.TypeMapping.Comparer)); - nullableEnumU64AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnumU64AsString.TypeMapping.KeyComparer)); + nullableEnumU64AsString.SetComparer(new NullableValueComparer(nullableEnumU64AsString.TypeMapping.Comparer)); + nullableEnumU64AsString.SetKeyComparer(new NullableValueComparer(nullableEnumU64AsString.TypeMapping.KeyComparer)); var nullableEnumU64AsStringArray = runtimeEntityType.AddProperty( "NullableEnumU64AsStringArray", @@ -9434,8 +9434,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( byte (CompiledModelTestBase.EnumU8 value) => ((byte)(value)), CompiledModelTestBase.EnumU8 (byte value) => ((CompiledModelTestBase.EnumU8)(value))))); - nullableEnumU8.SetValueComparer(new NullableValueComparer(nullableEnumU8.TypeMapping.Comparer)); - nullableEnumU8.SetKeyValueComparer(new NullableValueComparer(nullableEnumU8.TypeMapping.KeyComparer)); + nullableEnumU8.SetComparer(new NullableValueComparer(nullableEnumU8.TypeMapping.Comparer)); + nullableEnumU8.SetKeyComparer(new NullableValueComparer(nullableEnumU8.TypeMapping.KeyComparer)); var nullableEnumU8Array = runtimeEntityType.AddProperty( "NullableEnumU8Array", @@ -9562,8 +9562,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( byte (CompiledModelTestBase.EnumU8 value) => ((byte)(value)), CompiledModelTestBase.EnumU8 (byte value) => ((CompiledModelTestBase.EnumU8)(value))))); - nullableEnumU8AsString.SetValueComparer(new NullableValueComparer(nullableEnumU8AsString.TypeMapping.Comparer)); - nullableEnumU8AsString.SetKeyValueComparer(new NullableValueComparer(nullableEnumU8AsString.TypeMapping.KeyComparer)); + nullableEnumU8AsString.SetComparer(new NullableValueComparer(nullableEnumU8AsString.TypeMapping.Comparer)); + nullableEnumU8AsString.SetKeyComparer(new NullableValueComparer(nullableEnumU8AsString.TypeMapping.KeyComparer)); var nullableEnumU8AsStringArray = runtimeEntityType.AddProperty( "NullableEnumU8AsStringArray", @@ -9832,8 +9832,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas float (float v) => v), mappingInfo: new RelationalTypeMappingInfo( storeTypeName: "REAL")); - nullableFloat.SetValueComparer(new NullableValueComparer(nullableFloat.TypeMapping.Comparer)); - nullableFloat.SetKeyValueComparer(new NullableValueComparer(nullableFloat.TypeMapping.KeyComparer)); + nullableFloat.SetComparer(new NullableValueComparer(nullableFloat.TypeMapping.Comparer)); + nullableFloat.SetKeyComparer(new NullableValueComparer(nullableFloat.TypeMapping.KeyComparer)); var nullableFloatArray = runtimeEntityType.AddProperty( "NullableFloatArray", @@ -9922,8 +9922,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas relationshipIndex: -1, storeGenerationIndex: -1); nullableGuid.TypeMapping = SqliteGuidTypeMapping.Default; - nullableGuid.SetValueComparer(new NullableValueComparer(nullableGuid.TypeMapping.Comparer)); - nullableGuid.SetKeyValueComparer(new NullableValueComparer(nullableGuid.TypeMapping.KeyComparer)); + nullableGuid.SetComparer(new NullableValueComparer(nullableGuid.TypeMapping.Comparer)); + nullableGuid.SetKeyComparer(new NullableValueComparer(nullableGuid.TypeMapping.KeyComparer)); var nullableGuidArray = runtimeEntityType.AddProperty( "NullableGuidArray", @@ -10138,8 +10138,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas short (short v) => v), mappingInfo: new RelationalTypeMappingInfo( storeTypeName: "INTEGER")); - nullableInt16.SetValueComparer(new NullableValueComparer(nullableInt16.TypeMapping.Comparer)); - nullableInt16.SetKeyValueComparer(new NullableValueComparer(nullableInt16.TypeMapping.KeyComparer)); + nullableInt16.SetComparer(new NullableValueComparer(nullableInt16.TypeMapping.Comparer)); + nullableInt16.SetKeyComparer(new NullableValueComparer(nullableInt16.TypeMapping.KeyComparer)); var nullableInt16Array = runtimeEntityType.AddProperty( "NullableInt16Array", @@ -10242,8 +10242,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas int (int v) => v), mappingInfo: new RelationalTypeMappingInfo( storeTypeName: "INTEGER")); - nullableInt32.SetValueComparer(new NullableValueComparer(nullableInt32.TypeMapping.Comparer)); - nullableInt32.SetKeyValueComparer(new NullableValueComparer(nullableInt32.TypeMapping.KeyComparer)); + nullableInt32.SetComparer(new NullableValueComparer(nullableInt32.TypeMapping.Comparer)); + nullableInt32.SetKeyComparer(new NullableValueComparer(nullableInt32.TypeMapping.KeyComparer)); var nullableInt32Array = runtimeEntityType.AddProperty( "NullableInt32Array", @@ -10346,8 +10346,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas long (long v) => v), mappingInfo: new RelationalTypeMappingInfo( storeTypeName: "INTEGER")); - nullableInt64.SetValueComparer(new NullableValueComparer(nullableInt64.TypeMapping.Comparer)); - nullableInt64.SetKeyValueComparer(new NullableValueComparer(nullableInt64.TypeMapping.KeyComparer)); + nullableInt64.SetComparer(new NullableValueComparer(nullableInt64.TypeMapping.Comparer)); + nullableInt64.SetKeyComparer(new NullableValueComparer(nullableInt64.TypeMapping.KeyComparer)); var nullableInt64Array = runtimeEntityType.AddProperty( "NullableInt64Array", @@ -10450,8 +10450,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas sbyte (sbyte v) => v), mappingInfo: new RelationalTypeMappingInfo( storeTypeName: "INTEGER")); - nullableInt8.SetValueComparer(new NullableValueComparer(nullableInt8.TypeMapping.Comparer)); - nullableInt8.SetKeyValueComparer(new NullableValueComparer(nullableInt8.TypeMapping.KeyComparer)); + nullableInt8.SetComparer(new NullableValueComparer(nullableInt8.TypeMapping.Comparer)); + nullableInt8.SetKeyComparer(new NullableValueComparer(nullableInt8.TypeMapping.KeyComparer)); var nullableInt8Array = runtimeEntityType.AddProperty( "NullableInt8Array", @@ -10740,8 +10740,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas relationshipIndex: -1, storeGenerationIndex: -1); nullableTimeOnly.TypeMapping = SqliteTimeOnlyTypeMapping.Default; - nullableTimeOnly.SetValueComparer(new NullableValueComparer(nullableTimeOnly.TypeMapping.Comparer)); - nullableTimeOnly.SetKeyValueComparer(new NullableValueComparer(nullableTimeOnly.TypeMapping.KeyComparer)); + nullableTimeOnly.SetComparer(new NullableValueComparer(nullableTimeOnly.TypeMapping.Comparer)); + nullableTimeOnly.SetKeyComparer(new NullableValueComparer(nullableTimeOnly.TypeMapping.KeyComparer)); var nullableTimeOnlyArray = runtimeEntityType.AddProperty( "NullableTimeOnlyArray", @@ -10830,8 +10830,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas TimeSpan (TimeSpan v) => v), mappingInfo: new RelationalTypeMappingInfo( storeTypeName: "TEXT")); - nullableTimeSpan.SetValueComparer(new NullableValueComparer(nullableTimeSpan.TypeMapping.Comparer)); - nullableTimeSpan.SetKeyValueComparer(new NullableValueComparer(nullableTimeSpan.TypeMapping.KeyComparer)); + nullableTimeSpan.SetComparer(new NullableValueComparer(nullableTimeSpan.TypeMapping.Comparer)); + nullableTimeSpan.SetKeyComparer(new NullableValueComparer(nullableTimeSpan.TypeMapping.KeyComparer)); var nullableTimeSpanArray = runtimeEntityType.AddProperty( "NullableTimeSpanArray", @@ -10934,8 +10934,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas ushort (ushort v) => v), mappingInfo: new RelationalTypeMappingInfo( storeTypeName: "INTEGER")); - nullableUInt16.SetValueComparer(new NullableValueComparer(nullableUInt16.TypeMapping.Comparer)); - nullableUInt16.SetKeyValueComparer(new NullableValueComparer(nullableUInt16.TypeMapping.KeyComparer)); + nullableUInt16.SetComparer(new NullableValueComparer(nullableUInt16.TypeMapping.Comparer)); + nullableUInt16.SetKeyComparer(new NullableValueComparer(nullableUInt16.TypeMapping.KeyComparer)); var nullableUInt16Array = runtimeEntityType.AddProperty( "NullableUInt16Array", @@ -11038,8 +11038,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas uint (uint v) => v), mappingInfo: new RelationalTypeMappingInfo( storeTypeName: "INTEGER")); - nullableUInt32.SetValueComparer(new NullableValueComparer(nullableUInt32.TypeMapping.Comparer)); - nullableUInt32.SetKeyValueComparer(new NullableValueComparer(nullableUInt32.TypeMapping.KeyComparer)); + nullableUInt32.SetComparer(new NullableValueComparer(nullableUInt32.TypeMapping.Comparer)); + nullableUInt32.SetKeyComparer(new NullableValueComparer(nullableUInt32.TypeMapping.KeyComparer)); var nullableUInt32Array = runtimeEntityType.AddProperty( "NullableUInt32Array", @@ -11128,8 +11128,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas relationshipIndex: -1, storeGenerationIndex: -1); nullableUInt64.TypeMapping = SqliteULongTypeMapping.Default; - nullableUInt64.SetValueComparer(new NullableValueComparer(nullableUInt64.TypeMapping.Comparer)); - nullableUInt64.SetKeyValueComparer(new NullableValueComparer(nullableUInt64.TypeMapping.KeyComparer)); + nullableUInt64.SetComparer(new NullableValueComparer(nullableUInt64.TypeMapping.Comparer)); + nullableUInt64.SetKeyComparer(new NullableValueComparer(nullableUInt64.TypeMapping.KeyComparer)); var nullableUInt64Array = runtimeEntityType.AddProperty( "NullableUInt64Array", @@ -11218,8 +11218,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas byte (byte v) => v), mappingInfo: new RelationalTypeMappingInfo( storeTypeName: "INTEGER")); - nullableUInt8.SetValueComparer(new NullableValueComparer(nullableUInt8.TypeMapping.Comparer)); - nullableUInt8.SetKeyValueComparer(new NullableValueComparer(nullableUInt8.TypeMapping.KeyComparer)); + nullableUInt8.SetComparer(new NullableValueComparer(nullableUInt8.TypeMapping.Comparer)); + nullableUInt8.SetKeyComparer(new NullableValueComparer(nullableUInt8.TypeMapping.KeyComparer)); var nullableUInt8Array = runtimeEntityType.AddProperty( "NullableUInt8Array", @@ -13317,242 +13317,242 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var @bool = runtimeEntityType.FindProperty("Bool")!; - var boolArray = runtimeEntityType.FindProperty("BoolArray")!; - var boolToStringConverterProperty = runtimeEntityType.FindProperty("BoolToStringConverterProperty")!; - var boolToTwoValuesConverterProperty = runtimeEntityType.FindProperty("BoolToTwoValuesConverterProperty")!; - var boolToZeroOneConverterProperty = runtimeEntityType.FindProperty("BoolToZeroOneConverterProperty")!; - var bytes = runtimeEntityType.FindProperty("Bytes")!; - var bytesArray = runtimeEntityType.FindProperty("BytesArray")!; - var bytesToStringConverterProperty = runtimeEntityType.FindProperty("BytesToStringConverterProperty")!; - var castingConverterProperty = runtimeEntityType.FindProperty("CastingConverterProperty")!; - var @char = runtimeEntityType.FindProperty("Char")!; - var charArray = runtimeEntityType.FindProperty("CharArray")!; - var charToStringConverterProperty = runtimeEntityType.FindProperty("CharToStringConverterProperty")!; - var dateOnly = runtimeEntityType.FindProperty("DateOnly")!; - var dateOnlyArray = runtimeEntityType.FindProperty("DateOnlyArray")!; - var dateOnlyToStringConverterProperty = runtimeEntityType.FindProperty("DateOnlyToStringConverterProperty")!; - var dateTime = runtimeEntityType.FindProperty("DateTime")!; - var dateTimeArray = runtimeEntityType.FindProperty("DateTimeArray")!; - var dateTimeOffsetToBinaryConverterProperty = runtimeEntityType.FindProperty("DateTimeOffsetToBinaryConverterProperty")!; - var dateTimeOffsetToBytesConverterProperty = runtimeEntityType.FindProperty("DateTimeOffsetToBytesConverterProperty")!; - var dateTimeOffsetToStringConverterProperty = runtimeEntityType.FindProperty("DateTimeOffsetToStringConverterProperty")!; - var dateTimeToBinaryConverterProperty = runtimeEntityType.FindProperty("DateTimeToBinaryConverterProperty")!; - var dateTimeToStringConverterProperty = runtimeEntityType.FindProperty("DateTimeToStringConverterProperty")!; - var dateTimeToTicksConverterProperty = runtimeEntityType.FindProperty("DateTimeToTicksConverterProperty")!; - var @decimal = runtimeEntityType.FindProperty("Decimal")!; - var decimalArray = runtimeEntityType.FindProperty("DecimalArray")!; - var decimalNumberToBytesConverterProperty = runtimeEntityType.FindProperty("DecimalNumberToBytesConverterProperty")!; - var decimalNumberToStringConverterProperty = runtimeEntityType.FindProperty("DecimalNumberToStringConverterProperty")!; - var @double = runtimeEntityType.FindProperty("Double")!; - var doubleArray = runtimeEntityType.FindProperty("DoubleArray")!; - var doubleNumberToBytesConverterProperty = runtimeEntityType.FindProperty("DoubleNumberToBytesConverterProperty")!; - var doubleNumberToStringConverterProperty = runtimeEntityType.FindProperty("DoubleNumberToStringConverterProperty")!; - var enum16 = runtimeEntityType.FindProperty("Enum16")!; - var enum16Array = runtimeEntityType.FindProperty("Enum16Array")!; - var enum16AsString = runtimeEntityType.FindProperty("Enum16AsString")!; - var enum16AsStringArray = runtimeEntityType.FindProperty("Enum16AsStringArray")!; - var enum16AsStringCollection = runtimeEntityType.FindProperty("Enum16AsStringCollection")!; - var enum16Collection = runtimeEntityType.FindProperty("Enum16Collection")!; - var enum32 = runtimeEntityType.FindProperty("Enum32")!; - var enum32Array = runtimeEntityType.FindProperty("Enum32Array")!; - var enum32AsString = runtimeEntityType.FindProperty("Enum32AsString")!; - var enum32AsStringArray = runtimeEntityType.FindProperty("Enum32AsStringArray")!; - var enum32AsStringCollection = runtimeEntityType.FindProperty("Enum32AsStringCollection")!; - var enum32Collection = runtimeEntityType.FindProperty("Enum32Collection")!; - var enum64 = runtimeEntityType.FindProperty("Enum64")!; - var enum64Array = runtimeEntityType.FindProperty("Enum64Array")!; - var enum64AsString = runtimeEntityType.FindProperty("Enum64AsString")!; - var enum64AsStringArray = runtimeEntityType.FindProperty("Enum64AsStringArray")!; - var enum64AsStringCollection = runtimeEntityType.FindProperty("Enum64AsStringCollection")!; - var enum64Collection = runtimeEntityType.FindProperty("Enum64Collection")!; - var enum8 = runtimeEntityType.FindProperty("Enum8")!; - var enum8Array = runtimeEntityType.FindProperty("Enum8Array")!; - var enum8AsString = runtimeEntityType.FindProperty("Enum8AsString")!; - var enum8AsStringArray = runtimeEntityType.FindProperty("Enum8AsStringArray")!; - var enum8AsStringCollection = runtimeEntityType.FindProperty("Enum8AsStringCollection")!; - var enum8Collection = runtimeEntityType.FindProperty("Enum8Collection")!; - var enumToNumberConverterProperty = runtimeEntityType.FindProperty("EnumToNumberConverterProperty")!; - var enumToStringConverterProperty = runtimeEntityType.FindProperty("EnumToStringConverterProperty")!; - var enumU16 = runtimeEntityType.FindProperty("EnumU16")!; - var enumU16Array = runtimeEntityType.FindProperty("EnumU16Array")!; - var enumU16AsString = runtimeEntityType.FindProperty("EnumU16AsString")!; - var enumU16AsStringArray = runtimeEntityType.FindProperty("EnumU16AsStringArray")!; - var enumU16AsStringCollection = runtimeEntityType.FindProperty("EnumU16AsStringCollection")!; - var enumU16Collection = runtimeEntityType.FindProperty("EnumU16Collection")!; - var enumU32 = runtimeEntityType.FindProperty("EnumU32")!; - var enumU32Array = runtimeEntityType.FindProperty("EnumU32Array")!; - var enumU32AsString = runtimeEntityType.FindProperty("EnumU32AsString")!; - var enumU32AsStringArray = runtimeEntityType.FindProperty("EnumU32AsStringArray")!; - var enumU32AsStringCollection = runtimeEntityType.FindProperty("EnumU32AsStringCollection")!; - var enumU32Collection = runtimeEntityType.FindProperty("EnumU32Collection")!; - var enumU64 = runtimeEntityType.FindProperty("EnumU64")!; - var enumU64Array = runtimeEntityType.FindProperty("EnumU64Array")!; - var enumU64AsString = runtimeEntityType.FindProperty("EnumU64AsString")!; - var enumU64AsStringArray = runtimeEntityType.FindProperty("EnumU64AsStringArray")!; - var enumU64AsStringCollection = runtimeEntityType.FindProperty("EnumU64AsStringCollection")!; - var enumU64Collection = runtimeEntityType.FindProperty("EnumU64Collection")!; - var enumU8 = runtimeEntityType.FindProperty("EnumU8")!; - var enumU8Array = runtimeEntityType.FindProperty("EnumU8Array")!; - var enumU8AsString = runtimeEntityType.FindProperty("EnumU8AsString")!; - var enumU8AsStringArray = runtimeEntityType.FindProperty("EnumU8AsStringArray")!; - var enumU8AsStringCollection = runtimeEntityType.FindProperty("EnumU8AsStringCollection")!; - var enumU8Collection = runtimeEntityType.FindProperty("EnumU8Collection")!; - var @float = runtimeEntityType.FindProperty("Float")!; - var floatArray = runtimeEntityType.FindProperty("FloatArray")!; - var guid = runtimeEntityType.FindProperty("Guid")!; - var guidArray = runtimeEntityType.FindProperty("GuidArray")!; - var guidToBytesConverterProperty = runtimeEntityType.FindProperty("GuidToBytesConverterProperty")!; - var guidToStringConverterProperty = runtimeEntityType.FindProperty("GuidToStringConverterProperty")!; - var iPAddress = runtimeEntityType.FindProperty("IPAddress")!; - var iPAddressArray = runtimeEntityType.FindProperty("IPAddressArray")!; - var iPAddressToBytesConverterProperty = runtimeEntityType.FindProperty("IPAddressToBytesConverterProperty")!; - var iPAddressToStringConverterProperty = runtimeEntityType.FindProperty("IPAddressToStringConverterProperty")!; - var int16 = runtimeEntityType.FindProperty("Int16")!; - var int16Array = runtimeEntityType.FindProperty("Int16Array")!; - var int32 = runtimeEntityType.FindProperty("Int32")!; - var int32Array = runtimeEntityType.FindProperty("Int32Array")!; - var int64 = runtimeEntityType.FindProperty("Int64")!; - var int64Array = runtimeEntityType.FindProperty("Int64Array")!; - var int8 = runtimeEntityType.FindProperty("Int8")!; - var int8Array = runtimeEntityType.FindProperty("Int8Array")!; - var intNumberToBytesConverterProperty = runtimeEntityType.FindProperty("IntNumberToBytesConverterProperty")!; - var intNumberToStringConverterProperty = runtimeEntityType.FindProperty("IntNumberToStringConverterProperty")!; - var nullIntToNullStringConverterProperty = runtimeEntityType.FindProperty("NullIntToNullStringConverterProperty")!; - var nullableBool = runtimeEntityType.FindProperty("NullableBool")!; - var nullableBoolArray = runtimeEntityType.FindProperty("NullableBoolArray")!; - var nullableBytes = runtimeEntityType.FindProperty("NullableBytes")!; - var nullableBytesArray = runtimeEntityType.FindProperty("NullableBytesArray")!; - var nullableChar = runtimeEntityType.FindProperty("NullableChar")!; - var nullableCharArray = runtimeEntityType.FindProperty("NullableCharArray")!; - var nullableDateOnly = runtimeEntityType.FindProperty("NullableDateOnly")!; - var nullableDateOnlyArray = runtimeEntityType.FindProperty("NullableDateOnlyArray")!; - var nullableDateTime = runtimeEntityType.FindProperty("NullableDateTime")!; - var nullableDateTimeArray = runtimeEntityType.FindProperty("NullableDateTimeArray")!; - var nullableDecimal = runtimeEntityType.FindProperty("NullableDecimal")!; - var nullableDecimalArray = runtimeEntityType.FindProperty("NullableDecimalArray")!; - var nullableDouble = runtimeEntityType.FindProperty("NullableDouble")!; - var nullableDoubleArray = runtimeEntityType.FindProperty("NullableDoubleArray")!; - var nullableEnum16 = runtimeEntityType.FindProperty("NullableEnum16")!; - var nullableEnum16Array = runtimeEntityType.FindProperty("NullableEnum16Array")!; - var nullableEnum16AsString = runtimeEntityType.FindProperty("NullableEnum16AsString")!; - var nullableEnum16AsStringArray = runtimeEntityType.FindProperty("NullableEnum16AsStringArray")!; - var nullableEnum16AsStringCollection = runtimeEntityType.FindProperty("NullableEnum16AsStringCollection")!; - var nullableEnum16Collection = runtimeEntityType.FindProperty("NullableEnum16Collection")!; - var nullableEnum32 = runtimeEntityType.FindProperty("NullableEnum32")!; - var nullableEnum32Array = runtimeEntityType.FindProperty("NullableEnum32Array")!; - var nullableEnum32AsString = runtimeEntityType.FindProperty("NullableEnum32AsString")!; - var nullableEnum32AsStringArray = runtimeEntityType.FindProperty("NullableEnum32AsStringArray")!; - var nullableEnum32AsStringCollection = runtimeEntityType.FindProperty("NullableEnum32AsStringCollection")!; - var nullableEnum32Collection = runtimeEntityType.FindProperty("NullableEnum32Collection")!; - var nullableEnum64 = runtimeEntityType.FindProperty("NullableEnum64")!; - var nullableEnum64Array = runtimeEntityType.FindProperty("NullableEnum64Array")!; - var nullableEnum64AsString = runtimeEntityType.FindProperty("NullableEnum64AsString")!; - var nullableEnum64AsStringArray = runtimeEntityType.FindProperty("NullableEnum64AsStringArray")!; - var nullableEnum64AsStringCollection = runtimeEntityType.FindProperty("NullableEnum64AsStringCollection")!; - var nullableEnum64Collection = runtimeEntityType.FindProperty("NullableEnum64Collection")!; - var nullableEnum8 = runtimeEntityType.FindProperty("NullableEnum8")!; - var nullableEnum8Array = runtimeEntityType.FindProperty("NullableEnum8Array")!; - var nullableEnum8AsString = runtimeEntityType.FindProperty("NullableEnum8AsString")!; - var nullableEnum8AsStringArray = runtimeEntityType.FindProperty("NullableEnum8AsStringArray")!; - var nullableEnum8AsStringCollection = runtimeEntityType.FindProperty("NullableEnum8AsStringCollection")!; - var nullableEnum8Collection = runtimeEntityType.FindProperty("NullableEnum8Collection")!; - var nullableEnumU16 = runtimeEntityType.FindProperty("NullableEnumU16")!; - var nullableEnumU16Array = runtimeEntityType.FindProperty("NullableEnumU16Array")!; - var nullableEnumU16AsString = runtimeEntityType.FindProperty("NullableEnumU16AsString")!; - var nullableEnumU16AsStringArray = runtimeEntityType.FindProperty("NullableEnumU16AsStringArray")!; - var nullableEnumU16AsStringCollection = runtimeEntityType.FindProperty("NullableEnumU16AsStringCollection")!; - var nullableEnumU16Collection = runtimeEntityType.FindProperty("NullableEnumU16Collection")!; - var nullableEnumU32 = runtimeEntityType.FindProperty("NullableEnumU32")!; - var nullableEnumU32Array = runtimeEntityType.FindProperty("NullableEnumU32Array")!; - var nullableEnumU32AsString = runtimeEntityType.FindProperty("NullableEnumU32AsString")!; - var nullableEnumU32AsStringArray = runtimeEntityType.FindProperty("NullableEnumU32AsStringArray")!; - var nullableEnumU32AsStringCollection = runtimeEntityType.FindProperty("NullableEnumU32AsStringCollection")!; - var nullableEnumU32Collection = runtimeEntityType.FindProperty("NullableEnumU32Collection")!; - var nullableEnumU64 = runtimeEntityType.FindProperty("NullableEnumU64")!; - var nullableEnumU64Array = runtimeEntityType.FindProperty("NullableEnumU64Array")!; - var nullableEnumU64AsString = runtimeEntityType.FindProperty("NullableEnumU64AsString")!; - var nullableEnumU64AsStringArray = runtimeEntityType.FindProperty("NullableEnumU64AsStringArray")!; - var nullableEnumU64AsStringCollection = runtimeEntityType.FindProperty("NullableEnumU64AsStringCollection")!; - var nullableEnumU64Collection = runtimeEntityType.FindProperty("NullableEnumU64Collection")!; - var nullableEnumU8 = runtimeEntityType.FindProperty("NullableEnumU8")!; - var nullableEnumU8Array = runtimeEntityType.FindProperty("NullableEnumU8Array")!; - var nullableEnumU8AsString = runtimeEntityType.FindProperty("NullableEnumU8AsString")!; - var nullableEnumU8AsStringArray = runtimeEntityType.FindProperty("NullableEnumU8AsStringArray")!; - var nullableEnumU8AsStringCollection = runtimeEntityType.FindProperty("NullableEnumU8AsStringCollection")!; - var nullableEnumU8Collection = runtimeEntityType.FindProperty("NullableEnumU8Collection")!; - var nullableFloat = runtimeEntityType.FindProperty("NullableFloat")!; - var nullableFloatArray = runtimeEntityType.FindProperty("NullableFloatArray")!; - var nullableGuid = runtimeEntityType.FindProperty("NullableGuid")!; - var nullableGuidArray = runtimeEntityType.FindProperty("NullableGuidArray")!; - var nullableIPAddress = runtimeEntityType.FindProperty("NullableIPAddress")!; - var nullableIPAddressArray = runtimeEntityType.FindProperty("NullableIPAddressArray")!; - var nullableInt16 = runtimeEntityType.FindProperty("NullableInt16")!; - var nullableInt16Array = runtimeEntityType.FindProperty("NullableInt16Array")!; - var nullableInt32 = runtimeEntityType.FindProperty("NullableInt32")!; - var nullableInt32Array = runtimeEntityType.FindProperty("NullableInt32Array")!; - var nullableInt64 = runtimeEntityType.FindProperty("NullableInt64")!; - var nullableInt64Array = runtimeEntityType.FindProperty("NullableInt64Array")!; - var nullableInt8 = runtimeEntityType.FindProperty("NullableInt8")!; - var nullableInt8Array = runtimeEntityType.FindProperty("NullableInt8Array")!; - var nullablePhysicalAddress = runtimeEntityType.FindProperty("NullablePhysicalAddress")!; - var nullablePhysicalAddressArray = runtimeEntityType.FindProperty("NullablePhysicalAddressArray")!; - var nullableString = runtimeEntityType.FindProperty("NullableString")!; - var nullableStringArray = runtimeEntityType.FindProperty("NullableStringArray")!; - var nullableTimeOnly = runtimeEntityType.FindProperty("NullableTimeOnly")!; - var nullableTimeOnlyArray = runtimeEntityType.FindProperty("NullableTimeOnlyArray")!; - var nullableTimeSpan = runtimeEntityType.FindProperty("NullableTimeSpan")!; - var nullableTimeSpanArray = runtimeEntityType.FindProperty("NullableTimeSpanArray")!; - var nullableUInt16 = runtimeEntityType.FindProperty("NullableUInt16")!; - var nullableUInt16Array = runtimeEntityType.FindProperty("NullableUInt16Array")!; - var nullableUInt32 = runtimeEntityType.FindProperty("NullableUInt32")!; - var nullableUInt32Array = runtimeEntityType.FindProperty("NullableUInt32Array")!; - var nullableUInt64 = runtimeEntityType.FindProperty("NullableUInt64")!; - var nullableUInt64Array = runtimeEntityType.FindProperty("NullableUInt64Array")!; - var nullableUInt8 = runtimeEntityType.FindProperty("NullableUInt8")!; - var nullableUInt8Array = runtimeEntityType.FindProperty("NullableUInt8Array")!; - var nullableUri = runtimeEntityType.FindProperty("NullableUri")!; - var nullableUriArray = runtimeEntityType.FindProperty("NullableUriArray")!; - var physicalAddress = runtimeEntityType.FindProperty("PhysicalAddress")!; - var physicalAddressArray = runtimeEntityType.FindProperty("PhysicalAddressArray")!; - var physicalAddressToBytesConverterProperty = runtimeEntityType.FindProperty("PhysicalAddressToBytesConverterProperty")!; - var physicalAddressToStringConverterProperty = runtimeEntityType.FindProperty("PhysicalAddressToStringConverterProperty")!; - var @string = runtimeEntityType.FindProperty("String")!; - var stringArray = runtimeEntityType.FindProperty("StringArray")!; - var stringToBoolConverterProperty = runtimeEntityType.FindProperty("StringToBoolConverterProperty")!; - var stringToBytesConverterProperty = runtimeEntityType.FindProperty("StringToBytesConverterProperty")!; - var stringToCharConverterProperty = runtimeEntityType.FindProperty("StringToCharConverterProperty")!; - var stringToDateOnlyConverterProperty = runtimeEntityType.FindProperty("StringToDateOnlyConverterProperty")!; - var stringToDateTimeConverterProperty = runtimeEntityType.FindProperty("StringToDateTimeConverterProperty")!; - var stringToDateTimeOffsetConverterProperty = runtimeEntityType.FindProperty("StringToDateTimeOffsetConverterProperty")!; - var stringToDecimalNumberConverterProperty = runtimeEntityType.FindProperty("StringToDecimalNumberConverterProperty")!; - var stringToDoubleNumberConverterProperty = runtimeEntityType.FindProperty("StringToDoubleNumberConverterProperty")!; - var stringToEnumConverterProperty = runtimeEntityType.FindProperty("StringToEnumConverterProperty")!; - var stringToGuidConverterProperty = runtimeEntityType.FindProperty("StringToGuidConverterProperty")!; - var stringToIntNumberConverterProperty = runtimeEntityType.FindProperty("StringToIntNumberConverterProperty")!; - var stringToTimeOnlyConverterProperty = runtimeEntityType.FindProperty("StringToTimeOnlyConverterProperty")!; - var stringToTimeSpanConverterProperty = runtimeEntityType.FindProperty("StringToTimeSpanConverterProperty")!; - var stringToUriConverterProperty = runtimeEntityType.FindProperty("StringToUriConverterProperty")!; - var timeOnly = runtimeEntityType.FindProperty("TimeOnly")!; - var timeOnlyArray = runtimeEntityType.FindProperty("TimeOnlyArray")!; - var timeOnlyToStringConverterProperty = runtimeEntityType.FindProperty("TimeOnlyToStringConverterProperty")!; - var timeOnlyToTicksConverterProperty = runtimeEntityType.FindProperty("TimeOnlyToTicksConverterProperty")!; - var timeSpan = runtimeEntityType.FindProperty("TimeSpan")!; - var timeSpanArray = runtimeEntityType.FindProperty("TimeSpanArray")!; - var timeSpanToStringConverterProperty = runtimeEntityType.FindProperty("TimeSpanToStringConverterProperty")!; - var timeSpanToTicksConverterProperty = runtimeEntityType.FindProperty("TimeSpanToTicksConverterProperty")!; - var uInt16 = runtimeEntityType.FindProperty("UInt16")!; - var uInt16Array = runtimeEntityType.FindProperty("UInt16Array")!; - var uInt32 = runtimeEntityType.FindProperty("UInt32")!; - var uInt32Array = runtimeEntityType.FindProperty("UInt32Array")!; - var uInt64 = runtimeEntityType.FindProperty("UInt64")!; - var uInt64Array = runtimeEntityType.FindProperty("UInt64Array")!; - var uInt8 = runtimeEntityType.FindProperty("UInt8")!; - var uInt8Array = runtimeEntityType.FindProperty("UInt8Array")!; - var uri = runtimeEntityType.FindProperty("Uri")!; - var uriArray = runtimeEntityType.FindProperty("UriArray")!; - var uriToStringConverterProperty = runtimeEntityType.FindProperty("UriToStringConverterProperty")!; + var id = runtimeEntityType.FindProperty("Id"); + var @bool = runtimeEntityType.FindProperty("Bool"); + var boolArray = runtimeEntityType.FindProperty("BoolArray"); + var boolToStringConverterProperty = runtimeEntityType.FindProperty("BoolToStringConverterProperty"); + var boolToTwoValuesConverterProperty = runtimeEntityType.FindProperty("BoolToTwoValuesConverterProperty"); + var boolToZeroOneConverterProperty = runtimeEntityType.FindProperty("BoolToZeroOneConverterProperty"); + var bytes = runtimeEntityType.FindProperty("Bytes"); + var bytesArray = runtimeEntityType.FindProperty("BytesArray"); + var bytesToStringConverterProperty = runtimeEntityType.FindProperty("BytesToStringConverterProperty"); + var castingConverterProperty = runtimeEntityType.FindProperty("CastingConverterProperty"); + var @char = runtimeEntityType.FindProperty("Char"); + var charArray = runtimeEntityType.FindProperty("CharArray"); + var charToStringConverterProperty = runtimeEntityType.FindProperty("CharToStringConverterProperty"); + var dateOnly = runtimeEntityType.FindProperty("DateOnly"); + var dateOnlyArray = runtimeEntityType.FindProperty("DateOnlyArray"); + var dateOnlyToStringConverterProperty = runtimeEntityType.FindProperty("DateOnlyToStringConverterProperty"); + var dateTime = runtimeEntityType.FindProperty("DateTime"); + var dateTimeArray = runtimeEntityType.FindProperty("DateTimeArray"); + var dateTimeOffsetToBinaryConverterProperty = runtimeEntityType.FindProperty("DateTimeOffsetToBinaryConverterProperty"); + var dateTimeOffsetToBytesConverterProperty = runtimeEntityType.FindProperty("DateTimeOffsetToBytesConverterProperty"); + var dateTimeOffsetToStringConverterProperty = runtimeEntityType.FindProperty("DateTimeOffsetToStringConverterProperty"); + var dateTimeToBinaryConverterProperty = runtimeEntityType.FindProperty("DateTimeToBinaryConverterProperty"); + var dateTimeToStringConverterProperty = runtimeEntityType.FindProperty("DateTimeToStringConverterProperty"); + var dateTimeToTicksConverterProperty = runtimeEntityType.FindProperty("DateTimeToTicksConverterProperty"); + var @decimal = runtimeEntityType.FindProperty("Decimal"); + var decimalArray = runtimeEntityType.FindProperty("DecimalArray"); + var decimalNumberToBytesConverterProperty = runtimeEntityType.FindProperty("DecimalNumberToBytesConverterProperty"); + var decimalNumberToStringConverterProperty = runtimeEntityType.FindProperty("DecimalNumberToStringConverterProperty"); + var @double = runtimeEntityType.FindProperty("Double"); + var doubleArray = runtimeEntityType.FindProperty("DoubleArray"); + var doubleNumberToBytesConverterProperty = runtimeEntityType.FindProperty("DoubleNumberToBytesConverterProperty"); + var doubleNumberToStringConverterProperty = runtimeEntityType.FindProperty("DoubleNumberToStringConverterProperty"); + var enum16 = runtimeEntityType.FindProperty("Enum16"); + var enum16Array = runtimeEntityType.FindProperty("Enum16Array"); + var enum16AsString = runtimeEntityType.FindProperty("Enum16AsString"); + var enum16AsStringArray = runtimeEntityType.FindProperty("Enum16AsStringArray"); + var enum16AsStringCollection = runtimeEntityType.FindProperty("Enum16AsStringCollection"); + var enum16Collection = runtimeEntityType.FindProperty("Enum16Collection"); + var enum32 = runtimeEntityType.FindProperty("Enum32"); + var enum32Array = runtimeEntityType.FindProperty("Enum32Array"); + var enum32AsString = runtimeEntityType.FindProperty("Enum32AsString"); + var enum32AsStringArray = runtimeEntityType.FindProperty("Enum32AsStringArray"); + var enum32AsStringCollection = runtimeEntityType.FindProperty("Enum32AsStringCollection"); + var enum32Collection = runtimeEntityType.FindProperty("Enum32Collection"); + var enum64 = runtimeEntityType.FindProperty("Enum64"); + var enum64Array = runtimeEntityType.FindProperty("Enum64Array"); + var enum64AsString = runtimeEntityType.FindProperty("Enum64AsString"); + var enum64AsStringArray = runtimeEntityType.FindProperty("Enum64AsStringArray"); + var enum64AsStringCollection = runtimeEntityType.FindProperty("Enum64AsStringCollection"); + var enum64Collection = runtimeEntityType.FindProperty("Enum64Collection"); + var enum8 = runtimeEntityType.FindProperty("Enum8"); + var enum8Array = runtimeEntityType.FindProperty("Enum8Array"); + var enum8AsString = runtimeEntityType.FindProperty("Enum8AsString"); + var enum8AsStringArray = runtimeEntityType.FindProperty("Enum8AsStringArray"); + var enum8AsStringCollection = runtimeEntityType.FindProperty("Enum8AsStringCollection"); + var enum8Collection = runtimeEntityType.FindProperty("Enum8Collection"); + var enumToNumberConverterProperty = runtimeEntityType.FindProperty("EnumToNumberConverterProperty"); + var enumToStringConverterProperty = runtimeEntityType.FindProperty("EnumToStringConverterProperty"); + var enumU16 = runtimeEntityType.FindProperty("EnumU16"); + var enumU16Array = runtimeEntityType.FindProperty("EnumU16Array"); + var enumU16AsString = runtimeEntityType.FindProperty("EnumU16AsString"); + var enumU16AsStringArray = runtimeEntityType.FindProperty("EnumU16AsStringArray"); + var enumU16AsStringCollection = runtimeEntityType.FindProperty("EnumU16AsStringCollection"); + var enumU16Collection = runtimeEntityType.FindProperty("EnumU16Collection"); + var enumU32 = runtimeEntityType.FindProperty("EnumU32"); + var enumU32Array = runtimeEntityType.FindProperty("EnumU32Array"); + var enumU32AsString = runtimeEntityType.FindProperty("EnumU32AsString"); + var enumU32AsStringArray = runtimeEntityType.FindProperty("EnumU32AsStringArray"); + var enumU32AsStringCollection = runtimeEntityType.FindProperty("EnumU32AsStringCollection"); + var enumU32Collection = runtimeEntityType.FindProperty("EnumU32Collection"); + var enumU64 = runtimeEntityType.FindProperty("EnumU64"); + var enumU64Array = runtimeEntityType.FindProperty("EnumU64Array"); + var enumU64AsString = runtimeEntityType.FindProperty("EnumU64AsString"); + var enumU64AsStringArray = runtimeEntityType.FindProperty("EnumU64AsStringArray"); + var enumU64AsStringCollection = runtimeEntityType.FindProperty("EnumU64AsStringCollection"); + var enumU64Collection = runtimeEntityType.FindProperty("EnumU64Collection"); + var enumU8 = runtimeEntityType.FindProperty("EnumU8"); + var enumU8Array = runtimeEntityType.FindProperty("EnumU8Array"); + var enumU8AsString = runtimeEntityType.FindProperty("EnumU8AsString"); + var enumU8AsStringArray = runtimeEntityType.FindProperty("EnumU8AsStringArray"); + var enumU8AsStringCollection = runtimeEntityType.FindProperty("EnumU8AsStringCollection"); + var enumU8Collection = runtimeEntityType.FindProperty("EnumU8Collection"); + var @float = runtimeEntityType.FindProperty("Float"); + var floatArray = runtimeEntityType.FindProperty("FloatArray"); + var guid = runtimeEntityType.FindProperty("Guid"); + var guidArray = runtimeEntityType.FindProperty("GuidArray"); + var guidToBytesConverterProperty = runtimeEntityType.FindProperty("GuidToBytesConverterProperty"); + var guidToStringConverterProperty = runtimeEntityType.FindProperty("GuidToStringConverterProperty"); + var iPAddress = runtimeEntityType.FindProperty("IPAddress"); + var iPAddressArray = runtimeEntityType.FindProperty("IPAddressArray"); + var iPAddressToBytesConverterProperty = runtimeEntityType.FindProperty("IPAddressToBytesConverterProperty"); + var iPAddressToStringConverterProperty = runtimeEntityType.FindProperty("IPAddressToStringConverterProperty"); + var int16 = runtimeEntityType.FindProperty("Int16"); + var int16Array = runtimeEntityType.FindProperty("Int16Array"); + var int32 = runtimeEntityType.FindProperty("Int32"); + var int32Array = runtimeEntityType.FindProperty("Int32Array"); + var int64 = runtimeEntityType.FindProperty("Int64"); + var int64Array = runtimeEntityType.FindProperty("Int64Array"); + var int8 = runtimeEntityType.FindProperty("Int8"); + var int8Array = runtimeEntityType.FindProperty("Int8Array"); + var intNumberToBytesConverterProperty = runtimeEntityType.FindProperty("IntNumberToBytesConverterProperty"); + var intNumberToStringConverterProperty = runtimeEntityType.FindProperty("IntNumberToStringConverterProperty"); + var nullIntToNullStringConverterProperty = runtimeEntityType.FindProperty("NullIntToNullStringConverterProperty"); + var nullableBool = runtimeEntityType.FindProperty("NullableBool"); + var nullableBoolArray = runtimeEntityType.FindProperty("NullableBoolArray"); + var nullableBytes = runtimeEntityType.FindProperty("NullableBytes"); + var nullableBytesArray = runtimeEntityType.FindProperty("NullableBytesArray"); + var nullableChar = runtimeEntityType.FindProperty("NullableChar"); + var nullableCharArray = runtimeEntityType.FindProperty("NullableCharArray"); + var nullableDateOnly = runtimeEntityType.FindProperty("NullableDateOnly"); + var nullableDateOnlyArray = runtimeEntityType.FindProperty("NullableDateOnlyArray"); + var nullableDateTime = runtimeEntityType.FindProperty("NullableDateTime"); + var nullableDateTimeArray = runtimeEntityType.FindProperty("NullableDateTimeArray"); + var nullableDecimal = runtimeEntityType.FindProperty("NullableDecimal"); + var nullableDecimalArray = runtimeEntityType.FindProperty("NullableDecimalArray"); + var nullableDouble = runtimeEntityType.FindProperty("NullableDouble"); + var nullableDoubleArray = runtimeEntityType.FindProperty("NullableDoubleArray"); + var nullableEnum16 = runtimeEntityType.FindProperty("NullableEnum16"); + var nullableEnum16Array = runtimeEntityType.FindProperty("NullableEnum16Array"); + var nullableEnum16AsString = runtimeEntityType.FindProperty("NullableEnum16AsString"); + var nullableEnum16AsStringArray = runtimeEntityType.FindProperty("NullableEnum16AsStringArray"); + var nullableEnum16AsStringCollection = runtimeEntityType.FindProperty("NullableEnum16AsStringCollection"); + var nullableEnum16Collection = runtimeEntityType.FindProperty("NullableEnum16Collection"); + var nullableEnum32 = runtimeEntityType.FindProperty("NullableEnum32"); + var nullableEnum32Array = runtimeEntityType.FindProperty("NullableEnum32Array"); + var nullableEnum32AsString = runtimeEntityType.FindProperty("NullableEnum32AsString"); + var nullableEnum32AsStringArray = runtimeEntityType.FindProperty("NullableEnum32AsStringArray"); + var nullableEnum32AsStringCollection = runtimeEntityType.FindProperty("NullableEnum32AsStringCollection"); + var nullableEnum32Collection = runtimeEntityType.FindProperty("NullableEnum32Collection"); + var nullableEnum64 = runtimeEntityType.FindProperty("NullableEnum64"); + var nullableEnum64Array = runtimeEntityType.FindProperty("NullableEnum64Array"); + var nullableEnum64AsString = runtimeEntityType.FindProperty("NullableEnum64AsString"); + var nullableEnum64AsStringArray = runtimeEntityType.FindProperty("NullableEnum64AsStringArray"); + var nullableEnum64AsStringCollection = runtimeEntityType.FindProperty("NullableEnum64AsStringCollection"); + var nullableEnum64Collection = runtimeEntityType.FindProperty("NullableEnum64Collection"); + var nullableEnum8 = runtimeEntityType.FindProperty("NullableEnum8"); + var nullableEnum8Array = runtimeEntityType.FindProperty("NullableEnum8Array"); + var nullableEnum8AsString = runtimeEntityType.FindProperty("NullableEnum8AsString"); + var nullableEnum8AsStringArray = runtimeEntityType.FindProperty("NullableEnum8AsStringArray"); + var nullableEnum8AsStringCollection = runtimeEntityType.FindProperty("NullableEnum8AsStringCollection"); + var nullableEnum8Collection = runtimeEntityType.FindProperty("NullableEnum8Collection"); + var nullableEnumU16 = runtimeEntityType.FindProperty("NullableEnumU16"); + var nullableEnumU16Array = runtimeEntityType.FindProperty("NullableEnumU16Array"); + var nullableEnumU16AsString = runtimeEntityType.FindProperty("NullableEnumU16AsString"); + var nullableEnumU16AsStringArray = runtimeEntityType.FindProperty("NullableEnumU16AsStringArray"); + var nullableEnumU16AsStringCollection = runtimeEntityType.FindProperty("NullableEnumU16AsStringCollection"); + var nullableEnumU16Collection = runtimeEntityType.FindProperty("NullableEnumU16Collection"); + var nullableEnumU32 = runtimeEntityType.FindProperty("NullableEnumU32"); + var nullableEnumU32Array = runtimeEntityType.FindProperty("NullableEnumU32Array"); + var nullableEnumU32AsString = runtimeEntityType.FindProperty("NullableEnumU32AsString"); + var nullableEnumU32AsStringArray = runtimeEntityType.FindProperty("NullableEnumU32AsStringArray"); + var nullableEnumU32AsStringCollection = runtimeEntityType.FindProperty("NullableEnumU32AsStringCollection"); + var nullableEnumU32Collection = runtimeEntityType.FindProperty("NullableEnumU32Collection"); + var nullableEnumU64 = runtimeEntityType.FindProperty("NullableEnumU64"); + var nullableEnumU64Array = runtimeEntityType.FindProperty("NullableEnumU64Array"); + var nullableEnumU64AsString = runtimeEntityType.FindProperty("NullableEnumU64AsString"); + var nullableEnumU64AsStringArray = runtimeEntityType.FindProperty("NullableEnumU64AsStringArray"); + var nullableEnumU64AsStringCollection = runtimeEntityType.FindProperty("NullableEnumU64AsStringCollection"); + var nullableEnumU64Collection = runtimeEntityType.FindProperty("NullableEnumU64Collection"); + var nullableEnumU8 = runtimeEntityType.FindProperty("NullableEnumU8"); + var nullableEnumU8Array = runtimeEntityType.FindProperty("NullableEnumU8Array"); + var nullableEnumU8AsString = runtimeEntityType.FindProperty("NullableEnumU8AsString"); + var nullableEnumU8AsStringArray = runtimeEntityType.FindProperty("NullableEnumU8AsStringArray"); + var nullableEnumU8AsStringCollection = runtimeEntityType.FindProperty("NullableEnumU8AsStringCollection"); + var nullableEnumU8Collection = runtimeEntityType.FindProperty("NullableEnumU8Collection"); + var nullableFloat = runtimeEntityType.FindProperty("NullableFloat"); + var nullableFloatArray = runtimeEntityType.FindProperty("NullableFloatArray"); + var nullableGuid = runtimeEntityType.FindProperty("NullableGuid"); + var nullableGuidArray = runtimeEntityType.FindProperty("NullableGuidArray"); + var nullableIPAddress = runtimeEntityType.FindProperty("NullableIPAddress"); + var nullableIPAddressArray = runtimeEntityType.FindProperty("NullableIPAddressArray"); + var nullableInt16 = runtimeEntityType.FindProperty("NullableInt16"); + var nullableInt16Array = runtimeEntityType.FindProperty("NullableInt16Array"); + var nullableInt32 = runtimeEntityType.FindProperty("NullableInt32"); + var nullableInt32Array = runtimeEntityType.FindProperty("NullableInt32Array"); + var nullableInt64 = runtimeEntityType.FindProperty("NullableInt64"); + var nullableInt64Array = runtimeEntityType.FindProperty("NullableInt64Array"); + var nullableInt8 = runtimeEntityType.FindProperty("NullableInt8"); + var nullableInt8Array = runtimeEntityType.FindProperty("NullableInt8Array"); + var nullablePhysicalAddress = runtimeEntityType.FindProperty("NullablePhysicalAddress"); + var nullablePhysicalAddressArray = runtimeEntityType.FindProperty("NullablePhysicalAddressArray"); + var nullableString = runtimeEntityType.FindProperty("NullableString"); + var nullableStringArray = runtimeEntityType.FindProperty("NullableStringArray"); + var nullableTimeOnly = runtimeEntityType.FindProperty("NullableTimeOnly"); + var nullableTimeOnlyArray = runtimeEntityType.FindProperty("NullableTimeOnlyArray"); + var nullableTimeSpan = runtimeEntityType.FindProperty("NullableTimeSpan"); + var nullableTimeSpanArray = runtimeEntityType.FindProperty("NullableTimeSpanArray"); + var nullableUInt16 = runtimeEntityType.FindProperty("NullableUInt16"); + var nullableUInt16Array = runtimeEntityType.FindProperty("NullableUInt16Array"); + var nullableUInt32 = runtimeEntityType.FindProperty("NullableUInt32"); + var nullableUInt32Array = runtimeEntityType.FindProperty("NullableUInt32Array"); + var nullableUInt64 = runtimeEntityType.FindProperty("NullableUInt64"); + var nullableUInt64Array = runtimeEntityType.FindProperty("NullableUInt64Array"); + var nullableUInt8 = runtimeEntityType.FindProperty("NullableUInt8"); + var nullableUInt8Array = runtimeEntityType.FindProperty("NullableUInt8Array"); + var nullableUri = runtimeEntityType.FindProperty("NullableUri"); + var nullableUriArray = runtimeEntityType.FindProperty("NullableUriArray"); + var physicalAddress = runtimeEntityType.FindProperty("PhysicalAddress"); + var physicalAddressArray = runtimeEntityType.FindProperty("PhysicalAddressArray"); + var physicalAddressToBytesConverterProperty = runtimeEntityType.FindProperty("PhysicalAddressToBytesConverterProperty"); + var physicalAddressToStringConverterProperty = runtimeEntityType.FindProperty("PhysicalAddressToStringConverterProperty"); + var @string = runtimeEntityType.FindProperty("String"); + var stringArray = runtimeEntityType.FindProperty("StringArray"); + var stringToBoolConverterProperty = runtimeEntityType.FindProperty("StringToBoolConverterProperty"); + var stringToBytesConverterProperty = runtimeEntityType.FindProperty("StringToBytesConverterProperty"); + var stringToCharConverterProperty = runtimeEntityType.FindProperty("StringToCharConverterProperty"); + var stringToDateOnlyConverterProperty = runtimeEntityType.FindProperty("StringToDateOnlyConverterProperty"); + var stringToDateTimeConverterProperty = runtimeEntityType.FindProperty("StringToDateTimeConverterProperty"); + var stringToDateTimeOffsetConverterProperty = runtimeEntityType.FindProperty("StringToDateTimeOffsetConverterProperty"); + var stringToDecimalNumberConverterProperty = runtimeEntityType.FindProperty("StringToDecimalNumberConverterProperty"); + var stringToDoubleNumberConverterProperty = runtimeEntityType.FindProperty("StringToDoubleNumberConverterProperty"); + var stringToEnumConverterProperty = runtimeEntityType.FindProperty("StringToEnumConverterProperty"); + var stringToGuidConverterProperty = runtimeEntityType.FindProperty("StringToGuidConverterProperty"); + var stringToIntNumberConverterProperty = runtimeEntityType.FindProperty("StringToIntNumberConverterProperty"); + var stringToTimeOnlyConverterProperty = runtimeEntityType.FindProperty("StringToTimeOnlyConverterProperty"); + var stringToTimeSpanConverterProperty = runtimeEntityType.FindProperty("StringToTimeSpanConverterProperty"); + var stringToUriConverterProperty = runtimeEntityType.FindProperty("StringToUriConverterProperty"); + var timeOnly = runtimeEntityType.FindProperty("TimeOnly"); + var timeOnlyArray = runtimeEntityType.FindProperty("TimeOnlyArray"); + var timeOnlyToStringConverterProperty = runtimeEntityType.FindProperty("TimeOnlyToStringConverterProperty"); + var timeOnlyToTicksConverterProperty = runtimeEntityType.FindProperty("TimeOnlyToTicksConverterProperty"); + var timeSpan = runtimeEntityType.FindProperty("TimeSpan"); + var timeSpanArray = runtimeEntityType.FindProperty("TimeSpanArray"); + var timeSpanToStringConverterProperty = runtimeEntityType.FindProperty("TimeSpanToStringConverterProperty"); + var timeSpanToTicksConverterProperty = runtimeEntityType.FindProperty("TimeSpanToTicksConverterProperty"); + var uInt16 = runtimeEntityType.FindProperty("UInt16"); + var uInt16Array = runtimeEntityType.FindProperty("UInt16Array"); + var uInt32 = runtimeEntityType.FindProperty("UInt32"); + var uInt32Array = runtimeEntityType.FindProperty("UInt32Array"); + var uInt64 = runtimeEntityType.FindProperty("UInt64"); + var uInt64Array = runtimeEntityType.FindProperty("UInt64Array"); + var uInt8 = runtimeEntityType.FindProperty("UInt8"); + var uInt8Array = runtimeEntityType.FindProperty("UInt8Array"); + var uri = runtimeEntityType.FindProperty("Uri"); + var uriArray = runtimeEntityType.FindProperty("UriArray"); + var uriToStringConverterProperty = runtimeEntityType.FindProperty("UriToStringConverterProperty"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/OwnedType0EntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/OwnedType0EntityType.cs index 89fac0fffa8..4418c95a5e3 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/OwnedType0EntityType.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/OwnedType0EntityType.cs @@ -90,25 +90,26 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas principalDerivedAlternateId.TypeMapping = SqliteGuidTypeMapping.Default; principalDerivedAlternateId.SetCurrentValueComparer(new EntryCurrentValueComparer(principalDerivedAlternateId)); - var id = runtimeEntityType.AddProperty( - "Id", + var __synthesizedOrdinal = runtimeEntityType.AddProperty( + "__synthesizedOrdinal", typeof(int), - valueGenerated: ValueGenerated.OnAdd, + valueGenerated: ValueGenerated.OnAddOrUpdate, + beforeSaveBehavior: PropertySaveBehavior.Ignore, afterSaveBehavior: PropertySaveBehavior.Throw, sentinel: 0); - id.SetAccessors( + __synthesizedOrdinal.SetAccessors( int (InternalEntityEntry entry) => (entry.FlaggedAsStoreGenerated(2) ? entry.ReadStoreGeneratedValue(2) : (entry.FlaggedAsTemporary(2) && entry.ReadShadowValue(2) == 0 ? entry.ReadTemporaryValue(2) : entry.ReadShadowValue(2))), int (InternalEntityEntry entry) => entry.ReadShadowValue(2), - int (InternalEntityEntry entry) => entry.ReadOriginalValue(id, 2), - int (InternalEntityEntry entry) => entry.ReadRelationshipSnapshotValue(id, 2), + int (InternalEntityEntry entry) => entry.ReadOriginalValue(__synthesizedOrdinal, 2), + int (InternalEntityEntry entry) => entry.ReadRelationshipSnapshotValue(__synthesizedOrdinal, 2), object (ValueBuffer valueBuffer) => valueBuffer[2]); - id.SetPropertyIndexes( + __synthesizedOrdinal.SetPropertyIndexes( index: 2, originalValueIndex: 2, shadowIndex: 2, relationshipIndex: 2, storeGenerationIndex: 2); - id.TypeMapping = IntTypeMapping.Default.Clone( + __synthesizedOrdinal.TypeMapping = IntTypeMapping.Default.Clone( comparer: new ValueComparer( bool (int v1, int v2) => v1 == v2, int (int v) => v, @@ -123,7 +124,7 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas int (int v) => v), mappingInfo: new RelationalTypeMappingInfo( storeTypeName: "INTEGER")); - id.SetCurrentValueComparer(new EntryCurrentValueComparer(id)); + __synthesizedOrdinal.SetCurrentValueComparer(new EntryCurrentValueComparer(__synthesizedOrdinal)); var details = runtimeEntityType.AddProperty( "Details", @@ -679,7 +680,7 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas storeGenerationIndex: -1); var key = runtimeEntityType.AddKey( - new[] { principalDerivedId, principalDerivedAlternateId, id }); + new[] { principalDerivedId, principalDerivedAlternateId, __synthesizedOrdinal }); runtimeEntityType.SetPrimaryKey(key); return runtimeEntityType; @@ -733,41 +734,41 @@ public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEnt public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var principalDerivedId = runtimeEntityType.FindProperty("PrincipalDerivedId")!; - var principalDerivedAlternateId = runtimeEntityType.FindProperty("PrincipalDerivedAlternateId")!; - var id = runtimeEntityType.FindProperty("Id")!; - var details = runtimeEntityType.FindProperty("Details")!; - var number = runtimeEntityType.FindProperty("Number")!; - var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray")!; - var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable")!; - var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList")!; - var refTypeList = runtimeEntityType.FindProperty("RefTypeList")!; - var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList")!; - var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList")!; - var key = runtimeEntityType.FindKey(new[] { principalDerivedId, principalDerivedAlternateId, id }); + var principalDerivedId = runtimeEntityType.FindProperty("PrincipalDerivedId"); + var principalDerivedAlternateId = runtimeEntityType.FindProperty("PrincipalDerivedAlternateId"); + var __synthesizedOrdinal = runtimeEntityType.FindProperty("__synthesizedOrdinal"); + var details = runtimeEntityType.FindProperty("Details"); + var number = runtimeEntityType.FindProperty("Number"); + var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray"); + var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable"); + var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList"); + var refTypeList = runtimeEntityType.FindProperty("RefTypeList"); + var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList"); + var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList"); + var key = runtimeEntityType.FindKey(new[] { principalDerivedId, principalDerivedAlternateId, __synthesizedOrdinal }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateCompositeFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory>(key)); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { var entity7 = ((CompiledModelTestBase.OwnedType)(source.Entity)); - return ((ISnapshot)(new Snapshot, IList, List, DateTime[], IEnumerable, IList, List>(((ValueComparer)(((IProperty)principalDerivedId).GetValueComparer())).Snapshot(source.GetCurrentValue(principalDerivedId)), ((ValueComparer)(((IProperty)principalDerivedAlternateId).GetValueComparer())).Snapshot(source.GetCurrentValue(principalDerivedAlternateId)), ((ValueComparer)(((IProperty)id).GetValueComparer())).Snapshot(source.GetCurrentValue(id)), (source.GetCurrentValue(details) == null ? null : ((ValueComparer)(((IProperty)details).GetValueComparer())).Snapshot(source.GetCurrentValue(details))), ((ValueComparer)(((IProperty)number).GetValueComparer())).Snapshot(source.GetCurrentValue(number)), (((object)(source.GetCurrentValue(refTypeArray))) == null ? null : ((IPAddress[])(((ValueComparer)(((IProperty)refTypeArray).GetValueComparer())).Snapshot(((object)(source.GetCurrentValue(refTypeArray))))))), (((object)(source.GetCurrentValue>(refTypeEnumerable))) == null ? null : ((IEnumerable)(((ValueComparer)(((IProperty)refTypeEnumerable).GetValueComparer())).Snapshot(((object)(source.GetCurrentValue>(refTypeEnumerable))))))), (((object)(source.GetCurrentValue>(refTypeIList))) == null ? null : ((IList)(((ValueComparer)(((IProperty)refTypeIList).GetValueComparer())).Snapshot(((object)(source.GetCurrentValue>(refTypeIList))))))), (((object)(source.GetCurrentValue>(refTypeList))) == null ? null : ((List)(((ValueComparer)(((IProperty)refTypeList).GetValueComparer())).Snapshot(((object)(source.GetCurrentValue>(refTypeList))))))), (((IEnumerable)(source.GetCurrentValue(valueTypeArray))) == null ? null : ((DateTime[])(((ValueComparer>)(((IProperty)valueTypeArray).GetValueComparer())).Snapshot(((IEnumerable)(source.GetCurrentValue(valueTypeArray))))))), (source.GetCurrentValue>(valueTypeEnumerable) == null ? null : ((ValueComparer>)(((IProperty)valueTypeEnumerable).GetValueComparer())).Snapshot(source.GetCurrentValue>(valueTypeEnumerable))), (((IEnumerable)(source.GetCurrentValue>(valueTypeIList))) == null ? null : ((IList)(((ValueComparer>)(((IProperty)valueTypeIList).GetValueComparer())).Snapshot(((IEnumerable)(source.GetCurrentValue>(valueTypeIList))))))), (((IEnumerable)(source.GetCurrentValue>(valueTypeList))) == null ? null : ((List)(((ValueComparer>)(((IProperty)valueTypeList).GetValueComparer())).Snapshot(((IEnumerable)(source.GetCurrentValue>(valueTypeList)))))))))); + return ((ISnapshot)(new Snapshot, IList, List, DateTime[], IEnumerable, IList, List>(((ValueComparer)(((IProperty)principalDerivedId).GetValueComparer())).Snapshot(source.GetCurrentValue(principalDerivedId)), ((ValueComparer)(((IProperty)principalDerivedAlternateId).GetValueComparer())).Snapshot(source.GetCurrentValue(principalDerivedAlternateId)), ((ValueComparer)(((IProperty)__synthesizedOrdinal).GetValueComparer())).Snapshot(source.GetCurrentValue(__synthesizedOrdinal)), (source.GetCurrentValue(details) == null ? null : ((ValueComparer)(((IProperty)details).GetValueComparer())).Snapshot(source.GetCurrentValue(details))), ((ValueComparer)(((IProperty)number).GetValueComparer())).Snapshot(source.GetCurrentValue(number)), (((object)(source.GetCurrentValue(refTypeArray))) == null ? null : ((IPAddress[])(((ValueComparer)(((IProperty)refTypeArray).GetValueComparer())).Snapshot(((object)(source.GetCurrentValue(refTypeArray))))))), (((object)(source.GetCurrentValue>(refTypeEnumerable))) == null ? null : ((IEnumerable)(((ValueComparer)(((IProperty)refTypeEnumerable).GetValueComparer())).Snapshot(((object)(source.GetCurrentValue>(refTypeEnumerable))))))), (((object)(source.GetCurrentValue>(refTypeIList))) == null ? null : ((IList)(((ValueComparer)(((IProperty)refTypeIList).GetValueComparer())).Snapshot(((object)(source.GetCurrentValue>(refTypeIList))))))), (((object)(source.GetCurrentValue>(refTypeList))) == null ? null : ((List)(((ValueComparer)(((IProperty)refTypeList).GetValueComparer())).Snapshot(((object)(source.GetCurrentValue>(refTypeList))))))), (((IEnumerable)(source.GetCurrentValue(valueTypeArray))) == null ? null : ((DateTime[])(((ValueComparer>)(((IProperty)valueTypeArray).GetValueComparer())).Snapshot(((IEnumerable)(source.GetCurrentValue(valueTypeArray))))))), (source.GetCurrentValue>(valueTypeEnumerable) == null ? null : ((ValueComparer>)(((IProperty)valueTypeEnumerable).GetValueComparer())).Snapshot(source.GetCurrentValue>(valueTypeEnumerable))), (((IEnumerable)(source.GetCurrentValue>(valueTypeIList))) == null ? null : ((IList)(((ValueComparer>)(((IProperty)valueTypeIList).GetValueComparer())).Snapshot(((IEnumerable)(source.GetCurrentValue>(valueTypeIList))))))), (((IEnumerable)(source.GetCurrentValue>(valueTypeList))) == null ? null : ((List)(((ValueComparer>)(((IProperty)valueTypeList).GetValueComparer())).Snapshot(((IEnumerable)(source.GetCurrentValue>(valueTypeList)))))))))); }); runtimeEntityType.SetStoreGeneratedValuesFactory( - ISnapshot () => ((ISnapshot)(new Snapshot(((ValueComparer)(((IProperty)principalDerivedId).GetValueComparer())).Snapshot(default(long)), ((ValueComparer)(((IProperty)principalDerivedAlternateId).GetValueComparer())).Snapshot(default(Guid)), ((ValueComparer)(((IProperty)id).GetValueComparer())).Snapshot(default(int)))))); + ISnapshot () => ((ISnapshot)(new Snapshot(((ValueComparer)(((IProperty)principalDerivedId).GetValueComparer())).Snapshot(default(long)), ((ValueComparer)(((IProperty)principalDerivedAlternateId).GetValueComparer())).Snapshot(default(Guid)), ((ValueComparer)(((IProperty)__synthesizedOrdinal).GetValueComparer())).Snapshot(default(int)))))); runtimeEntityType.SetTemporaryValuesFactory( ISnapshot (InternalEntityEntry source) => ((ISnapshot)(new Snapshot(default(long), default(Guid), default(int))))); runtimeEntityType.SetShadowValuesFactory( - ISnapshot (IDictionary source) => ((ISnapshot)(new Snapshot((source.ContainsKey("PrincipalDerivedId") ? ((long)(source["PrincipalDerivedId"])) : 0L), (source.ContainsKey("PrincipalDerivedAlternateId") ? ((Guid)(source["PrincipalDerivedAlternateId"])) : new Guid("00000000-0000-0000-0000-000000000000")), (source.ContainsKey("Id") ? ((int)(source["Id"])) : 0))))); + ISnapshot (IDictionary source) => ((ISnapshot)(new Snapshot((source.ContainsKey("PrincipalDerivedId") ? ((long)(source["PrincipalDerivedId"])) : 0L), (source.ContainsKey("PrincipalDerivedAlternateId") ? ((Guid)(source["PrincipalDerivedAlternateId"])) : new Guid("00000000-0000-0000-0000-000000000000")), (source.ContainsKey("__synthesizedOrdinal") ? ((int)(source["__synthesizedOrdinal"])) : 0))))); runtimeEntityType.SetEmptyShadowValuesFactory( ISnapshot () => ((ISnapshot)(new Snapshot(default(long), default(Guid), default(int))))); runtimeEntityType.SetRelationshipSnapshotFactory( ISnapshot (InternalEntityEntry source) => { var entity7 = ((CompiledModelTestBase.OwnedType)(source.Entity)); - return ((ISnapshot)(new Snapshot(((ValueComparer)(((IProperty)principalDerivedId).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(principalDerivedId)), ((ValueComparer)(((IProperty)principalDerivedAlternateId).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(principalDerivedAlternateId)), ((ValueComparer)(((IProperty)id).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(id))))); + return ((ISnapshot)(new Snapshot(((ValueComparer)(((IProperty)principalDerivedId).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(principalDerivedId)), ((ValueComparer)(((IProperty)principalDerivedAlternateId).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(principalDerivedAlternateId)), ((ValueComparer)(((IProperty)__synthesizedOrdinal).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(__synthesizedOrdinal))))); }); runtimeEntityType.Counts = new PropertyCounts( propertyCount: 13, diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/OwnedTypeEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/OwnedTypeEntityType.cs index ec76266aef5..302a3c48557 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/OwnedTypeEntityType.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/OwnedTypeEntityType.cs @@ -709,18 +709,18 @@ public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEnt public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var principalBaseId = runtimeEntityType.FindProperty("PrincipalBaseId")!; - var principalBaseAlternateId = runtimeEntityType.FindProperty("PrincipalBaseAlternateId")!; - var details = runtimeEntityType.FindProperty("Details")!; - var number = runtimeEntityType.FindProperty("Number")!; - var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray")!; - var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable")!; - var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList")!; - var refTypeList = runtimeEntityType.FindProperty("RefTypeList")!; - var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList")!; - var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList")!; + var principalBaseId = runtimeEntityType.FindProperty("PrincipalBaseId"); + var principalBaseAlternateId = runtimeEntityType.FindProperty("PrincipalBaseAlternateId"); + var details = runtimeEntityType.FindProperty("Details"); + var number = runtimeEntityType.FindProperty("Number"); + var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray"); + var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable"); + var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList"); + var refTypeList = runtimeEntityType.FindProperty("RefTypeList"); + var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList"); + var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList"); var key = runtimeEntityType.FindKey(new[] { principalBaseId, principalBaseAlternateId }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateCompositeFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory>(key)); diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/PrincipalBaseEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/PrincipalBaseEntityType.cs index 7f1b92067de..d16e1bfa60f 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/PrincipalBaseEntityType.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/PrincipalBaseEntityType.cs @@ -83,9 +83,9 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas long (long v) => v), mappingInfo: new RelationalTypeMappingInfo( storeTypeName: "INTEGER")); - id.SetValueComparer(new NullableValueComparer(id.TypeMapping.Comparer)); - id.SetKeyValueComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); id.SetCurrentValueComparer(new EntryCurrentValueComparer(id)); + id.SetComparer(new NullableValueComparer(id.TypeMapping.Comparer)); + id.SetKeyComparer(new NullableValueComparer(id.TypeMapping.KeyComparer)); var alternateId = runtimeEntityType.AddProperty( "AlternateId", @@ -240,8 +240,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new ValueConverter( int (CompiledModelTestBase.AnEnum value) => ((int)(value)), CompiledModelTestBase.AnEnum (int value) => ((CompiledModelTestBase.AnEnum)(value))))); - enum2.SetValueComparer(new NullableValueComparer(enum2.TypeMapping.Comparer)); - enum2.SetKeyValueComparer(new NullableValueComparer(enum2.TypeMapping.KeyComparer)); + enum2.SetComparer(new NullableValueComparer(enum2.TypeMapping.Comparer)); + enum2.SetKeyComparer(new NullableValueComparer(enum2.TypeMapping.KeyComparer)); var flagsEnum1 = runtimeEntityType.AddProperty( "FlagsEnum1", @@ -908,29 +908,29 @@ public static RuntimeSkipNavigation CreateSkipNavigation1(RuntimeEntityType decl public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var alternateId = runtimeEntityType.FindProperty("AlternateId")!; - var discriminator = runtimeEntityType.FindProperty("Discriminator")!; - var enum1 = runtimeEntityType.FindProperty("Enum1")!; - var enum2 = runtimeEntityType.FindProperty("Enum2")!; - var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1")!; - var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2")!; - var point = runtimeEntityType.FindProperty("Point")!; - var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray")!; - var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable")!; - var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList")!; - var refTypeList = runtimeEntityType.FindProperty("RefTypeList")!; - var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList")!; - var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList")!; + var id = runtimeEntityType.FindProperty("Id"); + var alternateId = runtimeEntityType.FindProperty("AlternateId"); + var discriminator = runtimeEntityType.FindProperty("Discriminator"); + var enum1 = runtimeEntityType.FindProperty("Enum1"); + var enum2 = runtimeEntityType.FindProperty("Enum2"); + var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1"); + var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2"); + var point = runtimeEntityType.FindProperty("Point"); + var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray"); + var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable"); + var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList"); + var refTypeList = runtimeEntityType.FindProperty("RefTypeList"); + var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList"); + var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); var key0 = runtimeEntityType.FindKey(new[] { id, alternateId }); key0.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateCompositeFactory(key0)); key0.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory>(key0)); - var owned = runtimeEntityType.FindNavigation("Owned")!; + var owned = runtimeEntityType.FindNavigation("Owned"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { @@ -949,7 +949,7 @@ public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) ISnapshot (InternalEntityEntry source) => { var entity7 = ((CompiledModelTestBase.PrincipalBase)(source.Entity)); - return ((ISnapshot)(new Snapshot((source.GetCurrentValue(id) == null ? null : ((ValueComparer)(((IProperty)id).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(id))), ((ValueComparer)(((IProperty)alternateId).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(alternateId)), PrincipalBaseUnsafeAccessors._ownedField(entity7), null))); + return ((ISnapshot)(new Snapshot((source.GetCurrentValue(id) == null ? null : ((ValueComparer)(((IProperty)id).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(id))), ((ValueComparer)(((IProperty)alternateId).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(alternateId)), PrincipalBaseUnsafeAccessors._ownedField(entity7), (object)(null)))); }); runtimeEntityType.Counts = new PropertyCounts( propertyCount: 16, diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs index ca2ae795a65..f2b9562ce0d 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs @@ -353,11 +353,11 @@ public static RuntimeForeignKey CreateForeignKey2(RuntimeEntityType declaringEnt public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var derivedsId = runtimeEntityType.FindProperty("DerivedsId")!; - var derivedsAlternateId = runtimeEntityType.FindProperty("DerivedsAlternateId")!; - var principalsId = runtimeEntityType.FindProperty("PrincipalsId")!; - var principalsAlternateId = runtimeEntityType.FindProperty("PrincipalsAlternateId")!; - var rowid = runtimeEntityType.FindProperty("rowid")!; + var derivedsId = runtimeEntityType.FindProperty("DerivedsId"); + var derivedsAlternateId = runtimeEntityType.FindProperty("DerivedsAlternateId"); + var principalsId = runtimeEntityType.FindProperty("PrincipalsId"); + var principalsAlternateId = runtimeEntityType.FindProperty("PrincipalsAlternateId"); + var rowid = runtimeEntityType.FindProperty("rowid"); var key = runtimeEntityType.FindKey(new[] { derivedsId, derivedsAlternateId, principalsId, principalsAlternateId }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateCompositeFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory>(key)); diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/PrincipalDerivedEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/PrincipalDerivedEntityType.cs index 70eb6e3f353..26073ee6b59 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/PrincipalDerivedEntityType.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/PrincipalDerivedEntityType.cs @@ -88,25 +88,25 @@ public static RuntimeSkipNavigation CreateSkipNavigation1(RuntimeEntityType decl public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var alternateId = runtimeEntityType.FindProperty("AlternateId")!; - var discriminator = runtimeEntityType.FindProperty("Discriminator")!; - var enum1 = runtimeEntityType.FindProperty("Enum1")!; - var enum2 = runtimeEntityType.FindProperty("Enum2")!; - var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1")!; - var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2")!; - var point = runtimeEntityType.FindProperty("Point")!; - var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray")!; - var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable")!; - var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList")!; - var refTypeList = runtimeEntityType.FindProperty("RefTypeList")!; - var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray")!; - var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable")!; - var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList")!; - var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList")!; - var owned = runtimeEntityType.FindNavigation("Owned")!; - var dependent = runtimeEntityType.FindNavigation("Dependent")!; - var manyOwned = runtimeEntityType.FindNavigation("ManyOwned")!; + var id = runtimeEntityType.FindProperty("Id"); + var alternateId = runtimeEntityType.FindProperty("AlternateId"); + var discriminator = runtimeEntityType.FindProperty("Discriminator"); + var enum1 = runtimeEntityType.FindProperty("Enum1"); + var enum2 = runtimeEntityType.FindProperty("Enum2"); + var flagsEnum1 = runtimeEntityType.FindProperty("FlagsEnum1"); + var flagsEnum2 = runtimeEntityType.FindProperty("FlagsEnum2"); + var point = runtimeEntityType.FindProperty("Point"); + var refTypeArray = runtimeEntityType.FindProperty("RefTypeArray"); + var refTypeEnumerable = runtimeEntityType.FindProperty("RefTypeEnumerable"); + var refTypeIList = runtimeEntityType.FindProperty("RefTypeIList"); + var refTypeList = runtimeEntityType.FindProperty("RefTypeList"); + var valueTypeArray = runtimeEntityType.FindProperty("ValueTypeArray"); + var valueTypeEnumerable = runtimeEntityType.FindProperty("ValueTypeEnumerable"); + var valueTypeIList = runtimeEntityType.FindProperty("ValueTypeIList"); + var valueTypeList = runtimeEntityType.FindProperty("ValueTypeList"); + var owned = runtimeEntityType.FindNavigation("Owned"); + var dependent = runtimeEntityType.FindNavigation("Dependent"); + var manyOwned = runtimeEntityType.FindNavigation("ManyOwned"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { @@ -125,7 +125,7 @@ public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) ISnapshot (InternalEntityEntry source) => { var entity7 = ((CompiledModelTestBase.PrincipalDerived>)(source.Entity)); - return ((ISnapshot)(new Snapshot((source.GetCurrentValue(id) == null ? null : ((ValueComparer)(((IProperty)id).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(id))), ((ValueComparer)(((IProperty)alternateId).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(alternateId)), PrincipalBaseUnsafeAccessors._ownedField(entity7), null, PrincipalDerivedUnsafeAccessors>.Dependent(entity7), SnapshotFactoryFactory.SnapshotCollection(PrincipalDerivedUnsafeAccessors>.ManyOwned(entity7)), null))); + return ((ISnapshot)(new Snapshot((source.GetCurrentValue(id) == null ? null : ((ValueComparer)(((IProperty)id).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(id))), ((ValueComparer)(((IProperty)alternateId).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(alternateId)), PrincipalBaseUnsafeAccessors._ownedField(entity7), (object)(null), PrincipalDerivedUnsafeAccessors>.Dependent(entity7), SnapshotFactoryFactory.SnapshotCollection(PrincipalDerivedUnsafeAccessors>.ManyOwned(entity7)), (object)(null)))); }); runtimeEntityType.Counts = new PropertyCounts( propertyCount: 16, diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/CheckConstraints/DataEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/CheckConstraints/DataEntityType.cs index 359ca91cf9f..501200ed058 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/CheckConstraints/DataEntityType.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/CheckConstraints/DataEntityType.cs @@ -115,8 +115,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var blob = runtimeEntityType.FindProperty("Blob")!; + var id = runtimeEntityType.FindProperty("Id"); + var blob = runtimeEntityType.FindProperty("Blob"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/DbFunctions/DataEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/DbFunctions/DataEntityType.cs index 5070aca8292..b374dbcf238 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/DbFunctions/DataEntityType.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/DbFunctions/DataEntityType.cs @@ -75,7 +75,7 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var blob = runtimeEntityType.FindProperty("Blob")!; + var blob = runtimeEntityType.FindProperty("Blob"); runtimeEntityType.SetOriginalValuesFactory( ISnapshot (InternalEntityEntry source) => { diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/Dynamic_schema/DataEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/Dynamic_schema/DataEntityType.cs index 359ca91cf9f..501200ed058 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/Dynamic_schema/DataEntityType.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/Dynamic_schema/DataEntityType.cs @@ -115,8 +115,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var blob = runtimeEntityType.FindProperty("Blob")!; + var id = runtimeEntityType.FindProperty("Id"); + var blob = runtimeEntityType.FindProperty("Blob"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DataEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DataEntityType.cs new file mode 100644 index 00000000000..e827510cbaf --- /dev/null +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DataEntityType.cs @@ -0,0 +1,66 @@ +// +using System; +using System.Reflection; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; +using NetTopologySuite.Geometries; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class DataEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+Data", + typeof(CompiledModelTestBase.Data), + baseEntityType, + propertyCount: 3, + keyCount: 1); + + var id = runtimeEntityType.AddProperty( + "Id", + typeof(int), + valueGenerated: ValueGenerated.OnAdd, + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: 0); + + var blob = runtimeEntityType.AddProperty( + "Blob", + typeof(byte[]), + propertyInfo: typeof(CompiledModelTestBase.Data).GetProperty("Blob", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.Data).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var point = runtimeEntityType.AddProperty( + "Point", + typeof(Point), + nullable: true); + + var key = runtimeEntityType.AddKey( + new[] { id }); + runtimeEntityType.SetPrimaryKey(key); + + return runtimeEntityType; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + runtimeEntityType.AddAnnotation("Relational:FunctionName", null); + runtimeEntityType.AddAnnotation("Relational:Schema", null); + runtimeEntityType.AddAnnotation("Relational:SqlQuery", null); + runtimeEntityType.AddAnnotation("Relational:TableName", "Data"); + runtimeEntityType.AddAnnotation("Relational:ViewName", null); + runtimeEntityType.AddAnnotation("Relational:ViewSchema", null); + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextAssemblyAttributes.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextAssemblyAttributes.cs new file mode 100644 index 00000000000..c224873f6fa --- /dev/null +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextAssemblyAttributes.cs @@ -0,0 +1,9 @@ +// +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using TestNamespace; + +#pragma warning disable 219, 612, 618 +#nullable disable + +[assembly: DbContextModel(typeof(DbContext), typeof(DbContextModel))] diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextModel.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextModel.cs new file mode 100644 index 00000000000..583ee4d90cc --- /dev/null +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextModel.cs @@ -0,0 +1,48 @@ +// +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [DbContext(typeof(DbContext))] + public partial class DbContextModel : RuntimeModel + { + private static readonly bool _useOldBehavior31751 = + System.AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue31751", out var enabled31751) && enabled31751; + + static DbContextModel() + { + var model = new DbContextModel(); + + if (_useOldBehavior31751) + { + model.Initialize(); + } + else + { + var thread = new System.Threading.Thread(RunInitialization, 10 * 1024 * 1024); + thread.Start(); + thread.Join(); + + void RunInitialization() + { + model.Initialize(); + } + } + + model.Customize(); + _instance = (DbContextModel)model.FinalizeModel(); + } + + private static DbContextModel _instance; + public static IModel Instance => _instance; + + partial void Initialize(); + + partial void Customize(); + } +} diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextModelBuilder.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextModelBuilder.cs new file mode 100644 index 00000000000..548895ceeb8 --- /dev/null +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextModelBuilder.cs @@ -0,0 +1,54 @@ +// +using System; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + public partial class DbContextModel + { + private DbContextModel() + : base(skipDetectChanges: false, modelId: new Guid("00000000-0000-0000-0000-000000000000"), entityTypeCount: 9) + { + } + + partial void Initialize() + { + var data = DataEntityType.Create(this); + var dependentBase = DependentBaseEntityType.Create(this); + var manyTypes = ManyTypesEntityType.Create(this); + var principalBase = PrincipalBaseEntityType.Create(this); + var ownedType = OwnedTypeEntityType.Create(this); + var ownedType0 = OwnedType0EntityType.Create(this); + var principalBasePrincipalDerivedDependentBasebyte = PrincipalBasePrincipalDerivedDependentBasebyteEntityType.Create(this); + var dependentDerived = DependentDerivedEntityType.Create(this, dependentBase); + var principalDerived = PrincipalDerivedEntityType.Create(this, principalBase); + + DependentBaseEntityType.CreateForeignKey1(dependentBase, principalBase); + DependentBaseEntityType.CreateForeignKey2(dependentBase, principalDerived); + OwnedTypeEntityType.CreateForeignKey1(ownedType, principalBase); + OwnedTypeEntityType.CreateForeignKey2(ownedType, ownedType); + OwnedType0EntityType.CreateForeignKey1(ownedType0, principalDerived); + PrincipalBasePrincipalDerivedDependentBasebyteEntityType.CreateForeignKey1(principalBasePrincipalDerivedDependentBasebyte, principalDerived); + PrincipalBasePrincipalDerivedDependentBasebyteEntityType.CreateForeignKey2(principalBasePrincipalDerivedDependentBasebyte, principalBase); + PrincipalDerivedEntityType.CreateForeignKey1(principalDerived, principalBase); + + PrincipalBaseEntityType.CreateSkipNavigation1(principalBase, principalDerived, principalBasePrincipalDerivedDependentBasebyte); + PrincipalDerivedEntityType.CreateSkipNavigation1(principalDerived, principalBase, principalBasePrincipalDerivedDependentBasebyte); + + DataEntityType.CreateAnnotations(data); + DependentBaseEntityType.CreateAnnotations(dependentBase); + ManyTypesEntityType.CreateAnnotations(manyTypes); + PrincipalBaseEntityType.CreateAnnotations(principalBase); + OwnedTypeEntityType.CreateAnnotations(ownedType); + OwnedType0EntityType.CreateAnnotations(ownedType0); + PrincipalBasePrincipalDerivedDependentBasebyteEntityType.CreateAnnotations(principalBasePrincipalDerivedDependentBasebyte); + DependentDerivedEntityType.CreateAnnotations(dependentDerived); + PrincipalDerivedEntityType.CreateAnnotations(principalDerived); + + } + } +} diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DependentBaseEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DependentBaseEntityType.cs new file mode 100644 index 00000000000..5f4687b055c --- /dev/null +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DependentBaseEntityType.cs @@ -0,0 +1,126 @@ +// +using System; +using System.Reflection; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; +using Microsoft.EntityFrameworkCore.ValueGeneration; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class DependentBaseEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+DependentBase", + typeof(CompiledModelTestBase.DependentBase), + baseEntityType, + discriminatorProperty: "EnumDiscriminator", + discriminatorValue: CompiledModelTestBase.Enum1.One, + derivedTypesCount: 1, + propertyCount: 4, + navigationCount: 1, + foreignKeyCount: 2, + unnamedIndexCount: 1, + keyCount: 1); + + var principalId = runtimeEntityType.AddProperty( + "PrincipalId", + typeof(long), + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: 0L); + + var principalAlternateId = runtimeEntityType.AddProperty( + "PrincipalAlternateId", + typeof(Guid), + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: new Guid("00000000-0000-0000-0000-000000000000")); + + var enumDiscriminator = runtimeEntityType.AddProperty( + "EnumDiscriminator", + typeof(CompiledModelTestBase.Enum1), + afterSaveBehavior: PropertySaveBehavior.Throw, + valueGeneratorFactory: new DiscriminatorValueGeneratorFactory().Create); + enumDiscriminator.SetSentinelFromProviderValue(0); + + var id = runtimeEntityType.AddProperty( + "Id", + typeof(byte?), + propertyInfo: typeof(CompiledModelTestBase.DependentBase).GetProperty("Id", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.DependentBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var key = runtimeEntityType.AddKey( + new[] { principalId, principalAlternateId }); + runtimeEntityType.SetPrimaryKey(key); + + var index = runtimeEntityType.AddIndex( + new[] { principalId }, + unique: true); + + return runtimeEntityType; + } + + public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("PrincipalId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("Id") }), + principalEntityType, + deleteBehavior: DeleteBehavior.Cascade, + unique: true, + required: true); + + return runtimeForeignKey; + } + + public static RuntimeForeignKey CreateForeignKey2(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("PrincipalId"), declaringEntityType.FindProperty("PrincipalAlternateId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("Id"), principalEntityType.FindProperty("AlternateId") }), + principalEntityType, + deleteBehavior: DeleteBehavior.ClientNoAction, + unique: true, + required: true); + + var principal = declaringEntityType.AddNavigation("Principal", + runtimeForeignKey, + onDependent: true, + typeof(CompiledModelTestBase.PrincipalDerived>), + propertyInfo: typeof(CompiledModelTestBase.DependentBase).GetProperty("Principal", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.DependentBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var dependent = principalEntityType.AddNavigation("Dependent", + runtimeForeignKey, + onDependent: false, + typeof(CompiledModelTestBase.DependentBase), + propertyInfo: typeof(CompiledModelTestBase.PrincipalDerived>).GetProperty("Dependent", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalDerived>).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + eagerLoaded: true, + lazyLoadingEnabled: false); + + return runtimeForeignKey; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + runtimeEntityType.AddAnnotation("DiscriminatorMappingComplete", false); + runtimeEntityType.AddAnnotation("Relational:FunctionName", null); + runtimeEntityType.AddAnnotation("Relational:MappingStrategy", "TPH"); + runtimeEntityType.AddAnnotation("Relational:Schema", null); + runtimeEntityType.AddAnnotation("Relational:SqlQuery", null); + runtimeEntityType.AddAnnotation("Relational:TableName", "DependentBase"); + runtimeEntityType.AddAnnotation("Relational:ViewName", null); + runtimeEntityType.AddAnnotation("Relational:ViewSchema", null); + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DependentDerivedEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DependentDerivedEntityType.cs new file mode 100644 index 00000000000..ee41508b78c --- /dev/null +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DependentDerivedEntityType.cs @@ -0,0 +1,60 @@ +// +using System; +using System.Reflection; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class DependentDerivedEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+DependentDerived", + typeof(CompiledModelTestBase.DependentDerived), + baseEntityType, + discriminatorProperty: "EnumDiscriminator", + discriminatorValue: CompiledModelTestBase.Enum1.Two, + propertyCount: 2); + + var data = runtimeEntityType.AddProperty( + "Data", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.DependentDerived).GetProperty("Data", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.DependentDerived).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true, + maxLength: 20, + unicode: false); + data.AddAnnotation("Relational:IsFixedLength", true); + + var money = runtimeEntityType.AddProperty( + "Money", + typeof(decimal), + precision: 9, + scale: 3, + sentinel: 0m); + + return runtimeEntityType; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + runtimeEntityType.AddAnnotation("Relational:FunctionName", null); + runtimeEntityType.AddAnnotation("Relational:Schema", null); + runtimeEntityType.AddAnnotation("Relational:SqlQuery", null); + runtimeEntityType.AddAnnotation("Relational:TableName", "DependentBase"); + runtimeEntityType.AddAnnotation("Relational:ViewName", null); + runtimeEntityType.AddAnnotation("Relational:ViewSchema", null); + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/ManyTypesEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/ManyTypesEntityType.cs new file mode 100644 index 00000000000..ddf70ed1e99 --- /dev/null +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/ManyTypesEntityType.cs @@ -0,0 +1,1656 @@ +// +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.NetworkInformation; +using System.Reflection; +using System.Text; +using Microsoft.EntityFrameworkCore.ChangeTracking; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; +using Microsoft.EntityFrameworkCore.Sqlite.Storage.Internal; +using Microsoft.EntityFrameworkCore.Storage; +using Microsoft.EntityFrameworkCore.Storage.Json; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class ManyTypesEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+ManyTypes", + typeof(CompiledModelTestBase.ManyTypes), + baseEntityType, + propertyCount: 236, + keyCount: 1); + + var id = runtimeEntityType.AddProperty( + "Id", + typeof(CompiledModelTestBase.ManyTypesId), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Id", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueGenerated: ValueGenerated.OnAdd, + afterSaveBehavior: PropertySaveBehavior.Throw, + valueConverter: new CompiledModelTestBase.ManyTypesIdConverter()); + id.SetSentinelFromProviderValue(0); + + var @bool = runtimeEntityType.AddProperty( + "Bool", + typeof(bool), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Bool", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: false); + + var boolArray = runtimeEntityType.AddProperty( + "BoolArray", + typeof(bool[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BoolArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var boolToStringConverterProperty = runtimeEntityType.AddProperty( + "BoolToStringConverterProperty", + typeof(bool), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BoolToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + boolToStringConverterProperty.TypeMapping = SqliteStringTypeMapping.Default.Clone( + comparer: new ValueComparer( + bool (bool v1, bool v2) => v1 == v2, + int (bool v) => ((object)v).GetHashCode(), + bool (bool v) => v), + keyComparer: new ValueComparer( + bool (bool v1, bool v2) => v1 == v2, + int (bool v) => ((object)v).GetHashCode(), + bool (bool v) => v), + providerValueComparer: new ValueComparer( + bool (string v1, string v2) => v1 == v2, + int (string v) => ((object)v).GetHashCode(), + string (string v) => v), + mappingInfo: new RelationalTypeMappingInfo( + size: 1), + converter: new ValueConverter( + string (bool v) => ((string)((v ? "B" : "A"))), + bool (string v) => !(string.IsNullOrEmpty(v)) && ((int)(v.ToUpperInvariant()[0])) == ((int)("B".ToUpperInvariant()[0]))), + jsonValueReaderWriter: new JsonConvertedValueReaderWriter( + JsonStringReaderWriter.Instance, + new ValueConverter( + string (bool v) => ((string)((v ? "B" : "A"))), + bool (string v) => !(string.IsNullOrEmpty(v)) && ((int)(v.ToUpperInvariant()[0])) == ((int)("B".ToUpperInvariant()[0]))))); + boolToStringConverterProperty.SetSentinelFromProviderValue("A"); + + var boolToTwoValuesConverterProperty = runtimeEntityType.AddProperty( + "BoolToTwoValuesConverterProperty", + typeof(bool), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BoolToTwoValuesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + boolToTwoValuesConverterProperty.SetValueConverter(new ValueConverter( + byte (bool v) => ((byte)((v ? 1 : 0))), + bool (byte v) => v == 1)); + boolToTwoValuesConverterProperty.SetSentinelFromProviderValue((byte)0); + + var boolToZeroOneConverterProperty = runtimeEntityType.AddProperty( + "BoolToZeroOneConverterProperty", + typeof(bool), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BoolToZeroOneConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new BoolToZeroOneConverter()); + boolToZeroOneConverterProperty.SetSentinelFromProviderValue((short)0); + + var bytes = runtimeEntityType.AddProperty( + "Bytes", + typeof(byte[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Bytes", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var bytesArray = runtimeEntityType.AddProperty( + "BytesArray", + typeof(byte[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BytesArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var bytesToStringConverterProperty = runtimeEntityType.AddProperty( + "BytesToStringConverterProperty", + typeof(byte[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("BytesToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new BytesToStringConverter(), + valueComparer: new ArrayStructuralComparer()); + + var castingConverterProperty = runtimeEntityType.AddProperty( + "CastingConverterProperty", + typeof(int), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("CastingConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new CastingConverter()); + castingConverterProperty.SetSentinelFromProviderValue(0m); + + var @char = runtimeEntityType.AddProperty( + "Char", + typeof(char), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Char", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: '\0'); + + var charArray = runtimeEntityType.AddProperty( + "CharArray", + typeof(char[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("CharArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var charToStringConverterProperty = runtimeEntityType.AddProperty( + "CharToStringConverterProperty", + typeof(char), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("CharToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new CharToStringConverter()); + charToStringConverterProperty.SetSentinelFromProviderValue("\0"); + + var dateOnly = runtimeEntityType.AddProperty( + "DateOnly", + typeof(DateOnly), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateOnly", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: new DateOnly(1, 1, 1)); + + var dateOnlyArray = runtimeEntityType.AddProperty( + "DateOnlyArray", + typeof(DateOnly[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateOnlyArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var dateOnlyToStringConverterProperty = runtimeEntityType.AddProperty( + "DateOnlyToStringConverterProperty", + typeof(DateOnly), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateOnlyToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new DateOnlyToStringConverter()); + dateOnlyToStringConverterProperty.SetSentinelFromProviderValue("0001-01-01"); + + var dateTime = runtimeEntityType.AddProperty( + "DateTime", + typeof(DateTime), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTime", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + var dateTimeArray = runtimeEntityType.AddProperty( + "DateTimeArray", + typeof(DateTime[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var dateTimeOffsetToBinaryConverterProperty = runtimeEntityType.AddProperty( + "DateTimeOffsetToBinaryConverterProperty", + typeof(DateTimeOffset), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeOffsetToBinaryConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new DateTimeOffsetToBinaryConverter()); + dateTimeOffsetToBinaryConverterProperty.SetSentinelFromProviderValue(0L); + + var dateTimeOffsetToBytesConverterProperty = runtimeEntityType.AddProperty( + "DateTimeOffsetToBytesConverterProperty", + typeof(DateTimeOffset), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeOffsetToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new DateTimeOffsetToBytesConverter()); + dateTimeOffsetToBytesConverterProperty.SetSentinelFromProviderValue(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }); + + var dateTimeOffsetToStringConverterProperty = runtimeEntityType.AddProperty( + "DateTimeOffsetToStringConverterProperty", + typeof(DateTimeOffset), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeOffsetToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new DateTimeOffsetToStringConverter()); + dateTimeOffsetToStringConverterProperty.SetSentinelFromProviderValue("0001-01-01 00:00:00+00:00"); + + var dateTimeToBinaryConverterProperty = runtimeEntityType.AddProperty( + "DateTimeToBinaryConverterProperty", + typeof(DateTime), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeToBinaryConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new DateTimeToBinaryConverter()); + dateTimeToBinaryConverterProperty.SetSentinelFromProviderValue(0L); + + var dateTimeToStringConverterProperty = runtimeEntityType.AddProperty( + "DateTimeToStringConverterProperty", + typeof(DateTime), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new DateTimeToStringConverter()); + dateTimeToStringConverterProperty.SetSentinelFromProviderValue("0001-01-01 00:00:00"); + + var dateTimeToTicksConverterProperty = runtimeEntityType.AddProperty( + "DateTimeToTicksConverterProperty", + typeof(DateTime), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DateTimeToTicksConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + var @decimal = runtimeEntityType.AddProperty( + "Decimal", + typeof(decimal), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Decimal", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0m); + + var decimalArray = runtimeEntityType.AddProperty( + "DecimalArray", + typeof(decimal[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DecimalArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var decimalNumberToBytesConverterProperty = runtimeEntityType.AddProperty( + "DecimalNumberToBytesConverterProperty", + typeof(decimal), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DecimalNumberToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new NumberToBytesConverter()); + decimalNumberToBytesConverterProperty.SetSentinelFromProviderValue(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }); + + var decimalNumberToStringConverterProperty = runtimeEntityType.AddProperty( + "DecimalNumberToStringConverterProperty", + typeof(decimal), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DecimalNumberToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new NumberToStringConverter()); + decimalNumberToStringConverterProperty.SetSentinelFromProviderValue("0"); + + var @double = runtimeEntityType.AddProperty( + "Double", + typeof(double), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Double", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0.0); + + var doubleArray = runtimeEntityType.AddProperty( + "DoubleArray", + typeof(double[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DoubleArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var doubleNumberToBytesConverterProperty = runtimeEntityType.AddProperty( + "DoubleNumberToBytesConverterProperty", + typeof(double), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DoubleNumberToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new NumberToBytesConverter()); + doubleNumberToBytesConverterProperty.SetSentinelFromProviderValue(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }); + + var doubleNumberToStringConverterProperty = runtimeEntityType.AddProperty( + "DoubleNumberToStringConverterProperty", + typeof(double), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("DoubleNumberToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new NumberToStringConverter()); + doubleNumberToStringConverterProperty.SetSentinelFromProviderValue("0"); + + var enum16 = runtimeEntityType.AddProperty( + "Enum16", + typeof(CompiledModelTestBase.Enum16), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enum16.SetSentinelFromProviderValue((short)0); + + var enum16Array = runtimeEntityType.AddProperty( + "Enum16Array", + typeof(CompiledModelTestBase.Enum16[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum16AsString = runtimeEntityType.AddProperty( + "Enum16AsString", + typeof(CompiledModelTestBase.Enum16), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum16AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enum16AsString.SetSentinelFromProviderValue("Default"); + + var enum16AsStringArray = runtimeEntityType.AddProperty( + "Enum16AsStringArray", + typeof(CompiledModelTestBase.Enum16[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum16AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum16AsStringCollection = runtimeEntityType.AddProperty( + "Enum16AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum16AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum16Collection = runtimeEntityType.AddProperty( + "Enum16Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum16Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum32 = runtimeEntityType.AddProperty( + "Enum32", + typeof(CompiledModelTestBase.Enum32), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enum32.SetSentinelFromProviderValue(0); + + var enum32Array = runtimeEntityType.AddProperty( + "Enum32Array", + typeof(CompiledModelTestBase.Enum32[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum32AsString = runtimeEntityType.AddProperty( + "Enum32AsString", + typeof(CompiledModelTestBase.Enum32), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum32AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enum32AsString.SetSentinelFromProviderValue("Default"); + + var enum32AsStringArray = runtimeEntityType.AddProperty( + "Enum32AsStringArray", + typeof(CompiledModelTestBase.Enum32[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum32AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum32AsStringCollection = runtimeEntityType.AddProperty( + "Enum32AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum32AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum32Collection = runtimeEntityType.AddProperty( + "Enum32Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum32Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum64 = runtimeEntityType.AddProperty( + "Enum64", + typeof(CompiledModelTestBase.Enum64), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enum64.SetSentinelFromProviderValue(0L); + + var enum64Array = runtimeEntityType.AddProperty( + "Enum64Array", + typeof(CompiledModelTestBase.Enum64[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum64AsString = runtimeEntityType.AddProperty( + "Enum64AsString", + typeof(CompiledModelTestBase.Enum64), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum64AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enum64AsString.SetSentinelFromProviderValue("Default"); + + var enum64AsStringArray = runtimeEntityType.AddProperty( + "Enum64AsStringArray", + typeof(CompiledModelTestBase.Enum64[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum64AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum64AsStringCollection = runtimeEntityType.AddProperty( + "Enum64AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum64AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum64Collection = runtimeEntityType.AddProperty( + "Enum64Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum64Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum8 = runtimeEntityType.AddProperty( + "Enum8", + typeof(CompiledModelTestBase.Enum8), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enum8.SetSentinelFromProviderValue((sbyte)0); + + var enum8Array = runtimeEntityType.AddProperty( + "Enum8Array", + typeof(CompiledModelTestBase.Enum8[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum8AsString = runtimeEntityType.AddProperty( + "Enum8AsString", + typeof(CompiledModelTestBase.Enum8), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum8AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enum8AsString.SetSentinelFromProviderValue("Default"); + + var enum8AsStringArray = runtimeEntityType.AddProperty( + "Enum8AsStringArray", + typeof(CompiledModelTestBase.Enum8[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum8AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum8AsStringCollection = runtimeEntityType.AddProperty( + "Enum8AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum8AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enum8Collection = runtimeEntityType.AddProperty( + "Enum8Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Enum8Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumToNumberConverterProperty = runtimeEntityType.AddProperty( + "EnumToNumberConverterProperty", + typeof(CompiledModelTestBase.Enum32), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumToNumberConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new EnumToNumberConverter()); + enumToNumberConverterProperty.SetSentinelFromProviderValue(0); + + var enumToStringConverterProperty = runtimeEntityType.AddProperty( + "EnumToStringConverterProperty", + typeof(CompiledModelTestBase.Enum32), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new EnumToStringConverter()); + enumToStringConverterProperty.SetSentinelFromProviderValue("Default"); + + var enumU16 = runtimeEntityType.AddProperty( + "EnumU16", + typeof(CompiledModelTestBase.EnumU16), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enumU16.SetSentinelFromProviderValue((ushort)0); + + var enumU16Array = runtimeEntityType.AddProperty( + "EnumU16Array", + typeof(CompiledModelTestBase.EnumU16[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU16AsString = runtimeEntityType.AddProperty( + "EnumU16AsString", + typeof(CompiledModelTestBase.EnumU16), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU16AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enumU16AsString.SetSentinelFromProviderValue("Min"); + + var enumU16AsStringArray = runtimeEntityType.AddProperty( + "EnumU16AsStringArray", + typeof(CompiledModelTestBase.EnumU16[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU16AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU16AsStringCollection = runtimeEntityType.AddProperty( + "EnumU16AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU16AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU16Collection = runtimeEntityType.AddProperty( + "EnumU16Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU16Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU32 = runtimeEntityType.AddProperty( + "EnumU32", + typeof(CompiledModelTestBase.EnumU32), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enumU32.SetSentinelFromProviderValue(0u); + + var enumU32Array = runtimeEntityType.AddProperty( + "EnumU32Array", + typeof(CompiledModelTestBase.EnumU32[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU32AsString = runtimeEntityType.AddProperty( + "EnumU32AsString", + typeof(CompiledModelTestBase.EnumU32), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU32AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enumU32AsString.SetSentinelFromProviderValue("Min"); + + var enumU32AsStringArray = runtimeEntityType.AddProperty( + "EnumU32AsStringArray", + typeof(CompiledModelTestBase.EnumU32[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU32AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU32AsStringCollection = runtimeEntityType.AddProperty( + "EnumU32AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU32AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU32Collection = runtimeEntityType.AddProperty( + "EnumU32Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU32Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU64 = runtimeEntityType.AddProperty( + "EnumU64", + typeof(CompiledModelTestBase.EnumU64), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enumU64.SetSentinelFromProviderValue(0ul); + + var enumU64Array = runtimeEntityType.AddProperty( + "EnumU64Array", + typeof(CompiledModelTestBase.EnumU64[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU64AsString = runtimeEntityType.AddProperty( + "EnumU64AsString", + typeof(CompiledModelTestBase.EnumU64), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU64AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enumU64AsString.SetSentinelFromProviderValue("Min"); + + var enumU64AsStringArray = runtimeEntityType.AddProperty( + "EnumU64AsStringArray", + typeof(CompiledModelTestBase.EnumU64[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU64AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU64AsStringCollection = runtimeEntityType.AddProperty( + "EnumU64AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU64AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU64Collection = runtimeEntityType.AddProperty( + "EnumU64Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU64Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU8 = runtimeEntityType.AddProperty( + "EnumU8", + typeof(CompiledModelTestBase.EnumU8), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enumU8.SetSentinelFromProviderValue((byte)0); + + var enumU8Array = runtimeEntityType.AddProperty( + "EnumU8Array", + typeof(CompiledModelTestBase.EnumU8[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU8AsString = runtimeEntityType.AddProperty( + "EnumU8AsString", + typeof(CompiledModelTestBase.EnumU8), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU8AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + providerPropertyType: typeof(string)); + enumU8AsString.SetSentinelFromProviderValue("Min"); + + var enumU8AsStringArray = runtimeEntityType.AddProperty( + "EnumU8AsStringArray", + typeof(CompiledModelTestBase.EnumU8[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU8AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU8AsStringCollection = runtimeEntityType.AddProperty( + "EnumU8AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU8AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var enumU8Collection = runtimeEntityType.AddProperty( + "EnumU8Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("EnumU8Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var @float = runtimeEntityType.AddProperty( + "Float", + typeof(float), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Float", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0f); + + var floatArray = runtimeEntityType.AddProperty( + "FloatArray", + typeof(float[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("FloatArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var guid = runtimeEntityType.AddProperty( + "Guid", + typeof(Guid), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Guid", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: new Guid("00000000-0000-0000-0000-000000000000")); + + var guidArray = runtimeEntityType.AddProperty( + "GuidArray", + typeof(Guid[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("GuidArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var guidToBytesConverterProperty = runtimeEntityType.AddProperty( + "GuidToBytesConverterProperty", + typeof(Guid), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("GuidToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new GuidToBytesConverter()); + guidToBytesConverterProperty.SetSentinelFromProviderValue(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }); + + var guidToStringConverterProperty = runtimeEntityType.AddProperty( + "GuidToStringConverterProperty", + typeof(Guid), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("GuidToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new GuidToStringConverter()); + guidToStringConverterProperty.SetSentinelFromProviderValue("00000000-0000-0000-0000-000000000000"); + + var iPAddress = runtimeEntityType.AddProperty( + "IPAddress", + typeof(IPAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("IPAddress", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var iPAddressArray = runtimeEntityType.AddProperty( + "IPAddressArray", + typeof(IPAddress[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("IPAddressArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var iPAddressToBytesConverterProperty = runtimeEntityType.AddProperty( + "IPAddressToBytesConverterProperty", + typeof(IPAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("IPAddressToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new IPAddressToBytesConverter()); + + var iPAddressToStringConverterProperty = runtimeEntityType.AddProperty( + "IPAddressToStringConverterProperty", + typeof(IPAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("IPAddressToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new IPAddressToStringConverter()); + + var int16 = runtimeEntityType.AddProperty( + "Int16", + typeof(short), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: (short)0); + + var int16Array = runtimeEntityType.AddProperty( + "Int16Array", + typeof(short[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var int32 = runtimeEntityType.AddProperty( + "Int32", + typeof(int), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0); + + var int32Array = runtimeEntityType.AddProperty( + "Int32Array", + typeof(int[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var int64 = runtimeEntityType.AddProperty( + "Int64", + typeof(long), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0L); + + var int64Array = runtimeEntityType.AddProperty( + "Int64Array", + typeof(long[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var int8 = runtimeEntityType.AddProperty( + "Int8", + typeof(sbyte), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: (sbyte)0); + + var int8Array = runtimeEntityType.AddProperty( + "Int8Array", + typeof(sbyte[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Int8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var intNumberToBytesConverterProperty = runtimeEntityType.AddProperty( + "IntNumberToBytesConverterProperty", + typeof(int), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("IntNumberToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new NumberToBytesConverter()); + intNumberToBytesConverterProperty.SetSentinelFromProviderValue(new byte[] { 0, 0, 0, 0 }); + + var intNumberToStringConverterProperty = runtimeEntityType.AddProperty( + "IntNumberToStringConverterProperty", + typeof(int), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("IntNumberToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new NumberToStringConverter()); + intNumberToStringConverterProperty.SetSentinelFromProviderValue("0"); + + var nullIntToNullStringConverterProperty = runtimeEntityType.AddProperty( + "NullIntToNullStringConverterProperty", + typeof(int?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullIntToNullStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true, + valueConverter: new CompiledModelTestBase.NullIntToNullStringConverter()); + + var nullableBool = runtimeEntityType.AddProperty( + "NullableBool", + typeof(bool?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableBool", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableBoolArray = runtimeEntityType.AddProperty( + "NullableBoolArray", + typeof(bool?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableBoolArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableBytes = runtimeEntityType.AddProperty( + "NullableBytes", + typeof(byte[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableBytes", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableBytesArray = runtimeEntityType.AddProperty( + "NullableBytesArray", + typeof(byte[][]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableBytesArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableChar = runtimeEntityType.AddProperty( + "NullableChar", + typeof(char?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableChar", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableCharArray = runtimeEntityType.AddProperty( + "NullableCharArray", + typeof(char?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableCharArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableDateOnly = runtimeEntityType.AddProperty( + "NullableDateOnly", + typeof(DateOnly?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDateOnly", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableDateOnlyArray = runtimeEntityType.AddProperty( + "NullableDateOnlyArray", + typeof(DateOnly?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDateOnlyArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableDateTime = runtimeEntityType.AddProperty( + "NullableDateTime", + typeof(DateTime?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDateTime", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableDateTimeArray = runtimeEntityType.AddProperty( + "NullableDateTimeArray", + typeof(DateTime?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDateTimeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableDecimal = runtimeEntityType.AddProperty( + "NullableDecimal", + typeof(decimal?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDecimal", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableDecimalArray = runtimeEntityType.AddProperty( + "NullableDecimalArray", + typeof(decimal?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDecimalArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableDouble = runtimeEntityType.AddProperty( + "NullableDouble", + typeof(double?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDouble", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableDoubleArray = runtimeEntityType.AddProperty( + "NullableDoubleArray", + typeof(double?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableDoubleArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum16 = runtimeEntityType.AddProperty( + "NullableEnum16", + typeof(CompiledModelTestBase.Enum16?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnum16Array = runtimeEntityType.AddProperty( + "NullableEnum16Array", + typeof(CompiledModelTestBase.Enum16?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum16AsString = runtimeEntityType.AddProperty( + "NullableEnum16AsString", + typeof(CompiledModelTestBase.Enum16?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum16AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnum16AsStringArray = runtimeEntityType.AddProperty( + "NullableEnum16AsStringArray", + typeof(CompiledModelTestBase.Enum16?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum16AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum16AsStringCollection = runtimeEntityType.AddProperty( + "NullableEnum16AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum16AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum16Collection = runtimeEntityType.AddProperty( + "NullableEnum16Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum16Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum32 = runtimeEntityType.AddProperty( + "NullableEnum32", + typeof(CompiledModelTestBase.Enum32?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnum32Array = runtimeEntityType.AddProperty( + "NullableEnum32Array", + typeof(CompiledModelTestBase.Enum32?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum32AsString = runtimeEntityType.AddProperty( + "NullableEnum32AsString", + typeof(CompiledModelTestBase.Enum32?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum32AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnum32AsStringArray = runtimeEntityType.AddProperty( + "NullableEnum32AsStringArray", + typeof(CompiledModelTestBase.Enum32?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum32AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum32AsStringCollection = runtimeEntityType.AddProperty( + "NullableEnum32AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum32AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum32Collection = runtimeEntityType.AddProperty( + "NullableEnum32Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum32Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum64 = runtimeEntityType.AddProperty( + "NullableEnum64", + typeof(CompiledModelTestBase.Enum64?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnum64Array = runtimeEntityType.AddProperty( + "NullableEnum64Array", + typeof(CompiledModelTestBase.Enum64?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum64AsString = runtimeEntityType.AddProperty( + "NullableEnum64AsString", + typeof(CompiledModelTestBase.Enum64?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum64AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnum64AsStringArray = runtimeEntityType.AddProperty( + "NullableEnum64AsStringArray", + typeof(CompiledModelTestBase.Enum64?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum64AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum64AsStringCollection = runtimeEntityType.AddProperty( + "NullableEnum64AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum64AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum64Collection = runtimeEntityType.AddProperty( + "NullableEnum64Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum64Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum8 = runtimeEntityType.AddProperty( + "NullableEnum8", + typeof(CompiledModelTestBase.Enum8?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnum8Array = runtimeEntityType.AddProperty( + "NullableEnum8Array", + typeof(CompiledModelTestBase.Enum8?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum8AsString = runtimeEntityType.AddProperty( + "NullableEnum8AsString", + typeof(CompiledModelTestBase.Enum8?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum8AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnum8AsStringArray = runtimeEntityType.AddProperty( + "NullableEnum8AsStringArray", + typeof(CompiledModelTestBase.Enum8?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum8AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum8AsStringCollection = runtimeEntityType.AddProperty( + "NullableEnum8AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum8AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnum8Collection = runtimeEntityType.AddProperty( + "NullableEnum8Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnum8Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU16 = runtimeEntityType.AddProperty( + "NullableEnumU16", + typeof(CompiledModelTestBase.EnumU16?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnumU16Array = runtimeEntityType.AddProperty( + "NullableEnumU16Array", + typeof(CompiledModelTestBase.EnumU16?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU16AsString = runtimeEntityType.AddProperty( + "NullableEnumU16AsString", + typeof(CompiledModelTestBase.EnumU16?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU16AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnumU16AsStringArray = runtimeEntityType.AddProperty( + "NullableEnumU16AsStringArray", + typeof(CompiledModelTestBase.EnumU16?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU16AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU16AsStringCollection = runtimeEntityType.AddProperty( + "NullableEnumU16AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU16AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU16Collection = runtimeEntityType.AddProperty( + "NullableEnumU16Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU16Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU32 = runtimeEntityType.AddProperty( + "NullableEnumU32", + typeof(CompiledModelTestBase.EnumU32?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnumU32Array = runtimeEntityType.AddProperty( + "NullableEnumU32Array", + typeof(CompiledModelTestBase.EnumU32?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU32AsString = runtimeEntityType.AddProperty( + "NullableEnumU32AsString", + typeof(CompiledModelTestBase.EnumU32?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU32AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnumU32AsStringArray = runtimeEntityType.AddProperty( + "NullableEnumU32AsStringArray", + typeof(CompiledModelTestBase.EnumU32?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU32AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU32AsStringCollection = runtimeEntityType.AddProperty( + "NullableEnumU32AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU32AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU32Collection = runtimeEntityType.AddProperty( + "NullableEnumU32Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU32Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU64 = runtimeEntityType.AddProperty( + "NullableEnumU64", + typeof(CompiledModelTestBase.EnumU64?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnumU64Array = runtimeEntityType.AddProperty( + "NullableEnumU64Array", + typeof(CompiledModelTestBase.EnumU64?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU64AsString = runtimeEntityType.AddProperty( + "NullableEnumU64AsString", + typeof(CompiledModelTestBase.EnumU64?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU64AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnumU64AsStringArray = runtimeEntityType.AddProperty( + "NullableEnumU64AsStringArray", + typeof(CompiledModelTestBase.EnumU64?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU64AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU64AsStringCollection = runtimeEntityType.AddProperty( + "NullableEnumU64AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU64AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU64Collection = runtimeEntityType.AddProperty( + "NullableEnumU64Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU64Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU8 = runtimeEntityType.AddProperty( + "NullableEnumU8", + typeof(CompiledModelTestBase.EnumU8?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnumU8Array = runtimeEntityType.AddProperty( + "NullableEnumU8Array", + typeof(CompiledModelTestBase.EnumU8?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU8AsString = runtimeEntityType.AddProperty( + "NullableEnumU8AsString", + typeof(CompiledModelTestBase.EnumU8?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU8AsString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableEnumU8AsStringArray = runtimeEntityType.AddProperty( + "NullableEnumU8AsStringArray", + typeof(CompiledModelTestBase.EnumU8?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU8AsStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU8AsStringCollection = runtimeEntityType.AddProperty( + "NullableEnumU8AsStringCollection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU8AsStringCollection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableEnumU8Collection = runtimeEntityType.AddProperty( + "NullableEnumU8Collection", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableEnumU8Collection", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableFloat = runtimeEntityType.AddProperty( + "NullableFloat", + typeof(float?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableFloat", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableFloatArray = runtimeEntityType.AddProperty( + "NullableFloatArray", + typeof(float?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableFloatArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableGuid = runtimeEntityType.AddProperty( + "NullableGuid", + typeof(Guid?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableGuid", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableGuidArray = runtimeEntityType.AddProperty( + "NullableGuidArray", + typeof(Guid?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableGuidArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableIPAddress = runtimeEntityType.AddProperty( + "NullableIPAddress", + typeof(IPAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableIPAddress", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableIPAddressArray = runtimeEntityType.AddProperty( + "NullableIPAddressArray", + typeof(IPAddress[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableIPAddressArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableInt16 = runtimeEntityType.AddProperty( + "NullableInt16", + typeof(short?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableInt16Array = runtimeEntityType.AddProperty( + "NullableInt16Array", + typeof(short?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableInt32 = runtimeEntityType.AddProperty( + "NullableInt32", + typeof(int?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableInt32Array = runtimeEntityType.AddProperty( + "NullableInt32Array", + typeof(int?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableInt64 = runtimeEntityType.AddProperty( + "NullableInt64", + typeof(long?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableInt64Array = runtimeEntityType.AddProperty( + "NullableInt64Array", + typeof(long?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableInt8 = runtimeEntityType.AddProperty( + "NullableInt8", + typeof(sbyte?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableInt8Array = runtimeEntityType.AddProperty( + "NullableInt8Array", + typeof(sbyte?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableInt8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullablePhysicalAddress = runtimeEntityType.AddProperty( + "NullablePhysicalAddress", + typeof(PhysicalAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullablePhysicalAddress", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullablePhysicalAddressArray = runtimeEntityType.AddProperty( + "NullablePhysicalAddressArray", + typeof(PhysicalAddress[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullablePhysicalAddressArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableString = runtimeEntityType.AddProperty( + "NullableString", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableStringArray = runtimeEntityType.AddProperty( + "NullableStringArray", + typeof(string[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableStringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableTimeOnly = runtimeEntityType.AddProperty( + "NullableTimeOnly", + typeof(TimeOnly?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableTimeOnly", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableTimeOnlyArray = runtimeEntityType.AddProperty( + "NullableTimeOnlyArray", + typeof(TimeOnly?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableTimeOnlyArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableTimeSpan = runtimeEntityType.AddProperty( + "NullableTimeSpan", + typeof(TimeSpan?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableTimeSpan", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableTimeSpanArray = runtimeEntityType.AddProperty( + "NullableTimeSpanArray", + typeof(TimeSpan?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableTimeSpanArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableUInt16 = runtimeEntityType.AddProperty( + "NullableUInt16", + typeof(ushort?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableUInt16Array = runtimeEntityType.AddProperty( + "NullableUInt16Array", + typeof(ushort?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableUInt32 = runtimeEntityType.AddProperty( + "NullableUInt32", + typeof(uint?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableUInt32Array = runtimeEntityType.AddProperty( + "NullableUInt32Array", + typeof(uint?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableUInt64 = runtimeEntityType.AddProperty( + "NullableUInt64", + typeof(ulong?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableUInt64Array = runtimeEntityType.AddProperty( + "NullableUInt64Array", + typeof(ulong?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableUInt8 = runtimeEntityType.AddProperty( + "NullableUInt8", + typeof(byte?), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableUInt8Array = runtimeEntityType.AddProperty( + "NullableUInt8Array", + typeof(byte?[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUInt8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var nullableUri = runtimeEntityType.AddProperty( + "NullableUri", + typeof(Uri), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUri", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var nullableUriArray = runtimeEntityType.AddProperty( + "NullableUriArray", + typeof(Uri[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("NullableUriArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var physicalAddress = runtimeEntityType.AddProperty( + "PhysicalAddress", + typeof(PhysicalAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("PhysicalAddress", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var physicalAddressArray = runtimeEntityType.AddProperty( + "PhysicalAddressArray", + typeof(PhysicalAddress[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("PhysicalAddressArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var physicalAddressToBytesConverterProperty = runtimeEntityType.AddProperty( + "PhysicalAddressToBytesConverterProperty", + typeof(PhysicalAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("PhysicalAddressToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new PhysicalAddressToBytesConverter()); + + var physicalAddressToStringConverterProperty = runtimeEntityType.AddProperty( + "PhysicalAddressToStringConverterProperty", + typeof(PhysicalAddress), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("PhysicalAddressToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new PhysicalAddressToStringConverter()); + + var @string = runtimeEntityType.AddProperty( + "String", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("String", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var stringArray = runtimeEntityType.AddProperty( + "StringArray", + typeof(string[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var stringToBoolConverterProperty = runtimeEntityType.AddProperty( + "StringToBoolConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToBoolConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToBoolConverter()); + + var stringToBytesConverterProperty = runtimeEntityType.AddProperty( + "StringToBytesConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToBytesConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + stringToBytesConverterProperty.SetValueConverter(new ValueConverter( + byte[] (string v) => Encoding.GetEncoding(12000).GetBytes(v), + string (byte[] v) => Encoding.GetEncoding(12000).GetString(v))); + + var stringToCharConverterProperty = runtimeEntityType.AddProperty( + "StringToCharConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToCharConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToCharConverter()); + + var stringToDateOnlyConverterProperty = runtimeEntityType.AddProperty( + "StringToDateOnlyConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToDateOnlyConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToDateOnlyConverter()); + + var stringToDateTimeConverterProperty = runtimeEntityType.AddProperty( + "StringToDateTimeConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToDateTimeConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToDateTimeConverter()); + + var stringToDateTimeOffsetConverterProperty = runtimeEntityType.AddProperty( + "StringToDateTimeOffsetConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToDateTimeOffsetConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToDateTimeOffsetConverter()); + + var stringToDecimalNumberConverterProperty = runtimeEntityType.AddProperty( + "StringToDecimalNumberConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToDecimalNumberConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToNumberConverter()); + + var stringToDoubleNumberConverterProperty = runtimeEntityType.AddProperty( + "StringToDoubleNumberConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToDoubleNumberConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToNumberConverter()); + + var stringToEnumConverterProperty = runtimeEntityType.AddProperty( + "StringToEnumConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToEnumConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToEnumConverter()); + + var stringToGuidConverterProperty = runtimeEntityType.AddProperty( + "StringToGuidConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToGuidConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var stringToIntNumberConverterProperty = runtimeEntityType.AddProperty( + "StringToIntNumberConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToIntNumberConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToNumberConverter()); + + var stringToTimeOnlyConverterProperty = runtimeEntityType.AddProperty( + "StringToTimeOnlyConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToTimeOnlyConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToTimeOnlyConverter()); + + var stringToTimeSpanConverterProperty = runtimeEntityType.AddProperty( + "StringToTimeSpanConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToTimeSpanConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToTimeSpanConverter()); + + var stringToUriConverterProperty = runtimeEntityType.AddProperty( + "StringToUriConverterProperty", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("StringToUriConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new StringToUriConverter()); + + var timeOnly = runtimeEntityType.AddProperty( + "TimeOnly", + typeof(TimeOnly), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeOnly", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: new TimeOnly(0, 0, 0)); + + var timeOnlyArray = runtimeEntityType.AddProperty( + "TimeOnlyArray", + typeof(TimeOnly[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeOnlyArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var timeOnlyToStringConverterProperty = runtimeEntityType.AddProperty( + "TimeOnlyToStringConverterProperty", + typeof(TimeOnly), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeOnlyToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new TimeOnlyToStringConverter()); + timeOnlyToStringConverterProperty.SetSentinelFromProviderValue("00:00:00"); + + var timeOnlyToTicksConverterProperty = runtimeEntityType.AddProperty( + "TimeOnlyToTicksConverterProperty", + typeof(TimeOnly), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeOnlyToTicksConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new TimeOnlyToTicksConverter()); + timeOnlyToTicksConverterProperty.SetSentinelFromProviderValue(0L); + + var timeSpan = runtimeEntityType.AddProperty( + "TimeSpan", + typeof(TimeSpan), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeSpan", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: new TimeSpan(0, 0, 0, 0, 0)); + + var timeSpanArray = runtimeEntityType.AddProperty( + "TimeSpanArray", + typeof(TimeSpan[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeSpanArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var timeSpanToStringConverterProperty = runtimeEntityType.AddProperty( + "TimeSpanToStringConverterProperty", + typeof(TimeSpan), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeSpanToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new TimeSpanToStringConverter()); + timeSpanToStringConverterProperty.SetSentinelFromProviderValue("00:00:00"); + + var timeSpanToTicksConverterProperty = runtimeEntityType.AddProperty( + "TimeSpanToTicksConverterProperty", + typeof(TimeSpan), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("TimeSpanToTicksConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new TimeSpanToTicksConverter()); + timeSpanToTicksConverterProperty.SetSentinelFromProviderValue(0L); + + var uInt16 = runtimeEntityType.AddProperty( + "UInt16", + typeof(ushort), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt16", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: (ushort)0); + + var uInt16Array = runtimeEntityType.AddProperty( + "UInt16Array", + typeof(ushort[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt16Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var uInt32 = runtimeEntityType.AddProperty( + "UInt32", + typeof(uint), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt32", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0u); + + var uInt32Array = runtimeEntityType.AddProperty( + "UInt32Array", + typeof(uint[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt32Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var uInt64 = runtimeEntityType.AddProperty( + "UInt64", + typeof(ulong), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt64", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0ul); + + var uInt64Array = runtimeEntityType.AddProperty( + "UInt64Array", + typeof(ulong[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt64Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var uInt8 = runtimeEntityType.AddProperty( + "UInt8", + typeof(byte), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt8", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: (byte)0); + + var uInt8Array = runtimeEntityType.AddProperty( + "UInt8Array", + typeof(byte[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UInt8Array", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var uri = runtimeEntityType.AddProperty( + "Uri", + typeof(Uri), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("Uri", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var uriArray = runtimeEntityType.AddProperty( + "UriArray", + typeof(Uri[]), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UriArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var uriToStringConverterProperty = runtimeEntityType.AddProperty( + "UriToStringConverterProperty", + typeof(Uri), + propertyInfo: typeof(CompiledModelTestBase.ManyTypes).GetProperty("UriToStringConverterProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.ManyTypes).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueConverter: new UriToStringConverter()); + + var key = runtimeEntityType.AddKey( + new[] { id }); + runtimeEntityType.SetPrimaryKey(key); + + return runtimeEntityType; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + runtimeEntityType.AddAnnotation("Relational:FunctionName", null); + runtimeEntityType.AddAnnotation("Relational:Schema", null); + runtimeEntityType.AddAnnotation("Relational:SqlQuery", null); + runtimeEntityType.AddAnnotation("Relational:TableName", "ManyTypes"); + runtimeEntityType.AddAnnotation("Relational:ViewName", null); + runtimeEntityType.AddAnnotation("Relational:ViewSchema", null); + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/OwnedType0EntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/OwnedType0EntityType.cs new file mode 100644 index 00000000000..5223c57de9d --- /dev/null +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/OwnedType0EntityType.cs @@ -0,0 +1,165 @@ +// +using System; +using System.Collections.Generic; +using System.Net; +using System.Reflection; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class OwnedType0EntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalDerived>.ManyOwned#OwnedType", + typeof(CompiledModelTestBase.OwnedType), + baseEntityType, + sharedClrType: true, + propertyCount: 13, + servicePropertyCount: 1, + foreignKeyCount: 1, + keyCount: 1); + + var principalDerivedId = runtimeEntityType.AddProperty( + "PrincipalDerivedId", + typeof(long), + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: 0L); + + var principalDerivedAlternateId = runtimeEntityType.AddProperty( + "PrincipalDerivedAlternateId", + typeof(Guid), + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: new Guid("00000000-0000-0000-0000-000000000000")); + + var id = runtimeEntityType.AddProperty( + "Id", + typeof(int), + valueGenerated: ValueGenerated.OnAdd, + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: 0); + + var details = runtimeEntityType.AddProperty( + "Details", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("Details", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_details", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var number = runtimeEntityType.AddProperty( + "Number", + typeof(int), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("Number", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + sentinel: 0); + + var refTypeArray = runtimeEntityType.AddProperty( + "RefTypeArray", + typeof(IPAddress[]), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeArray", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var refTypeEnumerable = runtimeEntityType.AddProperty( + "RefTypeEnumerable", + typeof(IEnumerable), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeEnumerable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeEnumerable", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var refTypeIList = runtimeEntityType.AddProperty( + "RefTypeIList", + typeof(IList), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeIList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeIList", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var refTypeList = runtimeEntityType.AddProperty( + "RefTypeList", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeList", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var valueTypeArray = runtimeEntityType.AddProperty( + "ValueTypeArray", + typeof(DateTime[]), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_valueTypeArray", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var valueTypeEnumerable = runtimeEntityType.AddProperty( + "ValueTypeEnumerable", + typeof(IEnumerable), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeEnumerable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_valueTypeEnumerable", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var valueTypeIList = runtimeEntityType.AddProperty( + "ValueTypeIList", + typeof(IList), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeIList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var valueTypeList = runtimeEntityType.AddProperty( + "ValueTypeList", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_valueTypeList", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var context = runtimeEntityType.AddServiceProperty( + "Context", + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("Context", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + serviceType: typeof(DbContext)); + + var key = runtimeEntityType.AddKey( + new[] { principalDerivedId, principalDerivedAlternateId, id }); + runtimeEntityType.SetPrimaryKey(key); + + return runtimeEntityType; + } + + public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("PrincipalDerivedId"), declaringEntityType.FindProperty("PrincipalDerivedAlternateId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("Id"), principalEntityType.FindProperty("AlternateId") }), + principalEntityType, + deleteBehavior: DeleteBehavior.Cascade, + required: true, + ownership: true); + + var manyOwned = principalEntityType.AddNavigation("ManyOwned", + runtimeForeignKey, + onDependent: false, + typeof(ICollection), + fieldInfo: typeof(CompiledModelTestBase.PrincipalDerived>).GetField("ManyOwned", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + eagerLoaded: true); + + return runtimeForeignKey; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + runtimeEntityType.AddAnnotation("Relational:FunctionName", null); + runtimeEntityType.AddAnnotation("Relational:Schema", null); + runtimeEntityType.AddAnnotation("Relational:SqlQuery", null); + runtimeEntityType.AddAnnotation("Relational:TableName", "ManyOwned"); + runtimeEntityType.AddAnnotation("Relational:ViewName", null); + runtimeEntityType.AddAnnotation("Relational:ViewSchema", null); + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/OwnedTypeEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/OwnedTypeEntityType.cs new file mode 100644 index 00000000000..b4839f7656b --- /dev/null +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/OwnedTypeEntityType.cs @@ -0,0 +1,215 @@ +// +using System; +using System.Collections.Generic; +using System.Net; +using System.Reflection; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class OwnedTypeEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalBase.Owned#OwnedType", + typeof(CompiledModelTestBase.OwnedType), + baseEntityType, + sharedClrType: true, + changeTrackingStrategy: ChangeTrackingStrategy.ChangingAndChangedNotificationsWithOriginalValues, + propertyCount: 12, + servicePropertyCount: 1, + foreignKeyCount: 2, + keyCount: 1); + + var principalBaseId = runtimeEntityType.AddProperty( + "PrincipalBaseId", + typeof(long), + propertyAccessMode: PropertyAccessMode.Field, + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: 0L); + + var overrides = new StoreObjectDictionary(); + var principalBaseIdPrincipalBase = new RuntimeRelationalPropertyOverrides( + principalBaseId, + StoreObjectIdentifier.Table("PrincipalBase", "mySchema"), + false, + null); + overrides.Add(StoreObjectIdentifier.Table("PrincipalBase", "mySchema"), principalBaseIdPrincipalBase); + principalBaseId.AddAnnotation("Relational:RelationalOverrides", overrides); + + + var principalBaseAlternateId = runtimeEntityType.AddProperty( + "PrincipalBaseAlternateId", + typeof(Guid), + propertyAccessMode: PropertyAccessMode.Field, + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: new Guid("00000000-0000-0000-0000-000000000000")); + + var details = runtimeEntityType.AddProperty( + "Details", + typeof(string), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("Details", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_details", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var overrides0 = new StoreObjectDictionary(); + var detailsDetails = new RuntimeRelationalPropertyOverrides( + details, + StoreObjectIdentifier.Table("Details", null), + false, + null); + overrides0.Add(StoreObjectIdentifier.Table("Details", null), detailsDetails); + details.AddAnnotation("Relational:RelationalOverrides", overrides0); + + + var number = runtimeEntityType.AddProperty( + "Number", + typeof(int), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("Number", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + sentinel: 0); + + var refTypeArray = runtimeEntityType.AddProperty( + "RefTypeArray", + typeof(IPAddress[]), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeArray", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var refTypeEnumerable = runtimeEntityType.AddProperty( + "RefTypeEnumerable", + typeof(IEnumerable), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeEnumerable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeEnumerable", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var refTypeIList = runtimeEntityType.AddProperty( + "RefTypeIList", + typeof(IList), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeIList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeIList", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var refTypeList = runtimeEntityType.AddProperty( + "RefTypeList", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("RefTypeList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_refTypeList", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var valueTypeArray = runtimeEntityType.AddProperty( + "ValueTypeArray", + typeof(DateTime[]), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_valueTypeArray", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var valueTypeEnumerable = runtimeEntityType.AddProperty( + "ValueTypeEnumerable", + typeof(IEnumerable), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeEnumerable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_valueTypeEnumerable", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var valueTypeIList = runtimeEntityType.AddProperty( + "ValueTypeIList", + typeof(IList), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeIList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var valueTypeList = runtimeEntityType.AddProperty( + "ValueTypeList", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("ValueTypeList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.OwnedType).GetField("_valueTypeList", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + nullable: true); + + var context = runtimeEntityType.AddServiceProperty( + "Context", + propertyInfo: typeof(CompiledModelTestBase.OwnedType).GetProperty("Context", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + serviceType: typeof(DbContext)); + + var key = runtimeEntityType.AddKey( + new[] { principalBaseId, principalBaseAlternateId }); + runtimeEntityType.SetPrimaryKey(key); + + return runtimeEntityType; + } + + public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("PrincipalBaseId"), declaringEntityType.FindProperty("PrincipalBaseAlternateId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("Id"), principalEntityType.FindProperty("AlternateId") }), + principalEntityType, + deleteBehavior: DeleteBehavior.Cascade, + unique: true, + required: true, + requiredDependent: true, + ownership: true); + + var owned = principalEntityType.AddNavigation("Owned", + runtimeForeignKey, + onDependent: false, + typeof(CompiledModelTestBase.OwnedType), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("Owned", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("_ownedField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Field, + eagerLoaded: true); + + return runtimeForeignKey; + } + + public static RuntimeForeignKey CreateForeignKey2(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("PrincipalBaseId"), declaringEntityType.FindProperty("PrincipalBaseAlternateId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("PrincipalBaseId"), principalEntityType.FindProperty("PrincipalBaseAlternateId") }), + principalEntityType, + deleteBehavior: DeleteBehavior.Cascade, + unique: true, + required: true, + requiredDependent: true); + + return runtimeForeignKey; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + var fragments = new StoreObjectDictionary(); + var detailsFragment = new RuntimeEntityTypeMappingFragment( + runtimeEntityType, + StoreObjectIdentifier.Table("Details", null), + null); + fragments.Add(StoreObjectIdentifier.Table("Details", null), detailsFragment); + runtimeEntityType.AddAnnotation("Relational:MappingFragments", fragments); + runtimeEntityType.AddAnnotation("Relational:FunctionName", null); + runtimeEntityType.AddAnnotation("Relational:Schema", "mySchema"); + runtimeEntityType.AddAnnotation("Relational:SqlQuery", null); + runtimeEntityType.AddAnnotation("Relational:TableName", "PrincipalBase"); + runtimeEntityType.AddAnnotation("Relational:ViewName", null); + runtimeEntityType.AddAnnotation("Relational:ViewSchema", null); + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalBaseEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalBaseEntityType.cs new file mode 100644 index 00000000000..7e0a6cb9718 --- /dev/null +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalBaseEntityType.cs @@ -0,0 +1,212 @@ +// +using System; +using System.Collections.Generic; +using System.Net; +using System.Reflection; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; +using Microsoft.EntityFrameworkCore.Storage.Json; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using NetTopologySuite.Geometries; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class PrincipalBaseEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalBase", + typeof(CompiledModelTestBase.PrincipalBase), + baseEntityType, + discriminatorValue: "PrincipalBase", + derivedTypesCount: 1, + propertyCount: 15, + navigationCount: 1, + skipNavigationCount: 1, + unnamedIndexCount: 1, + keyCount: 2); + + var id = runtimeEntityType.AddProperty( + "Id", + typeof(long?), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("Id", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + afterSaveBehavior: PropertySaveBehavior.Throw); + + var overrides = new StoreObjectDictionary(); + var idPrincipalDerived = new RuntimeRelationalPropertyOverrides( + id, + StoreObjectIdentifier.Table("PrincipalDerived", null), + true, + "DerivedId"); + overrides.Add(StoreObjectIdentifier.Table("PrincipalDerived", null), idPrincipalDerived); + id.AddAnnotation("Relational:RelationalOverrides", overrides); + + + var alternateId = runtimeEntityType.AddProperty( + "AlternateId", + typeof(Guid), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("AlternateId", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.FieldDuringConstruction, + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: new Guid("00000000-0000-0000-0000-000000000000"), + jsonValueReaderWriter: JsonGuidReaderWriter.Instance); + + var enum1 = runtimeEntityType.AddProperty( + "Enum1", + typeof(CompiledModelTestBase.AnEnum), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("Enum1", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + enum1.SetSentinelFromProviderValue(0); + + var enum2 = runtimeEntityType.AddProperty( + "Enum2", + typeof(CompiledModelTestBase.AnEnum?), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("Enum2", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var flagsEnum1 = runtimeEntityType.AddProperty( + "FlagsEnum1", + typeof(CompiledModelTestBase.AFlagsEnum), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("FlagsEnum1", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + flagsEnum1.SetSentinelFromProviderValue(0); + + var flagsEnum2 = runtimeEntityType.AddProperty( + "FlagsEnum2", + typeof(CompiledModelTestBase.AFlagsEnum), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("FlagsEnum2", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + propertyAccessMode: PropertyAccessMode.Property); + flagsEnum2.SetSentinelFromProviderValue(6); + + var point = runtimeEntityType.AddProperty( + "Point", + typeof(Point), + nullable: true, + valueGenerated: ValueGenerated.OnAdd, + valueConverter: new CastingConverter(), + valueComparer: new CompiledModelTestBase.CustomValueComparer(), + providerValueComparer: new CompiledModelTestBase.CustomValueComparer()); + point.AddAnnotation("Relational:ColumnType", "geometry"); + point.AddAnnotation("Relational:DefaultValue", (NetTopologySuite.Geometries.Point)new NetTopologySuite.IO.WKTReader().Read("SRID=0;POINT Z(0 0 0)")); + + var refTypeArray = runtimeEntityType.AddProperty( + "RefTypeArray", + typeof(IPAddress[]), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("RefTypeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var refTypeEnumerable = runtimeEntityType.AddProperty( + "RefTypeEnumerable", + typeof(IEnumerable), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("RefTypeEnumerable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var refTypeIList = runtimeEntityType.AddProperty( + "RefTypeIList", + typeof(IList), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("RefTypeIList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var refTypeList = runtimeEntityType.AddProperty( + "RefTypeList", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("RefTypeList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var valueTypeArray = runtimeEntityType.AddProperty( + "ValueTypeArray", + typeof(DateTime[]), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("ValueTypeArray", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var valueTypeEnumerable = runtimeEntityType.AddProperty( + "ValueTypeEnumerable", + typeof(IEnumerable), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("ValueTypeEnumerable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var valueTypeIList = runtimeEntityType.AddProperty( + "ValueTypeIList", + typeof(IList), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("ValueTypeIList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var valueTypeList = runtimeEntityType.AddProperty( + "ValueTypeList", + typeof(List), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("ValueTypeList", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var key = runtimeEntityType.AddKey( + new[] { id }); + + var key0 = runtimeEntityType.AddKey( + new[] { id, alternateId }); + runtimeEntityType.SetPrimaryKey(key0); + key0.AddAnnotation("Relational:Name", "PK"); + + var index = runtimeEntityType.AddIndex( + new[] { alternateId, id }); + + return runtimeEntityType; + } + + public static RuntimeSkipNavigation CreateSkipNavigation1(RuntimeEntityType declaringEntityType, RuntimeEntityType targetEntityType, RuntimeEntityType joinEntityType) + { + var skipNavigation = declaringEntityType.AddSkipNavigation( + "Deriveds", + targetEntityType, + joinEntityType.FindForeignKey( + new[] { joinEntityType.FindProperty("PrincipalsId"), joinEntityType.FindProperty("PrincipalsAlternateId") }, + declaringEntityType.FindKey(new[] { declaringEntityType.FindProperty("Id"), declaringEntityType.FindProperty("AlternateId") }), + declaringEntityType), + true, + false, + typeof(ICollection), + propertyInfo: typeof(CompiledModelTestBase.PrincipalBase).GetProperty("Deriveds", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalBase).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var inverse = targetEntityType.FindSkipNavigation("Principals"); + if (inverse != null) + { + skipNavigation.Inverse = inverse; + inverse.Inverse = skipNavigation; + } + + return skipNavigation; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + runtimeEntityType.AddAnnotation("Relational:FunctionName", null); + runtimeEntityType.AddAnnotation("Relational:MappingStrategy", "TPT"); + runtimeEntityType.AddAnnotation("Relational:Schema", "mySchema"); + runtimeEntityType.AddAnnotation("Relational:SqlQuery", null); + runtimeEntityType.AddAnnotation("Relational:TableName", "PrincipalBase"); + runtimeEntityType.AddAnnotation("Relational:ViewName", null); + runtimeEntityType.AddAnnotation("Relational:ViewSchema", null); + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs new file mode 100644 index 00000000000..53b6d7eae37 --- /dev/null +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalBasePrincipalDerivedDependentBasebyteEntityType.cs @@ -0,0 +1,111 @@ +// +using System; +using System.Collections.Generic; +using System.Reflection; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class PrincipalBasePrincipalDerivedDependentBasebyteEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "PrincipalBasePrincipalDerived>", + typeof(Dictionary), + baseEntityType, + sharedClrType: true, + indexerPropertyInfo: RuntimeEntityType.FindIndexerProperty(typeof(Dictionary)), + propertyBag: true, + propertyCount: 5, + foreignKeyCount: 2, + unnamedIndexCount: 1, + keyCount: 1); + + var derivedsId = runtimeEntityType.AddProperty( + "DerivedsId", + typeof(long), + propertyInfo: runtimeEntityType.FindIndexerPropertyInfo(), + afterSaveBehavior: PropertySaveBehavior.Throw); + + var derivedsAlternateId = runtimeEntityType.AddProperty( + "DerivedsAlternateId", + typeof(Guid), + propertyInfo: runtimeEntityType.FindIndexerPropertyInfo(), + afterSaveBehavior: PropertySaveBehavior.Throw); + + var principalsId = runtimeEntityType.AddProperty( + "PrincipalsId", + typeof(long), + propertyInfo: runtimeEntityType.FindIndexerPropertyInfo(), + afterSaveBehavior: PropertySaveBehavior.Throw); + + var principalsAlternateId = runtimeEntityType.AddProperty( + "PrincipalsAlternateId", + typeof(Guid), + propertyInfo: runtimeEntityType.FindIndexerPropertyInfo(), + afterSaveBehavior: PropertySaveBehavior.Throw); + + var rowid = runtimeEntityType.AddProperty( + "rowid", + typeof(byte[]), + propertyInfo: runtimeEntityType.FindIndexerPropertyInfo(), + nullable: true, + concurrencyToken: true, + valueGenerated: ValueGenerated.OnAddOrUpdate, + beforeSaveBehavior: PropertySaveBehavior.Ignore, + afterSaveBehavior: PropertySaveBehavior.Ignore); + + var key = runtimeEntityType.AddKey( + new[] { derivedsId, derivedsAlternateId, principalsId, principalsAlternateId }); + runtimeEntityType.SetPrimaryKey(key); + + var index = runtimeEntityType.AddIndex( + new[] { principalsId, principalsAlternateId }); + + return runtimeEntityType; + } + + public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("DerivedsId"), declaringEntityType.FindProperty("DerivedsAlternateId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("Id"), principalEntityType.FindProperty("AlternateId") }), + principalEntityType, + deleteBehavior: DeleteBehavior.Cascade, + required: true); + + return runtimeForeignKey; + } + + public static RuntimeForeignKey CreateForeignKey2(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("PrincipalsId"), declaringEntityType.FindProperty("PrincipalsAlternateId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("Id"), principalEntityType.FindProperty("AlternateId") }), + principalEntityType, + deleteBehavior: DeleteBehavior.Cascade, + required: true); + + return runtimeForeignKey; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + runtimeEntityType.AddAnnotation("Relational:FunctionName", null); + runtimeEntityType.AddAnnotation("Relational:Schema", null); + runtimeEntityType.AddAnnotation("Relational:SqlQuery", null); + runtimeEntityType.AddAnnotation("Relational:TableName", "PrincipalBasePrincipalDerived>"); + runtimeEntityType.AddAnnotation("Relational:ViewName", null); + runtimeEntityType.AddAnnotation("Relational:ViewSchema", null); + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalDerivedEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalDerivedEntityType.cs new file mode 100644 index 00000000000..757c5ab1800 --- /dev/null +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/PrincipalDerivedEntityType.cs @@ -0,0 +1,84 @@ +// +using System; +using System.Collections.Generic; +using System.Reflection; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class PrincipalDerivedEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalDerived>", + typeof(CompiledModelTestBase.PrincipalDerived>), + baseEntityType, + discriminatorValue: "PrincipalDerived>", + propertyCount: 0, + navigationCount: 2, + skipNavigationCount: 1, + foreignKeyCount: 1); + + return runtimeEntityType; + } + + public static RuntimeForeignKey CreateForeignKey1(RuntimeEntityType declaringEntityType, RuntimeEntityType principalEntityType) + { + var runtimeForeignKey = declaringEntityType.AddForeignKey(new[] { declaringEntityType.FindProperty("Id"), declaringEntityType.FindProperty("AlternateId") }, + principalEntityType.FindKey(new[] { principalEntityType.FindProperty("Id"), principalEntityType.FindProperty("AlternateId") }), + principalEntityType, + deleteBehavior: DeleteBehavior.Cascade, + unique: true, + required: true); + + return runtimeForeignKey; + } + + public static RuntimeSkipNavigation CreateSkipNavigation1(RuntimeEntityType declaringEntityType, RuntimeEntityType targetEntityType, RuntimeEntityType joinEntityType) + { + var skipNavigation = declaringEntityType.AddSkipNavigation( + "Principals", + targetEntityType, + joinEntityType.FindForeignKey( + new[] { joinEntityType.FindProperty("DerivedsId"), joinEntityType.FindProperty("DerivedsAlternateId") }, + declaringEntityType.FindKey(new[] { declaringEntityType.FindProperty("Id"), declaringEntityType.FindProperty("AlternateId") }), + declaringEntityType), + true, + false, + typeof(ICollection), + propertyInfo: typeof(CompiledModelTestBase.PrincipalDerived>).GetProperty("Principals", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelTestBase.PrincipalDerived>).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + + var inverse = targetEntityType.FindSkipNavigation("Deriveds"); + if (inverse != null) + { + skipNavigation.Inverse = inverse; + inverse.Inverse = skipNavigation; + } + + return skipNavigation; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + runtimeEntityType.AddAnnotation("Relational:FunctionName", null); + runtimeEntityType.AddAnnotation("Relational:Schema", null); + runtimeEntityType.AddAnnotation("Relational:SqlQuery", null); + runtimeEntityType.AddAnnotation("Relational:TableName", "PrincipalDerived"); + runtimeEntityType.AddAnnotation("Relational:ViewName", null); + runtimeEntityType.AddAnnotation("Relational:ViewSchema", null); + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/SimpleModel/DependentDerivedEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/SimpleModel/DependentDerivedEntityType.cs index 173e60df6c9..29bd98e0f3e 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/SimpleModel/DependentDerivedEntityType.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/SimpleModel/DependentDerivedEntityType.cs @@ -111,8 +111,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var data = runtimeEntityType.FindProperty("Data")!; + var id = runtimeEntityType.FindProperty("Id"); + var data = runtimeEntityType.FindProperty("Data"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/Triggers/DataEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/Triggers/DataEntityType.cs index 2d335351ee5..5529d639eec 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/Triggers/DataEntityType.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/Triggers/DataEntityType.cs @@ -122,8 +122,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) { - var id = runtimeEntityType.FindProperty("Id")!; - var blob = runtimeEntityType.FindProperty("Blob")!; + var id = runtimeEntityType.FindProperty("Id"); + var blob = runtimeEntityType.FindProperty("Blob"); var key = runtimeEntityType.FindKey(new[] { id }); key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/CompiledModelSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/CompiledModelSqliteTest.cs index d1a4db51221..010499c6527 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/CompiledModelSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/CompiledModelSqliteTest.cs @@ -6,8 +6,8 @@ using System.Runtime.CompilerServices; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Sqlite.Design.Internal; -using NetTopologySuite.Geometries; using NetTopologySuite; +using NetTopologySuite.Geometries; namespace Microsoft.EntityFrameworkCore.Scaffolding; @@ -92,15 +92,19 @@ public override Task Sequences() public override Task Tpc_Sprocs() => Task.CompletedTask; - protected override TestHelpers TestHelpers => SqliteTestHelpers.Instance; - protected override ITestStoreFactory TestStoreFactory => SqliteTestStoreFactory.Instance; + protected override TestHelpers TestHelpers + => SqliteTestHelpers.Instance; + + protected override ITestStoreFactory TestStoreFactory + => SqliteTestStoreFactory.Instance; protected override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) { builder = base.AddOptions(builder) - .ConfigureWarnings(w => w - .Ignore(SqliteEventId.SchemaConfiguredWarning) - .Ignore(SqliteEventId.CompositeKeyWithValueGeneration)); + .ConfigureWarnings( + w => w + .Ignore(SqliteEventId.SchemaConfiguredWarning) + .Ignore(SqliteEventId.CompositeKeyWithValueGeneration)); new SqliteDbContextOptionsBuilder(builder).UseNetTopologySuite(); return builder; } diff --git a/test/EFCore.Sqlite.FunctionalTests/SqliteApiConsistencyTest.cs b/test/EFCore.Sqlite.FunctionalTests/SqliteApiConsistencyTest.cs index 78caa579e80..31825860234 100644 --- a/test/EFCore.Sqlite.FunctionalTests/SqliteApiConsistencyTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/SqliteApiConsistencyTest.cs @@ -7,7 +7,8 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class SqliteApiConsistencyTest(SqliteApiConsistencyTest.SqliteApiConsistencyFixture fixture) : ApiConsistencyTestBase(fixture) +public class SqliteApiConsistencyTest(SqliteApiConsistencyTest.SqliteApiConsistencyFixture fixture) + : ApiConsistencyTestBase(fixture) { protected override void AddServices(ServiceCollection serviceCollection) => serviceCollection.AddEntityFrameworkSqlite(); @@ -22,7 +23,9 @@ public class SqliteApiConsistencyFixture : ApiConsistencyFixtureBase typeof(SqliteServiceCollectionExtensions), typeof(SqliteDbContextOptionsBuilderExtensions), typeof(SqliteDbContextOptionsBuilder), - typeof(SqlitePropertyBuilderExtensions) + typeof(SqlitePropertyBuilderExtensions), + typeof(SqliteEntityTypeBuilderExtensions), + typeof(SqliteTableBuilderExtensions) ]; public override @@ -31,7 +34,10 @@ public override Type MutableExtensions, Type ConventionExtensions, Type ConventionBuilderExtensions, - Type RuntimeExtensions)> MetadataExtensionTypes { get; } + Type RuntimeExtensions)> MetadataExtensionTypes + { + get; + } = new() { { @@ -42,6 +48,15 @@ public override typeof(SqlitePropertyBuilderExtensions), null ) + }, + { + typeof(IReadOnlyEntityType), ( + typeof(SqliteEntityTypeExtensions), + typeof(SqliteEntityTypeExtensions), + typeof(SqliteEntityTypeExtensions), + typeof(SqliteEntityTypeBuilderExtensions), + null + ) } }; diff --git a/test/EFCore.Sqlite.FunctionalTests/SqliteDatabaseCreatorTest.cs b/test/EFCore.Sqlite.FunctionalTests/SqliteDatabaseCreatorTest.cs index 4e4ccb8f3c3..91d626f43c6 100644 --- a/test/EFCore.Sqlite.FunctionalTests/SqliteDatabaseCreatorTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/SqliteDatabaseCreatorTest.cs @@ -36,7 +36,7 @@ public async Task Exists_returns_false_when_database_doesnt_exist(bool async, bo [InlineData(true)] public async Task HasTables_returns_false_when_database_is_empty(bool async) { - using var testStore = await SqliteTestStore.GetOrCreateInitializedAsync("Empty"); + await using var testStore = await SqliteTestStore.GetOrCreateInitializedAsync("Empty"); var context = CreateContext(testStore.ConnectionString); var creator = context.GetService(); @@ -48,7 +48,7 @@ public async Task HasTables_returns_false_when_database_is_empty(bool async) [InlineData(true)] public async Task HasTables_returns_true_when_database_is_not_empty(bool async) { - using var testStore = await SqliteTestStore.GetOrCreateInitializedAsync($"HasATable{(async ? 'A' : 'S')}"); + await using var testStore = await SqliteTestStore.GetOrCreateInitializedAsync($"HasATable{(async ? 'A' : 'S')}"); var context = CreateContext(testStore.ConnectionString); context.Database.ExecuteSqlRaw("CREATE TABLE Dummy (Foo INTEGER)"); @@ -63,7 +63,7 @@ public async Task HasTables_returns_true_when_database_is_not_empty(bool async) [InlineData(true, true)] public async Task Exists_returns_true_when_database_exists(bool async, bool useCanConnect) { - using var testStore = await SqliteTestStore.GetOrCreateInitializedAsync("Empty"); + await using var testStore = await SqliteTestStore.GetOrCreateInitializedAsync("Empty"); var context = CreateContext(testStore.ConnectionString); if (useCanConnect) @@ -82,7 +82,7 @@ public async Task Exists_returns_true_when_database_exists(bool async, bool useC [InlineData(true)] public async Task Create_sets_journal_mode_to_wal(bool async) { - using var testStore = SqliteTestStore.GetOrCreate("Create"); + await using var testStore = SqliteTestStore.GetOrCreate("Create"); using var context = CreateContext(testStore.ConnectionString); var creator = context.GetService(); diff --git a/test/EFCore.Sqlite.FunctionalTests/StoreGeneratedFixupSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/StoreGeneratedFixupSqliteTest.cs index aa4b7ebd418..e40f6e4b3a9 100644 --- a/test/EFCore.Sqlite.FunctionalTests/StoreGeneratedFixupSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/StoreGeneratedFixupSqliteTest.cs @@ -7,8 +7,9 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class StoreGeneratedFixupSqliteTest(StoreGeneratedFixupSqliteTest.StoreGeneratedFixupSqliteFixture fixture) : StoreGeneratedFixupRelationalTestBase< - StoreGeneratedFixupSqliteTest.StoreGeneratedFixupSqliteFixture>(fixture) +public class StoreGeneratedFixupSqliteTest(StoreGeneratedFixupSqliteTest.StoreGeneratedFixupSqliteFixture fixture) + : StoreGeneratedFixupRelationalTestBase< + StoreGeneratedFixupSqliteTest.StoreGeneratedFixupSqliteFixture>(fixture) { [ConditionalFact] public void Temp_values_can_be_made_permanent() diff --git a/test/EFCore.Sqlite.FunctionalTests/TestUtilities/SqliteTestStore.cs b/test/EFCore.Sqlite.FunctionalTests/TestUtilities/SqliteTestStore.cs index 823452e857e..f53602725cf 100644 --- a/test/EFCore.Sqlite.FunctionalTests/TestUtilities/SqliteTestStore.cs +++ b/test/EFCore.Sqlite.FunctionalTests/TestUtilities/SqliteTestStore.cs @@ -72,7 +72,7 @@ protected override async Task InitializeAsync(Func createContext, Fun } using var context = createContext(); - if (!await context.Database.EnsureCreatedAsync()) + if (!await context.Database.EnsureCreatedResilientlyAsync()) { if (clean != null) { @@ -80,6 +80,9 @@ protected override async Task InitializeAsync(Func createContext, Fun } await CleanAsync(context); + + // Run context seeding + await context.Database.EnsureCreatedResilientlyAsync(); } if (seed != null) diff --git a/test/EFCore.Sqlite.FunctionalTests/TransactionInterceptionSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/TransactionInterceptionSqliteTest.cs index 028369c7f36..7396072f8b7 100644 --- a/test/EFCore.Sqlite.FunctionalTests/TransactionInterceptionSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/TransactionInterceptionSqliteTest.cs @@ -32,7 +32,8 @@ protected override bool ShouldSubscribeToDiagnosticListener } } - public class TransactionInterceptionWithDiagnosticsSqliteTest(TransactionInterceptionWithDiagnosticsSqliteTest.InterceptionSqliteFixture fixture) + public class TransactionInterceptionWithDiagnosticsSqliteTest( + TransactionInterceptionWithDiagnosticsSqliteTest.InterceptionSqliteFixture fixture) : TransactionInterceptionSqliteTestBase(fixture), IClassFixture { diff --git a/test/EFCore.Sqlite.FunctionalTests/TwoDatabasesSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/TwoDatabasesSqliteTest.cs index f3b6a70ed7f..9aabe4fddb8 100644 --- a/test/EFCore.Sqlite.FunctionalTests/TwoDatabasesSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/TwoDatabasesSqliteTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class TwoDatabasesSqliteTest(TwoDatabasesSqliteTest.TwoDatabasesFixture fixture) : TwoDatabasesTestBase(fixture), IClassFixture +public class TwoDatabasesSqliteTest(TwoDatabasesSqliteTest.TwoDatabasesFixture fixture) + : TwoDatabasesTestBase(fixture), IClassFixture { protected new TwoDatabasesFixture Fixture => (TwoDatabasesFixture)base.Fixture; diff --git a/test/EFCore.Sqlite.FunctionalTests/Update/JsonUpdateSqliteFixture.cs b/test/EFCore.Sqlite.FunctionalTests/Update/JsonUpdateSqliteFixture.cs index d8f6ebdda8a..c6b42f3648b 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Update/JsonUpdateSqliteFixture.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Update/JsonUpdateSqliteFixture.cs @@ -11,6 +11,7 @@ public class JsonUpdateSqliteFixture : JsonUpdateFixtureBase { protected override ITestStoreFactory TestStoreFactory => SqliteTestStoreFactory.Instance; + protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) { base.OnModelCreating(modelBuilder, context); diff --git a/test/EFCore.Sqlite.FunctionalTests/Update/JsonUpdateSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Update/JsonUpdateSqliteTest.cs index d679cb568de..a1135663a47 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Update/JsonUpdateSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Update/JsonUpdateSqliteTest.cs @@ -11,9 +11,7 @@ public class JsonUpdateSqliteTest : JsonUpdateTestBase { public JsonUpdateSqliteTest(JsonUpdateSqliteFixture fixture) : base(fixture) - { - ClearLog(); - } + => ClearLog(); public override async Task Add_element_to_json_collection_branch() { @@ -21,7 +19,7 @@ public override async Task Add_element_to_json_collection_branch() AssertSql( """ -@p0='[{"Date":"2101-01-01 00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":"10.1","NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_c1_c1"},{"SomethingSomething":"e1_r_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_c1_r"}},{"Date":"2102-01-01 00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":"10.2","NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_c2_c1"},{"SomethingSomething":"e1_r_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_c2_r"}},{"Date":"2010-10-10 00:00:00","Enum":-3,"Enums":null,"Fraction":"42.42","NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":[{"SomethingSomething":"ss1"},{"SomethingSomething":"ss2"}],"OwnedReferenceLeaf":{"SomethingSomething":"ss3"}}]' (Nullable = false) (Size = 795) +@p0='[{"Date":"2101-01-01 00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":"10.1","Id":89,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_c1_c1"},{"SomethingSomething":"e1_r_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_c1_r"}},{"Date":"2102-01-01 00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":"10.2","Id":90,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_c2_c1"},{"SomethingSomething":"e1_r_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_c2_r"}},{"Date":"2010-10-10 00:00:00","Enum":-3,"Enums":null,"Fraction":"42.42","Id":77,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":[{"SomethingSomething":"ss1"},{"SomethingSomething":"ss2"}],"OwnedReferenceLeaf":{"SomethingSomething":"ss3"}}]' (Nullable = false) (Size = 819) @p1='1' UPDATE "JsonEntitiesBasic" SET "OwnedReferenceRoot" = json_set("OwnedReferenceRoot", '$.OwnedCollectionBranch', json(@p0)) @@ -63,7 +61,7 @@ public override async Task Add_element_to_json_collection_on_derived() AssertSql( """ -@p0='[{"Date":"2221-01-01 00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":"221.1","NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"d2_r_c1"},{"SomethingSomething":"d2_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"d2_r_r"}},{"Date":"2222-01-01 00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":"222.1","NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"d2_r_c1"},{"SomethingSomething":"d2_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"d2_r_r"}},{"Date":"2010-10-10 00:00:00","Enum":-3,"Enums":null,"Fraction":"42.42","NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":[{"SomethingSomething":"ss1"},{"SomethingSomething":"ss2"}],"OwnedReferenceLeaf":{"SomethingSomething":"ss3"}}]' (Nullable = false) (Size = 779) +@p0='[{"Date":"2221-01-01 00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":"221.1","Id":104,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"d2_r_c1"},{"SomethingSomething":"d2_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"d2_r_r"}},{"Date":"2222-01-01 00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":"222.1","Id":105,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"d2_r_c1"},{"SomethingSomething":"d2_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"d2_r_r"}},{"Date":"2010-10-10 00:00:00","Enum":-3,"Enums":null,"Fraction":"42.42","Id":77,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":[{"SomethingSomething":"ss1"},{"SomethingSomething":"ss2"}],"OwnedReferenceLeaf":{"SomethingSomething":"ss3"}}]' (Nullable = false) (Size = 805) @p1='2' UPDATE "JsonEntitiesInheritance" SET "CollectionOnDerived" = @p0 @@ -85,7 +83,7 @@ public override async Task Add_element_to_json_collection_root() AssertSql( """ -@p0='[{"Name":"e1_c1","Names":["e1_c11","e1_c12"],"Number":11,"Numbers":[-1000,0,1000],"OwnedCollectionBranch":[{"Date":"2111-01-01 00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":"11.1","NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_c1_c1"},{"SomethingSomething":"e1_c1_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c1_r"}},{"Date":"2112-01-01 00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":"11.2","NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_c2_c1"},{"SomethingSomething":"e1_c1_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c2_r"}}],"OwnedReferenceBranch":{"Date":"2110-01-01 00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":"11.0","NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_r_c1"},{"SomethingSomething":"e1_c1_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_r_r"}}},{"Name":"e1_c2","Names":["e1_c21","e1_c22"],"Number":12,"Numbers":[-1001,0,1001],"OwnedCollectionBranch":[{"Date":"2121-01-01 00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":"12.1","NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_c1_c1"},{"SomethingSomething":"e1_c2_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_c1_r"}},{"Date":"2122-01-01 00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":"12.2","NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_c2_c1"},{"SomethingSomething":"e1_c2_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_c2_r"}}],"OwnedReferenceBranch":{"Date":"2120-01-01 00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":"12.0","NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_r_c1"},{"SomethingSomething":"e1_c2_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_r_r"}}},{"Name":"new Name","Names":null,"Number":142,"Numbers":null,"OwnedCollectionBranch":[],"OwnedReferenceBranch":{"Date":"2010-10-10 00:00:00","Enum":-3,"Enums":null,"Fraction":"42.42","NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":[{"SomethingSomething":"ss1"},{"SomethingSomething":"ss2"}],"OwnedReferenceLeaf":{"SomethingSomething":"ss3"}}}]' (Nullable = false) (Size = 2282) +@p0='[{"Id":0,"Name":"e1_c1","Names":["e1_c11","e1_c12"],"Number":11,"Numbers":[-1000,0,1000],"OwnedCollectionBranch":[{"Date":"2111-01-01 00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":"11.1","Id":92,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_c1_c1"},{"SomethingSomething":"e1_c1_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c1_r"}},{"Date":"2112-01-01 00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":"11.2","Id":93,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_c2_c1"},{"SomethingSomething":"e1_c1_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c2_r"}}],"OwnedReferenceBranch":{"Date":"2110-01-01 00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":"11.0","Id":91,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_r_c1"},{"SomethingSomething":"e1_c1_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_r_r"}}},{"Id":0,"Name":"e1_c2","Names":["e1_c21","e1_c22"],"Number":12,"Numbers":[-1001,0,1001],"OwnedCollectionBranch":[{"Date":"2121-01-01 00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":"12.1","Id":95,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_c1_c1"},{"SomethingSomething":"e1_c2_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_c1_r"}},{"Date":"2122-01-01 00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":"12.2","Id":96,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_c2_c1"},{"SomethingSomething":"e1_c2_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_c2_r"}}],"OwnedReferenceBranch":{"Date":"2120-01-01 00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":"12.0","Id":94,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_r_c1"},{"SomethingSomething":"e1_c2_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_r_r"}}},{"Id":0,"Name":"new Name","Names":null,"Number":142,"Numbers":null,"OwnedCollectionBranch":[],"OwnedReferenceBranch":{"Date":"2010-10-10 00:00:00","Enum":-3,"Enums":null,"Fraction":"42.42","Id":7,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":[{"SomethingSomething":"ss1"},{"SomethingSomething":"ss2"}],"OwnedReferenceLeaf":{"SomethingSomething":"ss3"}}}]' (Nullable = false) (Size = 2358) @p1='1' UPDATE "JsonEntitiesBasic" SET "OwnedCollectionRoot" = @p0 @@ -106,7 +104,7 @@ public override async Task Add_element_to_json_collection_root_null_navigations( AssertSql( """ -@p0='[{"Name":"e1_c1","Names":["e1_c11","e1_c12"],"Number":11,"Numbers":[-1000,0,1000],"OwnedCollectionBranch":[{"Date":"2111-01-01 00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":"11.1","NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_c1_c1"},{"SomethingSomething":"e1_c1_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c1_r"}},{"Date":"2112-01-01 00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":"11.2","NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_c2_c1"},{"SomethingSomething":"e1_c1_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c2_r"}}],"OwnedReferenceBranch":{"Date":"2110-01-01 00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":"11.0","NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_r_c1"},{"SomethingSomething":"e1_c1_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_r_r"}}},{"Name":"e1_c2","Names":["e1_c21","e1_c22"],"Number":12,"Numbers":[-1001,0,1001],"OwnedCollectionBranch":[{"Date":"2121-01-01 00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":"12.1","NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_c1_c1"},{"SomethingSomething":"e1_c2_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_c1_r"}},{"Date":"2122-01-01 00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":"12.2","NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_c2_c1"},{"SomethingSomething":"e1_c2_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_c2_r"}}],"OwnedReferenceBranch":{"Date":"2120-01-01 00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":"12.0","NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_r_c1"},{"SomethingSomething":"e1_c2_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_r_r"}}},{"Name":"new Name","Names":null,"Number":142,"Numbers":null,"OwnedCollectionBranch":null,"OwnedReferenceBranch":{"Date":"2010-10-10 00:00:00","Enum":-3,"Enums":null,"Fraction":"42.42","NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":null,"OwnedReferenceLeaf":null}}]' (Nullable = false) (Size = 2205) +@p0='[{"Id":0,"Name":"e1_c1","Names":["e1_c11","e1_c12"],"Number":11,"Numbers":[-1000,0,1000],"OwnedCollectionBranch":[{"Date":"2111-01-01 00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":"11.1","Id":92,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_c1_c1"},{"SomethingSomething":"e1_c1_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c1_r"}},{"Date":"2112-01-01 00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":"11.2","Id":93,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_c2_c1"},{"SomethingSomething":"e1_c1_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c2_r"}}],"OwnedReferenceBranch":{"Date":"2110-01-01 00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":"11.0","Id":91,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_r_c1"},{"SomethingSomething":"e1_c1_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_r_r"}}},{"Id":0,"Name":"e1_c2","Names":["e1_c21","e1_c22"],"Number":12,"Numbers":[-1001,0,1001],"OwnedCollectionBranch":[{"Date":"2121-01-01 00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":"12.1","Id":95,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_c1_c1"},{"SomethingSomething":"e1_c2_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_c1_r"}},{"Date":"2122-01-01 00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":"12.2","Id":96,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_c2_c1"},{"SomethingSomething":"e1_c2_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_c2_r"}}],"OwnedReferenceBranch":{"Date":"2120-01-01 00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":"12.0","Id":94,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_r_c1"},{"SomethingSomething":"e1_c2_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_r_r"}}},{"Id":0,"Name":"new Name","Names":null,"Number":142,"Numbers":null,"OwnedCollectionBranch":null,"OwnedReferenceBranch":{"Date":"2010-10-10 00:00:00","Enum":-3,"Enums":null,"Fraction":"42.42","Id":7,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":null,"OwnedReferenceLeaf":null}}]' (Nullable = false) (Size = 2281) @p1='1' UPDATE "JsonEntitiesBasic" SET "OwnedCollectionRoot" = @p0 @@ -127,7 +125,7 @@ public override async Task Add_entity_with_json() AssertSql( """ -@p0='{"Name":"RootName","Names":null,"Number":42,"Numbers":null,"OwnedCollectionBranch":[],"OwnedReferenceBranch":{"Date":"2010-10-10 00:00:00","Enum":-3,"Enums":null,"Fraction":"42.42","NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":[{"SomethingSomething":"ss1"},{"SomethingSomething":"ss2"}],"OwnedReferenceLeaf":{"SomethingSomething":"ss3"}}}' (Nullable = false) (Size = 355) +@p0='{"Id":0,"Name":"RootName","Names":null,"Number":42,"Numbers":null,"OwnedCollectionBranch":[],"OwnedReferenceBranch":{"Date":"2010-10-10 00:00:00","Enum":-3,"Enums":null,"Fraction":"42.42","Id":7,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":[{"SomethingSomething":"ss1"},{"SomethingSomething":"ss2"}],"OwnedReferenceLeaf":{"SomethingSomething":"ss3"}}}' (Nullable = false) (Size = 369) @p1='[]' (Nullable = false) (Size = 2) @p2='2' @p3=NULL (DbType = Int32) @@ -149,7 +147,7 @@ public override async Task Add_entity_with_json_null_navigations() AssertSql( """ -@p0='{"Name":"RootName","Names":null,"Number":42,"Numbers":null,"OwnedCollectionBranch":null,"OwnedReferenceBranch":{"Date":"2010-10-10 00:00:00","Enum":-3,"Enums":null,"Fraction":"42.42","NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":[{"SomethingSomething":"ss1"},{"SomethingSomething":"ss2"}],"OwnedReferenceLeaf":null}}' (Nullable = false) (Size = 333) +@p0='{"Id":0,"Name":"RootName","Names":null,"Number":42,"Numbers":null,"OwnedCollectionBranch":null,"OwnedReferenceBranch":{"Date":"2010-10-10 00:00:00","Enum":-3,"Enums":null,"Fraction":"42.42","Id":7,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":[{"SomethingSomething":"ss1"},{"SomethingSomething":"ss2"}],"OwnedReferenceLeaf":null}}' (Nullable = false) (Size = 347) @p1='2' @p2=NULL (DbType = Int32) @p3='NewEntity' (Size = 9) @@ -191,7 +189,7 @@ public override async Task Add_json_reference_root() AssertSql( """ -@p0='{"Name":"RootName","Names":null,"Number":42,"Numbers":null,"OwnedCollectionBranch":[],"OwnedReferenceBranch":{"Date":"2010-10-10 00:00:00","Enum":-3,"Enums":null,"Fraction":"42.42","NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":[{"SomethingSomething":"ss1"},{"SomethingSomething":"ss2"}],"OwnedReferenceLeaf":{"SomethingSomething":"ss3"}}}' (Nullable = false) (Size = 355) +@p0='{"Id":0,"Name":"RootName","Names":null,"Number":42,"Numbers":null,"OwnedCollectionBranch":[],"OwnedReferenceBranch":{"Date":"2010-10-10 00:00:00","Enum":-3,"Enums":null,"Fraction":"42.42","Id":7,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":[{"SomethingSomething":"ss1"},{"SomethingSomething":"ss2"}],"OwnedReferenceLeaf":{"SomethingSomething":"ss3"}}}' (Nullable = false) (Size = 369) @p1='1' UPDATE "JsonEntitiesBasic" SET "OwnedReferenceRoot" = @p0 @@ -378,8 +376,8 @@ public override async Task Edit_element_in_json_multiple_levels_partial_update() AssertSql( """ -@p0='[{"Date":"2111-01-01 00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":"11.1","NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"...and another"},{"SomethingSomething":"e1_c1_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c1_r"}},{"Date":"2112-01-01 00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":"11.2","NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"yet another change"},{"SomethingSomething":"and another"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c2_r"}}]' (Nullable = false) (Size = 565) -@p1='{"Name":"edit","Names":["e1_r1","e1_r2"],"Number":10,"Numbers":[-2147483648,-1,0,1,2147483647],"OwnedCollectionBranch":[{"Date":"2101-01-01 00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":"10.1","NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_c1_c1"},{"SomethingSomething":"e1_r_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_c1_r"}},{"Date":"2102-01-01 00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":"10.2","NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_c2_c1"},{"SomethingSomething":"e1_r_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_c2_r"}}],"OwnedReferenceBranch":{"Date":"2111-11-11 00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":"10.0","NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_r_c1"},{"SomethingSomething":"e1_r_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_r_r"}}}' (Nullable = false) (Size = 966) +@p0='[{"Date":"2111-01-01 00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":"11.1","Id":92,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"...and another"},{"SomethingSomething":"e1_c1_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c1_r"}},{"Date":"2112-01-01 00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":"11.2","Id":93,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"yet another change"},{"SomethingSomething":"and another"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c2_r"}}]' (Nullable = false) (Size = 581) +@p1='{"Id":0,"Name":"edit","Names":["e1_r1","e1_r2"],"Number":10,"Numbers":[-2147483648,-1,0,1,2147483647],"OwnedCollectionBranch":[{"Date":"2101-01-01 00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":"10.1","Id":89,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_c1_c1"},{"SomethingSomething":"e1_r_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_c1_r"}},{"Date":"2102-01-01 00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":"10.2","Id":90,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_c2_c1"},{"SomethingSomething":"e1_r_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_c2_r"}}],"OwnedReferenceBranch":{"Date":"2111-11-11 00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":"10.0","Id":88,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_r_c1"},{"SomethingSomething":"e1_r_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_r_r"}}}' (Nullable = false) (Size = 997) @p2='1' UPDATE "JsonEntitiesBasic" SET "OwnedCollectionRoot" = json_set("OwnedCollectionRoot", '$[0].OwnedCollectionBranch', json(@p0)), "OwnedReferenceRoot" = @p1 @@ -400,7 +398,7 @@ public override async Task Edit_element_in_json_branch_collection_and_add_elemen AssertSql( """ -@p0='[{"Date":"2101-01-01 00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":"4321.3","NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_c1_c1"},{"SomethingSomething":"e1_r_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_c1_r"}},{"Date":"2102-01-01 00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":"10.2","NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_c2_c1"},{"SomethingSomething":"e1_r_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_c2_r"}},{"Date":"2222-11-11 00:00:00","Enum":-3,"Enums":null,"Fraction":"45.32","NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":null,"OwnedReferenceLeaf":{"SomethingSomething":"cc"}}]' (Nullable = false) (Size = 741) +@p0='[{"Date":"2101-01-01 00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":"4321.3","Id":89,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_c1_c1"},{"SomethingSomething":"e1_r_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_c1_r"}},{"Date":"2102-01-01 00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":"10.2","Id":90,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_c2_c1"},{"SomethingSomething":"e1_r_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_c2_r"}},{"Date":"2222-11-11 00:00:00","Enum":-3,"Enums":null,"Fraction":"45.32","Id":77,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":null,"OwnedReferenceLeaf":{"SomethingSomething":"cc"}}]' (Nullable = false) (Size = 765) @p1='1' UPDATE "JsonEntitiesBasic" SET "OwnedReferenceRoot" = json_set("OwnedReferenceRoot", '$.OwnedCollectionBranch', json(@p0)) @@ -442,7 +440,7 @@ public override async Task Edit_two_elements_in_the_same_json_collection_at_the_ AssertSql( """ -@p0='[{"Name":"edit1","Names":["e1_c11","e1_c12"],"Number":11,"Numbers":[-1000,0,1000],"OwnedCollectionBranch":[{"Date":"2111-01-01 00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":"11.1","NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_c1_c1"},{"SomethingSomething":"e1_c1_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c1_r"}},{"Date":"2112-01-01 00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":"11.2","NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_c2_c1"},{"SomethingSomething":"e1_c1_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c2_r"}}],"OwnedReferenceBranch":{"Date":"2110-01-01 00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":"11.0","NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_r_c1"},{"SomethingSomething":"e1_c1_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_r_r"}}},{"Name":"edit2","Names":["e1_c21","e1_c22"],"Number":12,"Numbers":[-1001,0,1001],"OwnedCollectionBranch":[{"Date":"2121-01-01 00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":"12.1","NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_c1_c1"},{"SomethingSomething":"e1_c2_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_c1_r"}},{"Date":"2122-01-01 00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":"12.2","NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_c2_c1"},{"SomethingSomething":"e1_c2_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_c2_r"}}],"OwnedReferenceBranch":{"Date":"2120-01-01 00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":"12.0","NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_r_c1"},{"SomethingSomething":"e1_c2_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_r_r"}}}]' (Nullable = false) (Size = 1925) +@p0='[{"Id":0,"Name":"edit1","Names":["e1_c11","e1_c12"],"Number":11,"Numbers":[-1000,0,1000],"OwnedCollectionBranch":[{"Date":"2111-01-01 00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":"11.1","Id":92,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_c1_c1"},{"SomethingSomething":"e1_c1_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c1_r"}},{"Date":"2112-01-01 00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":"11.2","Id":93,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_c2_c1"},{"SomethingSomething":"e1_c1_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_c2_r"}}],"OwnedReferenceBranch":{"Date":"2110-01-01 00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":"11.0","Id":91,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c1_r_c1"},{"SomethingSomething":"e1_c1_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c1_r_r"}}},{"Id":0,"Name":"edit2","Names":["e1_c21","e1_c22"],"Number":12,"Numbers":[-1001,0,1001],"OwnedCollectionBranch":[{"Date":"2121-01-01 00:00:00","Enum":2,"Enums":[-1,-1,2],"Fraction":"12.1","Id":95,"NullableEnum":-1,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_c1_c1"},{"SomethingSomething":"e1_c2_c1_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_c1_r"}},{"Date":"2122-01-01 00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":"12.2","Id":96,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_c2_c1"},{"SomethingSomething":"e1_c2_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_c2_r"}}],"OwnedReferenceBranch":{"Date":"2120-01-01 00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":"12.0","Id":94,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_c2_r_c1"},{"SomethingSomething":"e1_c2_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_c2_r_r"}}}]' (Nullable = false) (Size = 1987) @p1='1' UPDATE "JsonEntitiesBasic" SET "OwnedCollectionRoot" = @p0 @@ -463,7 +461,7 @@ public override async Task Edit_collection_element_and_reference_at_once() AssertSql( """ -@p0='{"Date":"2102-01-01 00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":"10.2","NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"edit1"},{"SomethingSomething":"e1_r_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"edit2"}}' (Nullable = false) (Size = 264) +@p0='{"Date":"2102-01-01 00:00:00","Enum":-3,"Enums":[-1,-1,2],"Fraction":"10.2","Id":90,"NullableEnum":2,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"edit1"},{"SomethingSomething":"e1_r_c2_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"edit2"}}' (Nullable = false) (Size = 272) @p1='1' UPDATE "JsonEntitiesBasic" SET "OwnedReferenceRoot" = json_set("OwnedReferenceRoot", '$.OwnedCollectionBranch[1]', json(@p0)) @@ -1171,7 +1169,7 @@ public override async Task Edit_a_scalar_property_and_reference_navigation_on_th AssertSql( """ -@p0='{"Date":"2100-01-01 00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":"523.532","NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_r_c1"},{"SomethingSomething":"e1_r_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"edit"}}' (Nullable = false) (Size = 272) +@p0='{"Date":"2100-01-01 00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":"523.532","Id":88,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_r_c1"},{"SomethingSomething":"e1_r_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"edit"}}' (Nullable = false) (Size = 280) @p1='1' UPDATE "JsonEntitiesBasic" SET "OwnedReferenceRoot" = json_set("OwnedReferenceRoot", '$.OwnedReferenceBranch', json(@p0)) @@ -1192,7 +1190,7 @@ public override async Task Edit_a_scalar_property_and_collection_navigation_on_t AssertSql( """ -@p0='{"Date":"2100-01-01 00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":"523.532","NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"edit"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_r_r"}}' (Nullable = false) (Size = 236) +@p0='{"Date":"2100-01-01 00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":"523.532","Id":88,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"edit"}],"OwnedReferenceLeaf":{"SomethingSomething":"e1_r_r_r"}}' (Nullable = false) (Size = 244) @p1='1' UPDATE "JsonEntitiesBasic" SET "OwnedReferenceRoot" = json_set("OwnedReferenceRoot", '$.OwnedReferenceBranch', json(@p0)) @@ -1213,7 +1211,7 @@ public override async Task Edit_a_scalar_property_and_another_property_behind_re AssertSql( """ -@p0='{"Date":"2100-01-01 00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":"523.532","NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_r_c1"},{"SomethingSomething":"e1_r_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"edit"}}' (Nullable = false) (Size = 272) +@p0='{"Date":"2100-01-01 00:00:00","Enum":-1,"Enums":[-1,-1,2],"Fraction":"523.532","Id":88,"NullableEnum":null,"NullableEnums":[null,-1,2],"OwnedCollectionLeaf":[{"SomethingSomething":"e1_r_r_c1"},{"SomethingSomething":"e1_r_r_c2"}],"OwnedReferenceLeaf":{"SomethingSomething":"edit"}}' (Nullable = false) (Size = 280) @p1='1' UPDATE "JsonEntitiesBasic" SET "OwnedReferenceRoot" = json_set("OwnedReferenceRoot", '$.OwnedReferenceBranch', json(@p0)) @@ -2051,8 +2049,8 @@ public override async Task Add_and_update_top_level_optional_owned_collection_to { case true: AssertSql( - """ -@p0='[{"Name":null,"Names":null,"Number":0,"Numbers":null,"OwnedCollectionBranch":null,"OwnedReferenceBranch":null}]' (Nullable = false) (Size = 111) + """ +@p0='[{"Id":0,"Name":null,"Names":null,"Number":0,"Numbers":null,"OwnedCollectionBranch":null,"OwnedReferenceBranch":null}]' (Nullable = false) (Size = 118) @p1='2' @p2=NULL (DbType = Int32) @p3='NewEntity' (Size = 9) @@ -2060,15 +2058,15 @@ public override async Task Add_and_update_top_level_optional_owned_collection_to INSERT INTO "JsonEntitiesBasic" ("OwnedCollectionRoot", "Id", "EntityBasicId", "Name") VALUES (@p0, @p1, @p2, @p3); """, - // - """ + // + """ SELECT "j"."Id", "j"."EntityBasicId", "j"."Name", "j"."OwnedCollectionRoot", "j"."OwnedReferenceRoot" FROM "JsonEntitiesBasic" AS "j" WHERE "j"."Id" = 2 LIMIT 2 """, - // - """ + // + """ @p0=NULL (Nullable = false) @p1='2' @@ -2076,12 +2074,12 @@ LIMIT 2 WHERE "Id" = @p1 RETURNING 1; """, - // - """ + // + """ select OwnedCollectionRoot from JsonEntitiesBasic where Id = 2 """, - // - """ + // + """ SELECT "j"."Id", "j"."EntityBasicId", "j"."Name", "j"."OwnedCollectionRoot", "j"."OwnedReferenceRoot" FROM "JsonEntitiesBasic" AS "j" WHERE "j"."Id" = 2 @@ -2090,7 +2088,7 @@ LIMIT 2 break; case false: AssertSql( - """ + """ @p0='[]' (Nullable = false) (Size = 2) @p1='2' @p2=NULL (DbType = Int32) @@ -2099,28 +2097,28 @@ LIMIT 2 INSERT INTO "JsonEntitiesBasic" ("OwnedCollectionRoot", "Id", "EntityBasicId", "Name") VALUES (@p0, @p1, @p2, @p3); """, - // - """ + // + """ SELECT "j"."Id", "j"."EntityBasicId", "j"."Name", "j"."OwnedCollectionRoot", "j"."OwnedReferenceRoot" FROM "JsonEntitiesBasic" AS "j" WHERE "j"."Id" = 2 LIMIT 2 """, - // - """ -@p0='[{"Name":null,"Names":null,"Number":0,"Numbers":null,"OwnedCollectionBranch":null,"OwnedReferenceBranch":null}]' (Nullable = false) (Size = 111) + // + """ +@p0='[{"Id":0,"Name":null,"Names":null,"Number":0,"Numbers":null,"OwnedCollectionBranch":null,"OwnedReferenceBranch":null}]' (Nullable = false) (Size = 118) @p1='2' UPDATE "JsonEntitiesBasic" SET "OwnedCollectionRoot" = @p0 WHERE "Id" = @p1 RETURNING 1; """, - // - """ + // + """ select OwnedCollectionRoot from JsonEntitiesBasic where Id = 2 """, - // - """ + // + """ SELECT "j"."Id", "j"."EntityBasicId", "j"."Name", "j"."OwnedCollectionRoot", "j"."OwnedReferenceRoot" FROM "JsonEntitiesBasic" AS "j" WHERE "j"."Id" = 2 @@ -2129,7 +2127,7 @@ LIMIT 2 break; default: AssertSql( - """ + """ @p0='2' @p1=NULL (DbType = Int32) @p2='NewEntity' (Size = 9) @@ -2137,15 +2135,15 @@ LIMIT 2 INSERT INTO "JsonEntitiesBasic" ("Id", "EntityBasicId", "Name") VALUES (@p0, @p1, @p2); """, - // - """ + // + """ SELECT "j"."Id", "j"."EntityBasicId", "j"."Name", "j"."OwnedCollectionRoot", "j"."OwnedReferenceRoot" FROM "JsonEntitiesBasic" AS "j" WHERE "j"."Id" = 2 LIMIT 2 """, - // - """ + // + """ @p0='[]' (Nullable = false) (Size = 2) @p3='2' @p1=NULL (DbType = Int32) @@ -2155,12 +2153,12 @@ LIMIT 2 WHERE "Id" = @p3 RETURNING 1; """, - // - """ + // + """ select OwnedCollectionRoot from JsonEntitiesBasic where Id = 2 """, - // - """ + // + """ SELECT "j"."Id", "j"."EntityBasicId", "j"."Name", "j"."OwnedCollectionRoot", "j"."OwnedReferenceRoot" FROM "JsonEntitiesBasic" AS "j" WHERE "j"."Id" = 2 @@ -2178,8 +2176,8 @@ public override async Task Add_and_update_nested_optional_owned_collection_to_JS { case true: AssertSql( - """ -@p0='{"Name":null,"Names":null,"Number":0,"Numbers":null,"OwnedCollectionBranch":[{"Date":"0001-01-01 00:00:00","Enum":0,"Enums":null,"Fraction":"0.0","NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":null,"OwnedReferenceLeaf":null}],"OwnedReferenceBranch":null}' (Nullable = false) (Size = 270) + """ +@p0='{"Id":0,"Name":null,"Names":null,"Number":0,"Numbers":null,"OwnedCollectionBranch":[{"Date":"0001-01-01 00:00:00","Enum":0,"Enums":null,"Fraction":"0.0","Id":0,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":null,"OwnedReferenceLeaf":null}],"OwnedReferenceBranch":null}' (Nullable = false) (Size = 284) @p1='2' @p2=NULL (DbType = Int32) @p3='NewEntity' (Size = 9) @@ -2187,15 +2185,15 @@ public override async Task Add_and_update_nested_optional_owned_collection_to_JS INSERT INTO "JsonEntitiesBasic" ("OwnedReferenceRoot", "Id", "EntityBasicId", "Name") VALUES (@p0, @p1, @p2, @p3); """, - // - """ + // + """ SELECT "j"."Id", "j"."EntityBasicId", "j"."Name", "j"."OwnedCollectionRoot", "j"."OwnedReferenceRoot" FROM "JsonEntitiesBasic" AS "j" WHERE "j"."Id" = 2 LIMIT 2 """, - // - """ + // + """ @p0=NULL (Nullable = false) @p1='2' @@ -2203,8 +2201,8 @@ LIMIT 2 WHERE "Id" = @p1 RETURNING 1; """, - // - """ + // + """ SELECT "j"."Id", "j"."EntityBasicId", "j"."Name", "j"."OwnedCollectionRoot", "j"."OwnedReferenceRoot" FROM "JsonEntitiesBasic" AS "j" WHERE "j"."Id" = 2 @@ -2213,8 +2211,8 @@ LIMIT 2 break; case false: AssertSql( - """ -@p0='{"Name":null,"Names":null,"Number":0,"Numbers":null,"OwnedCollectionBranch":[],"OwnedReferenceBranch":null}' (Nullable = false) (Size = 107) + """ +@p0='{"Id":0,"Name":null,"Names":null,"Number":0,"Numbers":null,"OwnedCollectionBranch":[],"OwnedReferenceBranch":null}' (Nullable = false) (Size = 114) @p1='2' @p2=NULL (DbType = Int32) @p3='NewEntity' (Size = 9) @@ -2222,24 +2220,24 @@ LIMIT 2 INSERT INTO "JsonEntitiesBasic" ("OwnedReferenceRoot", "Id", "EntityBasicId", "Name") VALUES (@p0, @p1, @p2, @p3); """, - // - """ + // + """ SELECT "j"."Id", "j"."EntityBasicId", "j"."Name", "j"."OwnedCollectionRoot", "j"."OwnedReferenceRoot" FROM "JsonEntitiesBasic" AS "j" WHERE "j"."Id" = 2 LIMIT 2 """, - // - """ -@p0='[{"Date":"0001-01-01 00:00:00","Enum":0,"Enums":null,"Fraction":"0.0","NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":null,"OwnedReferenceLeaf":null}]' (Nullable = false) (Size = 165) + // + """ +@p0='[{"Date":"0001-01-01 00:00:00","Enum":0,"Enums":null,"Fraction":"0.0","Id":0,"NullableEnum":null,"NullableEnums":null,"OwnedCollectionLeaf":null,"OwnedReferenceLeaf":null}]' (Nullable = false) (Size = 172) @p1='2' UPDATE "JsonEntitiesBasic" SET "OwnedReferenceRoot" = json_set("OwnedReferenceRoot", '$.OwnedCollectionBranch', json(@p0)) WHERE "Id" = @p1 RETURNING 1; """, - // - """ + // + """ SELECT "j"."Id", "j"."EntityBasicId", "j"."Name", "j"."OwnedCollectionRoot", "j"."OwnedReferenceRoot" FROM "JsonEntitiesBasic" AS "j" WHERE "j"."Id" = 2 @@ -2248,8 +2246,8 @@ LIMIT 2 break; default: AssertSql( - """ -@p0='{"Name":null,"Names":null,"Number":0,"Numbers":null,"OwnedCollectionBranch":null,"OwnedReferenceBranch":null}' (Nullable = false) (Size = 109) + """ +@p0='{"Id":0,"Name":null,"Names":null,"Number":0,"Numbers":null,"OwnedCollectionBranch":null,"OwnedReferenceBranch":null}' (Nullable = false) (Size = 116) @p1='2' @p2=NULL (DbType = Int32) @p3='NewEntity' (Size = 9) @@ -2257,24 +2255,24 @@ LIMIT 2 INSERT INTO "JsonEntitiesBasic" ("OwnedReferenceRoot", "Id", "EntityBasicId", "Name") VALUES (@p0, @p1, @p2, @p3); """, - // - """ + // + """ SELECT "j"."Id", "j"."EntityBasicId", "j"."Name", "j"."OwnedCollectionRoot", "j"."OwnedReferenceRoot" FROM "JsonEntitiesBasic" AS "j" WHERE "j"."Id" = 2 LIMIT 2 """, - // - """ -@p0='{"Name":null,"Names":null,"Number":0,"Numbers":null,"OwnedCollectionBranch":[],"OwnedReferenceBranch":null}' (Nullable = false) (Size = 107) + // + """ +@p0='{"Id":0,"Name":null,"Names":null,"Number":0,"Numbers":null,"OwnedCollectionBranch":[],"OwnedReferenceBranch":null}' (Nullable = false) (Size = 114) @p1='2' UPDATE "JsonEntitiesBasic" SET "OwnedReferenceRoot" = @p0 WHERE "Id" = @p1 RETURNING 1; """, - // - """ + // + """ SELECT "j"."Id", "j"."EntityBasicId", "j"."Name", "j"."OwnedCollectionRoot", "j"."OwnedReferenceRoot" FROM "JsonEntitiesBasic" AS "j" WHERE "j"."Id" = 2 @@ -2288,21 +2286,21 @@ public override async Task Add_and_update_nested_optional_primitive_collection(b { await base.Add_and_update_nested_optional_primitive_collection(value); - string characterCollection = value switch + var characterCollection = value switch { true => "[\"A\"]", false => "[]", _ => "null" }; - string parameterSize = value switch + var parameterSize = value switch { true => "1562", false => "1559", _ => "1561" }; - string updateParameter = value switch + var updateParameter = value switch { true => "NULL (Nullable = false)", false => "'[\"Z\"]' (Nullable = false) (Size = 5)", @@ -2310,7 +2308,11 @@ public override async Task Add_and_update_nested_optional_primitive_collection(b }; AssertSql( - @"@p0='[{""TestBoolean"":false,""TestBooleanCollection"":[],""TestByte"":0,""TestByteArray"":null,""TestByteCollection"":null,""TestCharacter"":""\u0000"",""TestCharacterCollection"":" + characterCollection + @",""TestDateOnly"":""0001-01-01"",""TestDateOnlyCollection"":[],""TestDateTime"":""0001-01-01 00:00:00"",""TestDateTimeCollection"":[],""TestDateTimeOffset"":""0001-01-01 00:00:00+00:00"",""TestDateTimeOffsetCollection"":[],""TestDecimal"":""0.0"",""TestDecimalCollection"":[],""TestDefaultString"":null,""TestDefaultStringCollection"":[],""TestDouble"":0,""TestDoubleCollection"":[],""TestEnum"":0,""TestEnumCollection"":[],""TestEnumWithIntConverter"":0,""TestEnumWithIntConverterCollection"":[],""TestGuid"":""00000000-0000-0000-0000-000000000000"",""TestGuidCollection"":[],""TestInt16"":0,""TestInt16Collection"":[],""TestInt32"":0,""TestInt32Collection"":[],""TestInt64"":0,""TestInt64Collection"":[],""TestMaxLengthString"":null,""TestMaxLengthStringCollection"":[],""TestNullableEnum"":null,""TestNullableEnumCollection"":[],""TestNullableEnumWithConverterThatHandlesNulls"":null,""TestNullableEnumWithConverterThatHandlesNullsCollection"":[],""TestNullableEnumWithIntConverter"":null,""TestNullableEnumWithIntConverterCollection"":[],""TestNullableInt32"":null,""TestNullableInt32Collection"":[],""TestSignedByte"":0,""TestSignedByteCollection"":[],""TestSingle"":0,""TestSingleCollection"":[],""TestTimeOnly"":""00:00:00.0000000"",""TestTimeOnlyCollection"":[],""TestTimeSpan"":""0:00:00"",""TestTimeSpanCollection"":[],""TestUnsignedInt16"":0,""TestUnsignedInt16Collection"":[],""TestUnsignedInt32"":0,""TestUnsignedInt32Collection"":[],""TestUnsignedInt64"":0,""TestUnsignedInt64Collection"":[]}]' (Nullable = false) (Size = " + parameterSize + @") + @"@p0='[{""TestBoolean"":false,""TestBooleanCollection"":[],""TestByte"":0,""TestByteArray"":null,""TestByteCollection"":null,""TestCharacter"":""\u0000"",""TestCharacterCollection"":" + + characterCollection + + @",""TestDateOnly"":""0001-01-01"",""TestDateOnlyCollection"":[],""TestDateTime"":""0001-01-01 00:00:00"",""TestDateTimeCollection"":[],""TestDateTimeOffset"":""0001-01-01 00:00:00+00:00"",""TestDateTimeOffsetCollection"":[],""TestDecimal"":""0.0"",""TestDecimalCollection"":[],""TestDefaultString"":null,""TestDefaultStringCollection"":[],""TestDouble"":0,""TestDoubleCollection"":[],""TestEnum"":0,""TestEnumCollection"":[],""TestEnumWithIntConverter"":0,""TestEnumWithIntConverterCollection"":[],""TestGuid"":""00000000-0000-0000-0000-000000000000"",""TestGuidCollection"":[],""TestInt16"":0,""TestInt16Collection"":[],""TestInt32"":0,""TestInt32Collection"":[],""TestInt64"":0,""TestInt64Collection"":[],""TestMaxLengthString"":null,""TestMaxLengthStringCollection"":[],""TestNullableEnum"":null,""TestNullableEnumCollection"":[],""TestNullableEnumWithConverterThatHandlesNulls"":null,""TestNullableEnumWithConverterThatHandlesNullsCollection"":[],""TestNullableEnumWithIntConverter"":null,""TestNullableEnumWithIntConverterCollection"":[],""TestNullableInt32"":null,""TestNullableInt32Collection"":[],""TestSignedByte"":0,""TestSignedByteCollection"":[],""TestSingle"":0,""TestSingleCollection"":[],""TestTimeOnly"":""00:00:00.0000000"",""TestTimeOnlyCollection"":[],""TestTimeSpan"":""0:00:00"",""TestTimeSpanCollection"":[],""TestUnsignedInt16"":0,""TestUnsignedInt16Collection"":[],""TestUnsignedInt32"":0,""TestUnsignedInt32Collection"":[],""TestUnsignedInt64"":0,""TestUnsignedInt64Collection"":[]}]' (Nullable = false) (Size = " + + parameterSize + + @") @p1='7624' @p2='[]' (Size = 2) @p3=NULL (DbType = Binary) @@ -2340,15 +2342,17 @@ public override async Task Add_and_update_nested_optional_primitive_collection(b INSERT INTO ""JsonEntitiesAllTypes"" (""Collection"", ""Id"", ""TestBooleanCollection"", ""TestByteCollection"", ""TestCharacterCollection"", ""TestDateTimeCollection"", ""TestDateTimeOffsetCollection"", ""TestDecimalCollection"", ""TestDefaultStringCollection"", ""TestDoubleCollection"", ""TestEnumCollection"", ""TestEnumWithIntConverterCollection"", ""TestGuidCollection"", ""TestInt16Collection"", ""TestInt32Collection"", ""TestInt64Collection"", ""TestMaxLengthStringCollection"", ""TestNullableEnumCollection"", ""TestNullableEnumWithConverterThatHandlesNullsCollection"", ""TestNullableEnumWithIntConverterCollection"", ""TestNullableInt32Collection"", ""TestSignedByteCollection"", ""TestSingleCollection"", ""TestTimeSpanCollection"", ""TestUnsignedInt16Collection"", ""TestUnsignedInt32Collection"", ""TestUnsignedInt64Collection"") VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10, @p11, @p12, @p13, @p14, @p15, @p16, @p17, @p18, @p19, @p20, @p21, @p22, @p23, @p24, @p25, @p26);", - // - """ + // + """ SELECT "j"."Id", "j"."TestBooleanCollection", "j"."TestByteCollection", "j"."TestCharacterCollection", "j"."TestDateTimeCollection", "j"."TestDateTimeOffsetCollection", "j"."TestDecimalCollection", "j"."TestDefaultStringCollection", "j"."TestDoubleCollection", "j"."TestEnumCollection", "j"."TestEnumWithIntConverterCollection", "j"."TestGuidCollection", "j"."TestInt16Collection", "j"."TestInt32Collection", "j"."TestInt64Collection", "j"."TestMaxLengthStringCollection", "j"."TestNullableEnumCollection", "j"."TestNullableEnumWithConverterThatHandlesNullsCollection", "j"."TestNullableEnumWithIntConverterCollection", "j"."TestNullableInt32Collection", "j"."TestSignedByteCollection", "j"."TestSingleCollection", "j"."TestTimeSpanCollection", "j"."TestUnsignedInt16Collection", "j"."TestUnsignedInt32Collection", "j"."TestUnsignedInt64Collection", "j"."Collection", "j"."Reference" FROM "JsonEntitiesAllTypes" AS "j" WHERE "j"."Id" = 7624 LIMIT 2 """, // - "@p0=" + updateParameter + @" + "@p0=" + + updateParameter + + @" @p1='7624' UPDATE ""JsonEntitiesAllTypes"" SET ""Collection"" = json_set(""Collection"", '$[0].TestCharacterCollection', json(@p0)) @@ -2389,7 +2393,8 @@ public override Task Edit_single_property_collection_of_collection_of_nullable_e // Nested collections are not mapped in the relational model, so there is no data stored in the document for them public override Task Edit_single_property_collection_of_collection_of_nullable_enum_with_int_converter() - => Assert.ThrowsAsync(base.Edit_single_property_collection_of_collection_of_nullable_enum_with_int_converter); + => Assert.ThrowsAsync( + base.Edit_single_property_collection_of_collection_of_nullable_enum_with_int_converter); // Nested collections are not mapped in the relational model, so there is no data stored in the document for them public override Task Edit_single_property_collection_of_collection_of_nullable_int32() diff --git a/test/EFCore.Sqlite.FunctionalTests/WithConstructorsSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/WithConstructorsSqliteTest.cs index 3be239ea841..729174e71e3 100644 --- a/test/EFCore.Sqlite.FunctionalTests/WithConstructorsSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/WithConstructorsSqliteTest.cs @@ -5,7 +5,8 @@ namespace Microsoft.EntityFrameworkCore; #nullable disable -public class WithConstructorsSqliteTest(WithConstructorsSqliteTest.WithConstructorsSqliteFixture fixture) : WithConstructorsTestBase(fixture) +public class WithConstructorsSqliteTest(WithConstructorsSqliteTest.WithConstructorsSqliteFixture fixture) + : WithConstructorsTestBase(fixture) { protected override void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction) => facade.UseTransaction(transaction.GetDbTransaction()); diff --git a/test/EFCore.Sqlite.Tests/Metadata/Builders/SqliteMetadataBuilderExtensionsTest.cs b/test/EFCore.Sqlite.Tests/Metadata/Builders/SqliteMetadataBuilderExtensionsTest.cs new file mode 100644 index 00000000000..48cb541c748 --- /dev/null +++ b/test/EFCore.Sqlite.Tests/Metadata/Builders/SqliteMetadataBuilderExtensionsTest.cs @@ -0,0 +1,58 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.EntityFrameworkCore.Metadata.Internal; + +namespace Microsoft.EntityFrameworkCore.Metadata.Builders; + +public class SqliteMetadataBuilderExtensionsTest +{ + private IConventionModelBuilder CreateBuilder() + => new InternalModelBuilder(new Model()); + + [ConditionalFact] + public void Can_change_entity_type_UseSqlReturningClause() + { + var typeBuilder = CreateBuilder().Entity(typeof(Splot))!; + + Assert.Null(typeBuilder.Metadata.GetUseSqlReturningClauseConfigurationSource()); + + Assert.NotNull(typeBuilder.UseSqlReturningClause(true)); + Assert.True(typeBuilder.Metadata.IsSqlReturningClauseUsed()); + Assert.Equal(ConfigurationSource.Convention, typeBuilder.Metadata.GetUseSqlReturningClauseConfigurationSource()); + + Assert.NotNull(typeBuilder.UseSqlReturningClause(false, fromDataAnnotation: true)); + Assert.False(typeBuilder.Metadata.IsSqlReturningClauseUsed()); + Assert.Equal(ConfigurationSource.DataAnnotation, typeBuilder.Metadata.GetUseSqlReturningClauseConfigurationSource()); + + Assert.Null(typeBuilder.UseSqlReturningClause(true)); + Assert.False(typeBuilder.Metadata.IsSqlReturningClauseUsed()); + Assert.NotNull(typeBuilder.UseSqlReturningClause(false)); + + Assert.NotNull(typeBuilder.UseSqlReturningClause(null, fromDataAnnotation: true)); + Assert.True(typeBuilder.Metadata.IsSqlReturningClauseUsed()); + Assert.Null(typeBuilder.Metadata.GetUseSqlReturningClauseConfigurationSource()); + + var fragmentId = StoreObjectIdentifier.Table("Split"); + + Assert.Null(typeBuilder.Metadata.GetUseSqlReturningClauseConfigurationSource(fragmentId)); + + Assert.NotNull(typeBuilder.UseSqlReturningClause(true, fragmentId)); + Assert.True(typeBuilder.Metadata.IsSqlReturningClauseUsed(fragmentId)); + Assert.Equal(ConfigurationSource.Convention, typeBuilder.Metadata.GetUseSqlReturningClauseConfigurationSource(fragmentId)); + + Assert.NotNull(typeBuilder.UseSqlReturningClause(false, fragmentId, fromDataAnnotation: true)); + Assert.False(typeBuilder.Metadata.IsSqlReturningClauseUsed(fragmentId)); + Assert.Equal(ConfigurationSource.DataAnnotation, typeBuilder.Metadata.GetUseSqlReturningClauseConfigurationSource(fragmentId)); + + Assert.Null(typeBuilder.UseSqlReturningClause(true, fragmentId)); + Assert.False(typeBuilder.Metadata.IsSqlReturningClauseUsed(fragmentId)); + Assert.NotNull(typeBuilder.UseSqlReturningClause(false, fragmentId)); + + Assert.NotNull(typeBuilder.UseSqlReturningClause(null, fragmentId, fromDataAnnotation: true)); + Assert.True(typeBuilder.Metadata.IsSqlReturningClauseUsed(fragmentId)); + Assert.Null(typeBuilder.Metadata.GetUseSqlReturningClauseConfigurationSource(fragmentId)); + } + + private class Splot; +} diff --git a/test/EFCore.Sqlite.Tests/SqliteNTSApiConsistencyTest.cs b/test/EFCore.Sqlite.Tests/SqliteNTSApiConsistencyTest.cs index 807866f348c..2cf497d9c1b 100644 --- a/test/EFCore.Sqlite.Tests/SqliteNTSApiConsistencyTest.cs +++ b/test/EFCore.Sqlite.Tests/SqliteNTSApiConsistencyTest.cs @@ -3,7 +3,8 @@ namespace Microsoft.EntityFrameworkCore; -public class SqliteNTSApiConsistencyTest(SqliteNTSApiConsistencyTest.SqliteNTSApiConsistencyFixture fixture) : ApiConsistencyTestBase(fixture) +public class SqliteNTSApiConsistencyTest(SqliteNTSApiConsistencyTest.SqliteNTSApiConsistencyFixture fixture) + : ApiConsistencyTestBase(fixture) { protected override void AddServices(ServiceCollection serviceCollection) => serviceCollection.AddEntityFrameworkSqliteNetTopologySuite(); diff --git a/test/EFCore.Sqlite.Tests/Storage/SqliteTypeMappingTest.cs b/test/EFCore.Sqlite.Tests/Storage/SqliteTypeMappingTest.cs index 9a3c39e603f..f51b7d0733e 100644 --- a/test/EFCore.Sqlite.Tests/Storage/SqliteTypeMappingTest.cs +++ b/test/EFCore.Sqlite.Tests/Storage/SqliteTypeMappingTest.cs @@ -18,6 +18,7 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder.UseSqlite(_connection); // ReSharper disable once UnusedAutoPropertyAccessor.Local + // ReSharper disable once AutoPropertyCanBeMadeGetOnly.Local public DbSet NoTinnies { get; set; } = null!; } diff --git a/test/EFCore.Tests/ApiConsistencyTest.cs b/test/EFCore.Tests/ApiConsistencyTest.cs index 64752929022..c01f993d370 100644 --- a/test/EFCore.Tests/ApiConsistencyTest.cs +++ b/test/EFCore.Tests/ApiConsistencyTest.cs @@ -9,7 +9,8 @@ // ReSharper disable InconsistentNaming namespace Microsoft.EntityFrameworkCore; -public class ApiConsistencyTest(ApiConsistencyTest.ApiConsistencyFixture fixture) : ApiConsistencyTestBase(fixture) +public class ApiConsistencyTest(ApiConsistencyTest.ApiConsistencyFixture fixture) + : ApiConsistencyTestBase(fixture) { protected override Assembly TargetAssembly => typeof(EntityType).Assembly; diff --git a/test/EFCore.Tests/ChangeTracking/ChangeTrackerTest.cs b/test/EFCore.Tests/ChangeTracking/ChangeTrackerTest.cs index d5ae09f75f8..72b524727d2 100644 --- a/test/EFCore.Tests/ChangeTracking/ChangeTrackerTest.cs +++ b/test/EFCore.Tests/ChangeTracking/ChangeTrackerTest.cs @@ -4,7 +4,6 @@ #nullable enable using Microsoft.EntityFrameworkCore.Diagnostics.Internal; -using Microsoft.EntityFrameworkCore.InMemory.ValueGeneration.Internal; // ReSharper disable ClassNeverInstantiated.Local // ReSharper disable ParameterOnlyUsedForPreconditionCheck.Local @@ -507,7 +506,12 @@ public void Detect_property_change_is_logged(bool sensitive, bool callDetectChan [InlineData(true, true)] public void Detect_nested_property_change_is_logged(bool sensitive, bool callDetectChangesTwice) { - var wocket = new Wocket { Id = 1, Name = "Gollum", Pocket = new() { Contents = "Handsies" } }; + var wocket = new Wocket + { + Id = 1, + Name = "Gollum", + Pocket = new Pocket { Contents = "Handsies" } + }; using var context = sensitive ? new LikeAZooContextSensitive() : new LikeAZooContext(); context.Database.EnsureDeleted(); @@ -2206,7 +2210,6 @@ private class Cat(int id) private class Hat(int id) { - // ReSharper disable once AutoPropertyCanBeMadeGetOnly.Local public int Id { get; private set; } = id; @@ -2218,7 +2221,6 @@ private class Hat(int id) private class Mat(int id) { - // ReSharper disable once AutoPropertyCanBeMadeGetOnly.Local public int Id { get; private set; } = id; diff --git a/test/EFCore.Tests/ChangeTracking/ComplexPropertyEntryTest.cs b/test/EFCore.Tests/ChangeTracking/ComplexPropertyEntryTest.cs index 3dc53c49206..ff727c7a983 100644 --- a/test/EFCore.Tests/ChangeTracking/ComplexPropertyEntryTest.cs +++ b/test/EFCore.Tests/ChangeTracking/ComplexPropertyEntryTest.cs @@ -475,11 +475,13 @@ protected internal override void OnModelCreating(ModelBuilder modelBuilder) private struct Culture { public string Species { get; set; } + // ReSharper disable once UnusedAutoPropertyAccessor.Local public string? Subspecies { get; set; } public int Rating { get; set; } + // ReSharper disable once UnusedAutoPropertyAccessor.Local - public bool? Validation { get; set; } + public bool? Validation { get; set; } public Manufacturer Manufacturer { get; set; } public License License { get; set; } } diff --git a/test/EFCore.Tests/ChangeTracking/Internal/ChangeDetectorTest.cs b/test/EFCore.Tests/ChangeTracking/Internal/ChangeDetectorTest.cs index 4e6cfb5142a..c198ca80ef2 100644 --- a/test/EFCore.Tests/ChangeTracking/Internal/ChangeDetectorTest.cs +++ b/test/EFCore.Tests/ChangeTracking/Internal/ChangeDetectorTest.cs @@ -2131,8 +2131,8 @@ public override void AttachGraph( } private class TestRelationshipListener(IEntityGraphAttacher attacher) : NavigationFixer( - attacher, new EntityMaterializerSource( - new EntityMaterializerSourceDependencies(Enumerable.Empty()))) + attacher, new EntityMaterializerSource( + new EntityMaterializerSourceDependencies(Enumerable.Empty()))) { public Tuple, IEnumerable, object, object> KeyChange { diff --git a/test/EFCore.Tests/ChangeTracking/Internal/CurrentValueComparerTest.cs b/test/EFCore.Tests/ChangeTracking/Internal/CurrentValueComparerTest.cs index 4126d2d8214..6b4517b3e8d 100644 --- a/test/EFCore.Tests/ChangeTracking/Internal/CurrentValueComparerTest.cs +++ b/test/EFCore.Tests/ChangeTracking/Internal/CurrentValueComparerTest.cs @@ -177,17 +177,7 @@ private void CanSort( .ToList(); Assert.Equal( - new byte[][] - { - [], - [], - [7], - [9], - [9], - [1, 1], - [3, 3], - [3, 3, 3] - }, + new byte[][] { [], [], [7], [9], [9], [1, 1], [3, 3], [3, 3, 3] }, entries); } @@ -350,17 +340,7 @@ private void CanSortNullable( .ToList(); Assert.Equal( - new[] - { - null, - null, - [7], - [9], - [9], - [1, 1], - [3, 3], - new byte[] { 3, 3, 3 } - }, + new[] { null, null, [7], [9], [9], [1, 1], [3, 3], new byte[] { 3, 3, 3 } }, entries); } diff --git a/test/EFCore.Tests/ChangeTracking/Internal/FixupCompositeTest.cs b/test/EFCore.Tests/ChangeTracking/Internal/FixupCompositeTest.cs index 6368d5aca7a..e3721a3620d 100644 --- a/test/EFCore.Tests/ChangeTracking/Internal/FixupCompositeTest.cs +++ b/test/EFCore.Tests/ChangeTracking/Internal/FixupCompositeTest.cs @@ -3603,10 +3603,8 @@ public class ChildShared private class FixupContext : DbContext { public FixupContext() - { // ReSharper disable once VirtualMemberCallInConstructor - ChangeTracker.AutoDetectChangesEnabled = false; - } + => ChangeTracker.AutoDetectChangesEnabled = false; protected internal override void OnModelCreating(ModelBuilder modelBuilder) { diff --git a/test/EFCore.Tests/ChangeTracking/Internal/FixupTest.cs b/test/EFCore.Tests/ChangeTracking/Internal/FixupTest.cs index 873088cb00e..6cc981b6dc8 100644 --- a/test/EFCore.Tests/ChangeTracking/Internal/FixupTest.cs +++ b/test/EFCore.Tests/ChangeTracking/Internal/FixupTest.cs @@ -3481,9 +3481,7 @@ public Category() } public Category(int id) - { - _id = id; - } + => _id = id; public string Value1 { get; set; } public string Value2 { get; set; } diff --git a/test/EFCore.Tests/ChangeTracking/Internal/OwnedFixupTest.cs b/test/EFCore.Tests/ChangeTracking/Internal/OwnedFixupTest.cs index 26343a61b37..c44d8fb14dd 100644 --- a/test/EFCore.Tests/ChangeTracking/Internal/OwnedFixupTest.cs +++ b/test/EFCore.Tests/ChangeTracking/Internal/OwnedFixupTest.cs @@ -36,7 +36,7 @@ public void Detaching_owner_does_not_delete_owned_entities(bool delayCascade) var thing = new Thing { ThingId = Guid.NewGuid(), - OwnedByThings = [new() { OwnedByThingId = Guid.NewGuid() }, new() { OwnedByThingId = Guid.NewGuid() }] + OwnedByThings = [new OwnedByThing { OwnedByThingId = Guid.NewGuid() }, new OwnedByThing { OwnedByThingId = Guid.NewGuid() }] }; context.Attach(thing); diff --git a/test/EFCore.Tests/ChangeTracking/Internal/QueryFixupTest.cs b/test/EFCore.Tests/ChangeTracking/Internal/QueryFixupTest.cs index 2a973154f3d..03c2e795e96 100644 --- a/test/EFCore.Tests/ChangeTracking/Internal/QueryFixupTest.cs +++ b/test/EFCore.Tests/ChangeTracking/Internal/QueryFixupTest.cs @@ -1157,9 +1157,7 @@ public class SmidgetDN private class QueryFixupContext : DbContext { public QueryFixupContext() - { - ChangeTracker.AutoDetectChangesEnabled = false; - } + => ChangeTracker.AutoDetectChangesEnabled = false; protected internal override void OnModelCreating(ModelBuilder modelBuilder) { diff --git a/test/EFCore.Tests/ChangeTracking/Internal/ShadowFixupTest.cs b/test/EFCore.Tests/ChangeTracking/Internal/ShadowFixupTest.cs index 5b4fc7aa43d..8003244e3af 100644 --- a/test/EFCore.Tests/ChangeTracking/Internal/ShadowFixupTest.cs +++ b/test/EFCore.Tests/ChangeTracking/Internal/ShadowFixupTest.cs @@ -243,9 +243,7 @@ public Category() } public Category(int id) - { - Id = id; - } + => Id = id; public int Id { get; set; } } @@ -257,9 +255,7 @@ public Product() } public Product(int id) - { - Id = id; - } + => Id = id; public int Id { get; set; } } @@ -267,9 +263,7 @@ public Product(int id) private sealed class FixupContext : DbContext { public FixupContext() - { - ChangeTracker.AutoDetectChangesEnabled = false; - } + => ChangeTracker.AutoDetectChangesEnabled = false; protected internal override void OnModelCreating(ModelBuilder modelBuilder) { diff --git a/test/EFCore.Tests/ChangeTracking/Internal/ShadowFkFixupTest.cs b/test/EFCore.Tests/ChangeTracking/Internal/ShadowFkFixupTest.cs index 64565b33be0..51decdf383f 100644 --- a/test/EFCore.Tests/ChangeTracking/Internal/ShadowFkFixupTest.cs +++ b/test/EFCore.Tests/ChangeTracking/Internal/ShadowFkFixupTest.cs @@ -1583,10 +1583,8 @@ private class SpecialOffer private class FixupContext : DbContext { public FixupContext() - { // ReSharper disable once VirtualMemberCallInConstructor - ChangeTracker.AutoDetectChangesEnabled = false; - } + => ChangeTracker.AutoDetectChangesEnabled = false; protected internal override void OnModelCreating(ModelBuilder modelBuilder) { diff --git a/test/EFCore.Tests/ChangeTracking/NavigationEntryTest.cs b/test/EFCore.Tests/ChangeTracking/NavigationEntryTest.cs index f6523df24d7..072e08cfd9a 100644 --- a/test/EFCore.Tests/ChangeTracking/NavigationEntryTest.cs +++ b/test/EFCore.Tests/ChangeTracking/NavigationEntryTest.cs @@ -168,6 +168,7 @@ private class Chunky private class Cherry { public int Garcia { get; set; } + // ReSharper disable once UnusedAutoPropertyAccessor.Local public int Id { get; set; } diff --git a/test/EFCore.Tests/ChangeTracking/PropertyEntryTest.cs b/test/EFCore.Tests/ChangeTracking/PropertyEntryTest.cs index 9deb211b505..2cc539bea61 100644 --- a/test/EFCore.Tests/ChangeTracking/PropertyEntryTest.cs +++ b/test/EFCore.Tests/ChangeTracking/PropertyEntryTest.cs @@ -4782,7 +4782,8 @@ protected internal override void OnModelCreating(ModelBuilder modelBuilder) }); } - private class PrimateContext(ChangeTrackingStrategy fullNotificationStrategy = ChangeTrackingStrategy.ChangingAndChangedNotifications) : DbContext + private class PrimateContext(ChangeTrackingStrategy fullNotificationStrategy = ChangeTrackingStrategy.ChangingAndChangedNotifications) + : DbContext { private readonly ChangeTrackingStrategy _fullNotificationStrategy = fullNotificationStrategy; diff --git a/test/EFCore.Tests/ChangeTracking/TrackGraphTestBase.cs b/test/EFCore.Tests/ChangeTracking/TrackGraphTestBase.cs index 28a51fb869a..64d8c21d0c7 100644 --- a/test/EFCore.Tests/ChangeTracking/TrackGraphTestBase.cs +++ b/test/EFCore.Tests/ChangeTracking/TrackGraphTestBase.cs @@ -35,19 +35,19 @@ public async Task Can_iterate_over_graph_using_public_surface(bool async) Id = 1, Products = [ - new() + new Product { Id = 1, CategoryId = 1, Details = new ProductDetails { Id = 1 } }, - new() + new Product { Id = 2, CategoryId = 1, Details = new ProductDetails { Id = 2 } }, - new() + new Product { Id = 3, CategoryId = 1, @@ -164,9 +164,9 @@ public void Can_attach_nullable_PK_parent_with_child_collection(bool useAttach, { Products = [ - new(), - new(), - new() + new NullbileProduct(), + new NullbileProduct(), + new NullbileProduct() ] }; @@ -413,9 +413,9 @@ public void Can_attach_parent_with_child_collection() Id = 1, Products = [ - new() { Id = 1 }, - new() { Id = 2 }, - new() { Id = 3 } + new Product { Id = 1 }, + new Product { Id = 2 }, + new Product { Id = 3 } ] }; @@ -581,9 +581,9 @@ public void Entities_that_are_already_tracked_will_not_get_attached() Id = 1, Products = [ - new() { Id = 1 }, + new Product { Id = 1 }, existingProduct, - new() { Id = 3 } + new Product { Id = 3 } ] }; @@ -626,19 +626,19 @@ public void Further_graph_traversal_stops_if_an_entity_is_not_attached() Id = 1, Products = [ - new() + new Product { Id = 1, CategoryId = 1, Details = new ProductDetails { Id = 1 } }, - new() + new Product { Id = 2, CategoryId = 1, Details = new ProductDetails { Id = 2 } }, - new() + new Product { Id = 3, CategoryId = 1, @@ -795,9 +795,9 @@ public void Dependents_are_detached_not_deleted_when_principal_is_detached(bool Id = 1, Products = [ - new() { Id = 1 }, - new() { Id = 2 }, - new() { Id = 3 } + new Product { Id = 1 }, + new Product { Id = 2 }, + new Product { Id = 3 } ] }; @@ -845,9 +845,9 @@ public void Dependents_are_detached_not_deleted_when_principal_is_detached(bool { newCategory.Products = [ - new() { Id = 1 }, - new() { Id = 2 }, - new() { Id = 3 } + new Product { Id = 1 }, + new Product { Id = 2 }, + new Product { Id = 3 } ]; } @@ -940,19 +940,19 @@ public void TrackGraph_overload_can_visit_a_graph_without_attaching() Id = 1, Products = [ - new() + new Product { Id = 1, CategoryId = 1, Details = new ProductDetails { Id = 1 } }, - new() + new Product { Id = 2, CategoryId = 1, Details = new ProductDetails { Id = 2 } }, - new() + new Product { Id = 3, CategoryId = 1, @@ -1056,9 +1056,9 @@ private static void KeyValueAttachTest(string databaseName, Action( LambdaExpression equalsExpression, LambdaExpression hashCodeExpression, LambdaExpression snapshotExpression) : ValueComparer( - (Expression>)equalsExpression, - (Expression>)hashCodeExpression, - (Expression>)snapshotExpression); + (Expression>)equalsExpression, + (Expression>)hashCodeExpression, + (Expression>)snapshotExpression); private enum JustAnEnum : ushort { diff --git a/test/EFCore.Tests/CollectionComparerTest.cs b/test/EFCore.Tests/CollectionComparerTest.cs index 00ba675298f..ca3e509fa97 100644 --- a/test/EFCore.Tests/CollectionComparerTest.cs +++ b/test/EFCore.Tests/CollectionComparerTest.cs @@ -21,10 +21,10 @@ public void Can_detect_changes_to_primitive_collections_using_arrays() ArrayNullableInt = [0, null, 2], ArrayString = ["0", "1", "2"], ArrayNullableString = ["0", null, "2"], - ArrayStruct = [new("0"), new("1"), new("2")], - ArrayNullableStruct = [new("0"), null, new("2")], - ArrayClass = [new("0"), new("1"), new("2")], - ArrayNullableClass = [new("0"), null, new("2")], + ArrayStruct = [new MyStruct("0"), new MyStruct("1"), new MyStruct("2")], + ArrayNullableStruct = [new MyStruct("0"), null, new MyStruct("2")], + ArrayClass = [new MyClass("0"), new MyClass("1"), new MyClass("2")], + ArrayNullableClass = [new MyClass("0"), null, new MyClass("2")], EnumerableInt = new[] { 0, 1, 2 }, EnumerableNullableInt = new int?[] { 0, null, 2 }, EnumerableString = new[] { "0", "1", "2" }, diff --git a/test/EFCore.Tests/DbContextFactoryTest.cs b/test/EFCore.Tests/DbContextFactoryTest.cs index b1c709bff90..e620b82d4b8 100644 --- a/test/EFCore.Tests/DbContextFactoryTest.cs +++ b/test/EFCore.Tests/DbContextFactoryTest.cs @@ -3,7 +3,6 @@ using Microsoft.EntityFrameworkCore.InMemory.Infrastructure.Internal; using Microsoft.EntityFrameworkCore.Internal; -using static System.Formats.Asn1.AsnWriter; namespace Microsoft.EntityFrameworkCore; @@ -613,7 +612,7 @@ public void Add_factory_and_then_context_using_scope( if (validateScopes && ((factoryLifetime == ServiceLifetime.Scoped - && contextLifetime == ServiceLifetime.Singleton) + && contextLifetime == ServiceLifetime.Singleton) || (factoryLifetime == ServiceLifetime.Singleton && contextLifetime != ServiceLifetime.Singleton && optionsLifetime == ServiceLifetime.Scoped))) @@ -764,9 +763,9 @@ var effectiveOptionsLifetime if (validateScopes && ((factoryLifetime == ServiceLifetime.Singleton - && effectiveOptionsLifetime == ServiceLifetime.Scoped) - || (factoryLifetime == ServiceLifetime.Scoped - && effectiveOptionsLifetime == ServiceLifetime.Singleton))) + && effectiveOptionsLifetime == ServiceLifetime.Scoped) + || (factoryLifetime == ServiceLifetime.Scoped + && effectiveOptionsLifetime == ServiceLifetime.Singleton))) { Assert.Throws(scope.ServiceProvider.GetRequiredService>); } diff --git a/test/EFCore.Tests/DbContextTest.Services.cs b/test/EFCore.Tests/DbContextTest.Services.cs index ccbf61d15f0..96ea3531e75 100644 --- a/test/EFCore.Tests/DbContextTest.Services.cs +++ b/test/EFCore.Tests/DbContextTest.Services.cs @@ -418,7 +418,8 @@ public ApplicationService ApplicationService => _singletonOptions.RootApplicationServiceProvider!.GetService(); } - private class TestScopedService(ICurrentDbContext currentContext, IEntityEntryGraphIterator graphIterator) : EntityGraphAttacher(graphIterator) + private class TestScopedService(ICurrentDbContext currentContext, IEntityEntryGraphIterator graphIterator) + : EntityGraphAttacher(graphIterator) { private readonly ICurrentDbContext _currentContext = currentContext; @@ -426,7 +427,8 @@ public ApplicationService ApplicationService => _currentContext.Context.GetService(); } - private class TestTransientService(ICurrentDbContext currentContext, IDiagnosticsLogger logger) : LazyLoader(currentContext, logger) + private class TestTransientService(ICurrentDbContext currentContext, IDiagnosticsLogger logger) + : LazyLoader(currentContext, logger) { public ApplicationService ApplicationService => Context!.GetService(); @@ -919,15 +921,11 @@ public EarlyLearningCenter() } public EarlyLearningCenter(IServiceProvider serviceProvider) - { - _serviceProvider = serviceProvider; - } + => _serviceProvider = serviceProvider; public EarlyLearningCenter(IServiceProvider serviceProvider, DbContextOptions options) : base(options) - { - _serviceProvider = serviceProvider; - } + => _serviceProvider = serviceProvider; public DbSet Products { get; set; } public DbSet Categories { get; set; } @@ -951,7 +949,8 @@ protected internal override void OnModelCreating(ModelBuilder modelBuilder) } } - private class FakeEntityMaterializerSource(EntityMaterializerSourceDependencies dependencies) : EntityMaterializerSource(dependencies); + private class FakeEntityMaterializerSource(EntityMaterializerSourceDependencies dependencies) + : EntityMaterializerSource(dependencies); private class FakeModelSource : IModelSource { @@ -3042,7 +3041,8 @@ private class CustomInMemoryValueGeneratorSelector( ValueGeneratorSelectorDependencies dependencies, IInMemoryDatabase inMemoryDatabase) : InMemoryValueGeneratorSelector(dependencies, inMemoryDatabase); - private class CustomInMemoryTableFactory(ILoggingOptions loggingOptions, IInMemorySingletonOptions options) : InMemoryTableFactory(loggingOptions, options); + private class CustomInMemoryTableFactory(ILoggingOptions loggingOptions, IInMemorySingletonOptions options) + : InMemoryTableFactory(loggingOptions, options); [ConditionalFact] public void Can_replace_services_in_passed_options() diff --git a/test/EFCore.Tests/DbContextTest.cs b/test/EFCore.Tests/DbContextTest.cs index 556bbb2de26..b5c329c55e5 100644 --- a/test/EFCore.Tests/DbContextTest.cs +++ b/test/EFCore.Tests/DbContextTest.cs @@ -1335,7 +1335,8 @@ public void It_throws_with_derived_name() public class FakeServiceProvider : IServiceProvider, IDisposable { - private readonly IServiceProvider _realProvider = new ServiceCollection().AddEntityFrameworkInMemoryDatabase().BuildServiceProvider(validateScopes: true); + private readonly IServiceProvider _realProvider = + new ServiceCollection().AddEntityFrameworkInMemoryDatabase().BuildServiceProvider(validateScopes: true); public bool Disposed { get; set; } diff --git a/test/EFCore.Tests/DbSetInitializerTest.cs b/test/EFCore.Tests/DbSetInitializerTest.cs index f9d9559f434..c6d21df059d 100644 --- a/test/EFCore.Tests/DbSetInitializerTest.cs +++ b/test/EFCore.Tests/DbSetInitializerTest.cs @@ -46,11 +46,12 @@ public IReadOnlyList FindSets(Type contextType) private class JustAContext(DbContextOptions options) : DbContext(options) { - // ReSharper disable once UnusedAutoPropertyAccessor.Local public DbSet One { get; set; } + // ReSharper disable once UnusedAutoPropertyAccessor.Local private DbSet Two { get; set; } + // ReSharper disable once UnusedAutoPropertyAccessor.Local public DbSet Three { get; private set; } diff --git a/test/EFCore.Tests/Diagnostics/CoreEventIdTest.cs b/test/EFCore.Tests/Diagnostics/CoreEventIdTest.cs index 43e03daa045..0320e663772 100644 --- a/test/EFCore.Tests/Diagnostics/CoreEventIdTest.cs +++ b/test/EFCore.Tests/Diagnostics/CoreEventIdTest.cs @@ -92,7 +92,8 @@ public object GetService(Type serviceType) => null; } - private class FakeNavigationBase(string name, ConfigurationSource configurationSource, EntityType entityType) : PropertyBase(name, null, null, configurationSource), INavigationBase + private class FakeNavigationBase(string name, ConfigurationSource configurationSource, EntityType entityType) + : PropertyBase(name, null, null, configurationSource), INavigationBase { public IEntityType DeclaringEntityType => (IEntityType)DeclaringType; 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.Tests/Extensions/ServiceProviderExtensionsTest.cs b/test/EFCore.Tests/Extensions/ServiceProviderExtensionsTest.cs index 2f5a596f94a..75ec353280a 100644 --- a/test/EFCore.Tests/Extensions/ServiceProviderExtensionsTest.cs +++ b/test/EFCore.Tests/Extensions/ServiceProviderExtensionsTest.cs @@ -106,8 +106,6 @@ private interface IPilkington; private class Karl : IPilkington { public Karl() - { - throw new NotSupportedException(KarlQuote); - } + => throw new NotSupportedException(KarlQuote); } } diff --git a/test/EFCore.Tests/Extensions/TypeExtensionsTest.cs b/test/EFCore.Tests/Extensions/TypeExtensionsTest.cs index d0845414f82..1933f9c6baa 100644 --- a/test/EFCore.Tests/Extensions/TypeExtensionsTest.cs +++ b/test/EFCore.Tests/Extensions/TypeExtensionsTest.cs @@ -5,6 +5,7 @@ using System.Collections; using System.Collections.ObjectModel; + namespace Microsoft.EntityFrameworkCore; public class TypeExtensionsTest @@ -576,19 +577,13 @@ public static TheoryData CreateOpenGenericsTestData() { typeof(Dictionary<,>), false, "Dictionary<,>" }, { typeof(List<>), true, "System.Collections.Generic.List<>" }, { typeof(Dictionary<,>), true, "System.Collections.Generic.Dictionary<,>" }, - { - typeof(Level1<>.Level2<>.Level3<>), true, - "Microsoft.EntityFrameworkCore.TypeExtensionsTest+Level1<>+Level2<>+Level3<>" - }, + { typeof(Level1<>.Level2<>.Level3<>), true, "Microsoft.EntityFrameworkCore.TypeExtensionsTest+Level1<>+Level2<>+Level3<>" }, { typeof(PartiallyClosedGeneric<>).BaseType, true, "Microsoft.EntityFrameworkCore.TypeExtensionsTest+C<, int>" }, { typeof(OuterGeneric<>.InnerNonGeneric.InnerGeneric<,>.InnerGenericLeafNode<>), true, "Microsoft.EntityFrameworkCore.TypeExtensionsTest+OuterGeneric<>+InnerNonGeneric+InnerGeneric<,>+InnerGenericLeafNode<>" }, - { - closedDictionaryType, true, - "System.Collections.Generic.Dictionary,>" - }, + { closedDictionaryType, true, "System.Collections.Generic.Dictionary,>" }, { closedLevelType, true, "Microsoft.EntityFrameworkCore.TypeExtensionsTest+Level1<>+Level2+Level3<>" }, { closedInnerType, true, diff --git a/test/EFCore.Tests/Infrastructure/EntityFrameworkMetricsTest.cs b/test/EFCore.Tests/Infrastructure/EntityFrameworkMetricsTest.cs index 9efee770e7d..310beb19f7c 100644 --- a/test/EFCore.Tests/Infrastructure/EntityFrameworkMetricsTest.cs +++ b/test/EFCore.Tests/Infrastructure/EntityFrameworkMetricsTest.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using Microsoft.EntityFrameworkCore.Infrastructure.Internal; using OpenTelemetry; using OpenTelemetry.Metrics; diff --git a/test/EFCore.Tests/Infrastructure/Internal/ConcurrencyDetectorTest.cs b/test/EFCore.Tests/Infrastructure/Internal/ConcurrencyDetectorTest.cs index d78fdf75a4c..fdf30dcd9c7 100644 --- a/test/EFCore.Tests/Infrastructure/Internal/ConcurrencyDetectorTest.cs +++ b/test/EFCore.Tests/Infrastructure/Internal/ConcurrencyDetectorTest.cs @@ -10,27 +10,20 @@ public void MultipleContextOnSameThread_Should_Success() { var preparingContext = new Context(); - var customer = new Customer - { - FirstName = "John", - LastName = "Doe" - }; + var customer = new Customer { FirstName = "John", LastName = "Doe" }; preparingContext.Customers.Add(customer); preparingContext.SaveChanges(); - var order = new Order - { - CustomerId = customer.CustomerId, - OrderDate = DateTime.Now - }; + var order = new Order { CustomerId = customer.CustomerId, OrderDate = DateTime.Now }; preparingContext.Orders.Add(order); preparingContext.SaveChanges(); - var context = new Context(); + var context = new Context(); - var exception = Record.Exception(() => context.Orders.Select(o => new { Date = o.OrderDate, Name = GetCustomer(o.OrderId, context) }).ToArray()); + var exception = Record.Exception( + () => context.Orders.Select(o => new { Date = o.OrderDate, Name = GetCustomer(o.OrderId, context) }).ToArray()); Assert.Null(exception); } @@ -76,7 +69,9 @@ protected internal override void OnModelCreating(ModelBuilder modelBuilder) .HasForeignKey(o => o.CustomerId); } + // ReSharper disable once UnusedAutoPropertyAccessor.Local public DbSet Customers { get; set; } + // ReSharper disable once UnusedAutoPropertyAccessor.Local public DbSet Orders { get; set; } } @@ -98,9 +93,7 @@ public Order() } public Order(ILazyLoader lazyLoader) - { - _lazyLoader = lazyLoader; - } + => _lazyLoader = lazyLoader; public int OrderId { get; set; } public DateTime OrderDate { get; set; } diff --git a/test/EFCore.Tests/Infrastructure/ModelValidatorTest.cs b/test/EFCore.Tests/Infrastructure/ModelValidatorTest.cs index a791b9d5411..e6ca88c0332 100644 --- a/test/EFCore.Tests/Infrastructure/ModelValidatorTest.cs +++ b/test/EFCore.Tests/Infrastructure/ModelValidatorTest.cs @@ -46,7 +46,7 @@ public virtual void Detects_well_known_concrete_collections_mapped_as_owned_enti { var modelBuilder = CreateConventionModelBuilder(); - modelBuilder.Entity>>().OwnsMany(x => x.JsonbFields, r => r.ToJson());; + modelBuilder.Entity>>().OwnsMany(x => x.JsonbFields, r => r.ToJson()); VerifyError( CoreStrings.WarningAsErrorTemplate( @@ -312,18 +312,43 @@ public virtual void Does_not_throw_for_non_generic_collection() protected class MyCollection : IList { private readonly List _list = []; - public IEnumerator GetEnumerator() => _list.GetEnumerator(); - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public void Add(int item) => _list.Add(item); - public void Clear() => _list.Clear(); - public bool Contains(int item) => _list.Contains(item); - public void CopyTo(int[] array, int arrayIndex) => _list.CopyTo(array, arrayIndex); - public bool Remove(int item) => _list.Remove(item); - public int Count => _list.Count; - public bool IsReadOnly => ((ICollection)_list).IsReadOnly; - public int IndexOf(int item) => _list.IndexOf(item); - public void Insert(int index, int item) => _list.Insert(index, item); - public void RemoveAt(int index) => _list.RemoveAt(index); + + public IEnumerator GetEnumerator() + => _list.GetEnumerator(); + + IEnumerator IEnumerable.GetEnumerator() + => GetEnumerator(); + + public void Add(int item) + => _list.Add(item); + + public void Clear() + => _list.Clear(); + + public bool Contains(int item) + => _list.Contains(item); + + public void CopyTo(int[] array, int arrayIndex) + => _list.CopyTo(array, arrayIndex); + + public bool Remove(int item) + => _list.Remove(item); + + public int Count + => _list.Count; + + public bool IsReadOnly + => ((ICollection)_list).IsReadOnly; + + public int IndexOf(int item) + => _list.IndexOf(item); + + public void Insert(int index, int item) + => _list.Insert(index, item); + + public void RemoveAt(int index) + => _list.RemoveAt(index); + public int this[int index] { get => _list[index]; @@ -709,9 +734,11 @@ public virtual void Detects_conflicting_converter_and_provider_type_with_relatio var dId = modelBuilder.Model.FindEntityType(typeof(D)).FindProperty(nameof(D.Id)); - Assert.Equal(CoreStrings.ConflictingRelationshipConversions("D", "Id", "string", "CastingConverter"), + Assert.Equal( + CoreStrings.ConflictingRelationshipConversions("D", "Id", "string", "CastingConverter"), Assert.Throws(dId.GetValueConverter).Message); - Assert.Equal(CoreStrings.ConflictingRelationshipConversions("D", "Id", "string", "CastingConverter"), + Assert.Equal( + CoreStrings.ConflictingRelationshipConversions("D", "Id", "string", "CastingConverter"), Assert.Throws(dId.GetProviderClrType).Message); } @@ -732,9 +759,11 @@ public virtual void Detects_conflicting_provider_types_with_relationship_cycle() var dId = modelBuilder.Model.FindEntityType(typeof(D)).FindProperty(nameof(D.Id)); - Assert.Equal(CoreStrings.ConflictingRelationshipConversions("D", "Id", "string", "long"), + Assert.Equal( + CoreStrings.ConflictingRelationshipConversions("D", "Id", "string", "long"), Assert.Throws(dId.GetValueConverter).Message); - Assert.Equal(CoreStrings.ConflictingRelationshipConversions("D", "Id", "string", "long"), + Assert.Equal( + CoreStrings.ConflictingRelationshipConversions("D", "Id", "string", "long"), Assert.Throws(dId.GetProviderClrType).Message); } diff --git a/test/EFCore.Tests/Infrastructure/ModelValidatorTestBase.cs b/test/EFCore.Tests/Infrastructure/ModelValidatorTestBase.cs index 522d2ff6986..dd0db43f636 100644 --- a/test/EFCore.Tests/Infrastructure/ModelValidatorTestBase.cs +++ b/test/EFCore.Tests/Infrastructure/ModelValidatorTestBase.cs @@ -436,9 +436,7 @@ protected class Picture } protected ModelValidatorTestBase() - { - LoggerFactory = new ListLoggerFactory(l => l == DbLoggerCategory.Model.Validation.Name || l == DbLoggerCategory.Model.Name); - } + => LoggerFactory = new ListLoggerFactory(l => l == DbLoggerCategory.Model.Validation.Name || l == DbLoggerCategory.Model.Name); protected ListLoggerFactory LoggerFactory { get; } diff --git a/test/EFCore.Tests/Metadata/Conventions/ConventionDispatcherTest.cs b/test/EFCore.Tests/Metadata/Conventions/ConventionDispatcherTest.cs index 352ed8d8e34..c6236e957ae 100644 --- a/test/EFCore.Tests/Metadata/Conventions/ConventionDispatcherTest.cs +++ b/test/EFCore.Tests/Metadata/Conventions/ConventionDispatcherTest.cs @@ -63,7 +63,8 @@ public void OnModelInitialized_calls_conventions_in_order(bool useBuilder) Assert.Equal(1, convention2.Calls); Assert.Equal(0, convention3.Calls); - AssertSetOperations(new ModelInitializedConvention(terminate: true), + AssertSetOperations( + new ModelInitializedConvention(terminate: true), conventions, conventions.ModelInitializedConventions); } @@ -114,7 +115,8 @@ public void OnModelFinalized_calls_conventions_in_order(bool useBuilder) Assert.Equal(1, convention2.Calls); Assert.Equal(0, convention3.Calls); - AssertSetOperations(new ModelFinalizingConvention(terminate: true), + AssertSetOperations( + new ModelFinalizingConvention(terminate: true), conventions, conventions.ModelFinalizingConventions); } @@ -205,7 +207,8 @@ public void OnModelAnnotationChanged_calls_conventions_in_order(bool useBuilder, builder.Metadata[CoreAnnotationNames.ProductVersion] = "bar"; Assert.Equal(new[] { "bar", null }, convention1.Calls); - AssertSetOperations(new ModelAnnotationChangedConvention(terminate: true), + AssertSetOperations( + new ModelAnnotationChangedConvention(terminate: true), conventions, conventions.ModelAnnotationChangedConventions); } @@ -298,7 +301,8 @@ public void ModelEmbeddedDiscriminatorName_calls_conventions_in_order(bool useBu Assert.Equal(new[] { ("Cheese", null), ("Onion", "Cheese") }, convention2.Calls); Assert.Empty(convention3.Calls); - AssertSetOperations(new ModelEmbeddedDiscriminatorNameConvention(terminate: true), + AssertSetOperations( + new ModelEmbeddedDiscriminatorNameConvention(terminate: true), conventions, conventions.ModelEmbeddedDiscriminatorNameConventions); } @@ -307,7 +311,10 @@ private class ModelEmbeddedDiscriminatorNameConvention(bool terminate) : IModelE public readonly List<(string, string)> Calls = []; public void ProcessEmbeddedDiscriminatorName( - IConventionModelBuilder modelBuilder, string newName, string oldName, IConventionContext context) + IConventionModelBuilder modelBuilder, + string newName, + string oldName, + IConventionContext context) { Assert.NotNull(modelBuilder.Metadata.Builder); @@ -367,7 +374,8 @@ public void OnEntityTypeAdded_calls_conventions_in_order(bool useBuilder, bool u Assert.Empty(builder.Metadata.GetEntityTypes()); Assert.Null(builder.Metadata.FindEntityType(typeof(Order))); - AssertSetOperations(new EntityTypeAddedConvention(terminate: true), + AssertSetOperations( + new EntityTypeAddedConvention(terminate: true), conventions, conventions.EntityTypeAddedConventions); } @@ -448,9 +456,11 @@ public void OnEntityTypeIgnored_calls_conventions_in_order(bool useBuilder, bool Assert.Equal(1, convention5.Calls); Assert.Equal(0, convention6.Calls); - AssertSetOperations(new TypeIgnoredConvention(terminate: true), + AssertSetOperations( + new TypeIgnoredConvention(terminate: true), conventions, conventions.TypeIgnoredConventions); - AssertSetOperations(new EntityTypeRemovedConvention(terminate: true), + AssertSetOperations( + new EntityTypeRemovedConvention(terminate: true), conventions, conventions.EntityTypeRemovedConventions); } @@ -550,7 +560,8 @@ public void OnEntityTypeMemberIgnored_calls_conventions_in_order(bool useBuilder Assert.Equal(new[] { "A" }, convention2.Calls); Assert.Empty(convention3.Calls); - AssertSetOperations(new EntityTypeMemberIgnoredConvention(terminate: true), + AssertSetOperations( + new EntityTypeMemberIgnoredConvention(terminate: true), conventions, conventions.EntityTypeMemberIgnoredConventions); } @@ -645,7 +656,8 @@ public void OnBaseTypeChanged_calls_conventions_in_order(bool useBuilder, bool u Assert.Equal(new[] { typeof(Order), null }, convention2.Calls); Assert.Empty(convention3.Calls); - AssertSetOperations(new EntityTypeBaseTypeChangedConvention(terminate: true), + AssertSetOperations( + new EntityTypeBaseTypeChangedConvention(terminate: true), conventions, conventions.EntityTypeBaseTypeChangedConventions); } @@ -709,8 +721,8 @@ public void OnDiscriminatorPropertySet_calls_conventions_in_order(bool useBuilde scope.Dispose(); } - Assert.Equal(new string[] { nameof(Order.OrderId) }, convention1.Calls); - Assert.Equal(new string[] { nameof(Order.OrderId) }, convention2.Calls); + Assert.Equal(new[] { nameof(Order.OrderId) }, convention1.Calls); + Assert.Equal(new[] { nameof(Order.OrderId) }, convention2.Calls); Assert.Empty(convention3.Calls); if (useBuilder) @@ -722,8 +734,8 @@ public void OnDiscriminatorPropertySet_calls_conventions_in_order(bool useBuilde entityBuilder.Metadata.SetDiscriminatorProperty(propertyBuilder.Metadata, ConfigurationSource.Convention); } - Assert.Equal(new string[] { nameof(Order.OrderId) }, convention1.Calls); - Assert.Equal(new string[] { nameof(Order.OrderId) }, convention2.Calls); + Assert.Equal(new[] { nameof(Order.OrderId) }, convention1.Calls); + Assert.Equal(new[] { nameof(Order.OrderId) }, convention2.Calls); Assert.Empty(convention3.Calls); if (useBuilder) @@ -739,7 +751,8 @@ public void OnDiscriminatorPropertySet_calls_conventions_in_order(bool useBuilde Assert.Equal(new[] { nameof(Order.OrderId), null }, convention2.Calls); Assert.Empty(convention3.Calls); - AssertSetOperations(new DiscriminatorPropertySetConvention(terminate: true), + AssertSetOperations( + new DiscriminatorPropertySetConvention(terminate: true), conventions, conventions.DiscriminatorPropertySetConventions); } @@ -841,7 +854,8 @@ public void OnPrimaryKeyChanged_calls_conventions_in_order(bool useBuilder, bool Assert.Empty(convention3.Calls); Assert.Null(entityBuilder.Metadata.GetPrimaryKeyConfigurationSource()); - AssertSetOperations(new EntityTypePrimaryKeyChangedConvention(terminate: true), + AssertSetOperations( + new EntityTypePrimaryKeyChangedConvention(terminate: true), conventions, conventions.EntityTypePrimaryKeyChangedConventions); } @@ -937,7 +951,8 @@ public void OnEntityTypeAnnotationChanged_calls_conventions_in_order(bool useBui entityBuilder.Metadata[CoreAnnotationNames.PropertyAccessMode] = PropertyAccessMode.Field; Assert.Equal(new[] { "bar", null }, convention1.Calls); - AssertSetOperations(new EntityTypeAnnotationChangedConvention(terminate: true), + AssertSetOperations( + new EntityTypeAnnotationChangedConvention(terminate: true), conventions, conventions.EntityTypeAnnotationChangedConventions); } @@ -1013,7 +1028,8 @@ public void OnForeignKeyAdded_calls_conventions_in_order(bool useBuilder, bool u Assert.Equal(new[] { "OrderId1" }, convention2.Calls); Assert.Empty(convention3.Calls); - AssertSetOperations(new ForeignKeyAddedConvention(terminate: true), + AssertSetOperations( + new ForeignKeyAddedConvention(terminate: true), conventions, conventions.ForeignKeyAddedConventions); } @@ -1087,7 +1103,8 @@ public void OnForeignKeyRemoved_calls_conventions_in_order(bool useScope) Assert.Equal(new[] { "FK" }, convention2.Calls); Assert.Empty(convention3.Calls); - AssertSetOperations(new ForeignKeyRemovedConvention(terminate: true), + AssertSetOperations( + new ForeignKeyRemovedConvention(terminate: true), conventions, conventions.ForeignKeyRemovedConventions); } @@ -1213,7 +1230,8 @@ public void OnForeignKeyPrincipalEndChanged_calls_conventions_in_order(bool useS Assert.Equal(new[] { nameof(Order), nameof(Order), nameof(OrderDetails), nameof(OrderDetails) }, convention2.Calls); Assert.Empty(convention3.Calls); - AssertSetOperations(new ForeignKeyPrincipalEndChangedConvention(terminate: true), + AssertSetOperations( + new ForeignKeyPrincipalEndChangedConvention(terminate: true), conventions, conventions.ForeignKeyPrincipalEndChangedConventions); } @@ -1279,7 +1297,8 @@ public void OnForeignKeyPropertiesChangedConvention_calls_conventions_in_order(b Assert.Equal(new[] { ("FK2", "FK3"), ("FK", "FK3") }, convention2.Calls); Assert.Empty(convention3.Calls); - AssertSetOperations(new ForeignKeyPropertiesChangedConvention(terminate: true), + AssertSetOperations( + new ForeignKeyPropertiesChangedConvention(terminate: true), conventions, conventions.ForeignKeyPropertiesChangedConventions); } @@ -1394,7 +1413,8 @@ public void OnForeignKeyUniquenessChanged_calls_conventions_in_order(bool useBui dependentEntityBuilder.Metadata.RemoveForeignKey( foreignKey.Properties, foreignKey.PrincipalKey, foreignKey.PrincipalEntityType)); - AssertSetOperations(new ForeignKeyUniquenessChangedConvention(terminate: true), + AssertSetOperations( + new ForeignKeyUniquenessChangedConvention(terminate: true), conventions, conventions.ForeignKeyUniquenessChangedConventions); } @@ -1493,7 +1513,8 @@ public void OnForeignKeyRequirednessChanged_calls_conventions_in_order(bool useB dependentEntityBuilder.Metadata.RemoveForeignKey( foreignKey.Properties, foreignKey.PrincipalKey, foreignKey.PrincipalEntityType)); - AssertSetOperations(new ForeignKeyRequirednessChangedConvention(terminate: true), + AssertSetOperations( + new ForeignKeyRequirednessChangedConvention(terminate: true), conventions, conventions.ForeignKeyRequirednessChangedConventions); } @@ -1594,7 +1615,8 @@ public void OnForeignKeyDependentRequirednessChanged_calls_conventions_in_order( dependentEntityBuilder.Metadata.RemoveForeignKey( foreignKey.Properties, foreignKey.PrincipalKey, foreignKey.PrincipalEntityType)); - AssertSetOperations(new ForeignKeyDependentRequirednessChangedConvention(terminate: true), + AssertSetOperations( + new ForeignKeyDependentRequirednessChangedConvention(terminate: true), conventions, conventions.ForeignKeyDependentRequirednessChangedConventions); } @@ -1695,7 +1717,8 @@ public void OnForeignKeyOwnershipChanged_calls_conventions_in_order(bool useBuil dependentEntityBuilder.Metadata.RemoveForeignKey( foreignKey.Properties, foreignKey.PrincipalKey, foreignKey.PrincipalEntityType)); - AssertSetOperations(new ForeignKeyOwnershipChangedConvention(terminate: true), + AssertSetOperations( + new ForeignKeyOwnershipChangedConvention(terminate: true), conventions, conventions.ForeignKeyOwnershipChangedConventions); } @@ -1793,7 +1816,8 @@ public void OnForeignKeyAnnotationChanged_calls_conventions_in_order(bool useBui Assert.Equal(new[] { "bar", null }, convention1.Calls); - AssertSetOperations(new ForeignKeyAnnotationChangedConvention(terminate: true), + AssertSetOperations( + new ForeignKeyAnnotationChangedConvention(terminate: true), conventions, conventions.ForeignKeyAnnotationChangedConventions); } @@ -1882,7 +1906,8 @@ public void OnForeignKeyNullNavigationSet_calls_conventions_in_order(bool useBui Assert.Equal(new[] { true, false }, convention2.Calls); Assert.Empty(convention3.Calls); - AssertSetOperations(new ForeignKeyNullNavigationSetConvention(terminate: true), + AssertSetOperations( + new ForeignKeyNullNavigationSetConvention(terminate: true), conventions, conventions.ForeignKeyNullNavigationSetConventions); } @@ -1962,7 +1987,8 @@ public void OnNavigationAdded_calls_conventions_in_order(bool useBuilder, bool u Assert.Equal(new[] { nameof(OrderDetails.Order), nameof(Order.OrderDetails) }, convention2.Calls); Assert.Empty(convention3.Calls); - AssertSetOperations(new NavigationAddedConvention(terminate: true), + AssertSetOperations( + new NavigationAddedConvention(terminate: true), conventions, conventions.NavigationAddedConventions); } @@ -2073,7 +2099,8 @@ public void OnNavigationAnnotationChanged_calls_conventions_in_order(bool useBui Assert.Equal(new[] { "bar", null }, convention1.Calls); - AssertSetOperations(new NavigationAnnotationChangedConvention(terminate: true), + AssertSetOperations( + new NavigationAnnotationChangedConvention(terminate: true), conventions, conventions.NavigationAnnotationChangedConventions); } @@ -2168,7 +2195,8 @@ public void OnNavigationRemoved_calls_conventions_in_order(bool useBuilder, bool Assert.Equal(new[] { nameof(OrderDetails.Order) }, convention2.Calls); Assert.Empty(convention3.Calls); - AssertSetOperations(new NavigationRemovedConvention(terminate: true), + AssertSetOperations( + new NavigationRemovedConvention(terminate: true), conventions, conventions.NavigationRemovedConventions); } @@ -2241,7 +2269,8 @@ public void OnSkipNavigationAdded_calls_conventions_in_order(bool useBuilder, bo Assert.Equal(new[] { nameof(Order.Products) }, convention2.Calls); Assert.Empty(convention3.Calls); - AssertSetOperations(new SkipNavigationAddedConvention(terminate: true), + AssertSetOperations( + new SkipNavigationAddedConvention(terminate: true), conventions, conventions.SkipNavigationAddedConventions); } @@ -2342,7 +2371,8 @@ public void OnSkipNavigationAnnotationChanged_calls_conventions_in_order(bool us Assert.Equal(new[] { "bar", null }, convention1.Calls); - AssertSetOperations(new SkipNavigationAnnotationChangedConvention(terminate: true), + AssertSetOperations( + new SkipNavigationAnnotationChangedConvention(terminate: true), conventions, conventions.SkipNavigationAnnotationChangedConventions); } @@ -2432,7 +2462,8 @@ public void OnSkipNavigationForeignKeyChanged_calls_conventions_in_order(bool us Assert.Equal(new[] { foreignKey, null }, convention2.Calls); Assert.Empty(convention3.Calls); - AssertSetOperations(new SkipNavigationForeignKeyChangedConvention(terminate: true), + AssertSetOperations( + new SkipNavigationForeignKeyChangedConvention(terminate: true), conventions, conventions.SkipNavigationForeignKeyChangedConventions); } @@ -2528,7 +2559,8 @@ public void OnSkipNavigationInverseChanged_calls_conventions_in_order(bool useBu Assert.Empty(convention3.Calls); - AssertSetOperations(new SkipNavigationInverseChangedConvention(terminate: true), + AssertSetOperations( + new SkipNavigationInverseChangedConvention(terminate: true), conventions, conventions.SkipNavigationInverseChangedConventions); } @@ -2599,7 +2631,8 @@ public void OnSkipNavigationRemoved_calls_conventions_in_order(bool useScope) Assert.Equal(new[] { nameof(Order.Products) }, convention2.Calls); Assert.Empty(convention3.Calls); - AssertSetOperations(new SkipNavigationRemovedConvention(terminate: true), + AssertSetOperations( + new SkipNavigationRemovedConvention(terminate: true), conventions, conventions.SkipNavigationRemovedConventions); } @@ -2669,7 +2702,8 @@ public void OnTriggerAdded_calls_conventions_in_order(bool useBuilder, bool useS Assert.Equal(new[] { "MyTrigger" }, convention2.Calls); Assert.Empty(convention3.Calls); - AssertSetOperations(new TriggerAddedConvention(terminate: true), + AssertSetOperations( + new TriggerAddedConvention(terminate: true), conventions, conventions.TriggerAddedConventions); } @@ -2736,7 +2770,8 @@ public void OnTriggerRemoved_calls_conventions_in_order(bool useScope) Assert.Equal(new[] { "MyTrigger" }, convention2.Calls); Assert.Empty(convention3.Calls); - AssertSetOperations(new TriggerRemovedConvention(terminate: true), + AssertSetOperations( + new TriggerRemovedConvention(terminate: true), conventions, conventions.TriggerRemovedConventions); } @@ -2810,7 +2845,8 @@ public void OnKeyAdded_calls_conventions_in_order(bool useBuilder, bool useScope Assert.Equal(new[] { keyPropertyName }, convention2.Calls); Assert.Empty(convention3.Calls); - AssertSetOperations(new KeyAddedConvention(terminate: true), + AssertSetOperations( + new KeyAddedConvention(terminate: true), conventions, conventions.KeyAddedConventions); } @@ -2871,7 +2907,8 @@ public void OnKeyRemoved_calls_conventions_in_order(bool useScope) Assert.Equal(new[] { "OrderId" }, convention2.Calls); Assert.Empty(convention3.Calls); - AssertSetOperations(new KeyRemovedConvention(terminate: true), + AssertSetOperations( + new KeyRemovedConvention(terminate: true), conventions, conventions.KeyRemovedConventions); } @@ -2969,7 +3006,8 @@ public void OnKeyAnnotationChanged_calls_conventions_in_order(bool useBuilder, b Assert.Equal(new[] { "bar", null }, convention1.Calls); - AssertSetOperations(new KeyAnnotationChangedConvention(terminate: true), + AssertSetOperations( + new KeyAnnotationChangedConvention(terminate: true), conventions, conventions.KeyAnnotationChangedConventions); } @@ -3044,7 +3082,8 @@ public void OnIndexAdded_calls_conventions_in_order(bool useBuilder, bool useSco Assert.Equal(new[] { "OrderId" }, convention2.Calls); Assert.Empty(convention3.Calls); - AssertSetOperations(new IndexAddedConvention(terminate: true), + AssertSetOperations( + new IndexAddedConvention(terminate: true), conventions, conventions.IndexAddedConventions); } @@ -3110,7 +3149,8 @@ public void OnIndexRemoved_calls_conventions_in_order(bool useScope) Assert.Equal(new[] { "OrderId" }, convention2.Calls); Assert.Empty(convention3.Calls); - AssertSetOperations(new IndexRemovedConvention(terminate: true), + AssertSetOperations( + new IndexRemovedConvention(terminate: true), conventions, conventions.IndexRemovedConventions); } @@ -3206,7 +3246,8 @@ public void OnIndexUniquenessChanged_calls_conventions_in_order(bool useBuilder, Assert.Same(index, entityBuilder.Metadata.RemoveIndex(index.Properties)); - AssertSetOperations(new IndexUniquenessChangedConvention(terminate: true), + AssertSetOperations( + new IndexUniquenessChangedConvention(terminate: true), conventions, conventions.IndexUniquenessChangedConventions); } @@ -3301,7 +3342,8 @@ public void OnIndexSortOrderChanged_calls_conventions_in_order(bool useBuilder, Assert.Same(index, entityBuilder.Metadata.RemoveIndex(index.Properties)); - AssertSetOperations(new IndexSortOrderChangedConvention(terminate: true), + AssertSetOperations( + new IndexSortOrderChangedConvention(terminate: true), conventions, conventions.IndexSortOrderChangedConventions); } @@ -3398,7 +3440,8 @@ public void OnIndexAnnotationChanged_calls_conventions_in_order(bool useBuilder, Assert.Equal(new[] { "bar", null }, convention1.Calls); - AssertSetOperations(new IndexAnnotationChangedConvention(terminate: true), + AssertSetOperations( + new IndexAnnotationChangedConvention(terminate: true), conventions, conventions.IndexAnnotationChangedConventions); } @@ -3500,7 +3543,8 @@ public void OnPropertyAdded_calls_conventions_in_order(bool useBuilder, bool use Assert.Empty(entityBuilder.Metadata.GetProperties()); - AssertSetOperations(new PropertyAddedConvention(terminate: true), + AssertSetOperations( + new PropertyAddedConvention(terminate: true), conventions, conventions.PropertyAddedConventions); } @@ -3637,7 +3681,8 @@ public void OnPropertyNullabilityChanged_calls_conventions_in_order(bool useBuil Assert.Empty(convention3.Calls); - AssertSetOperations(new PropertyNullabilityChangedConvention(terminate: true), + AssertSetOperations( + new PropertyNullabilityChangedConvention(terminate: true), conventions, conventions.PropertyNullabilityChangedConventions); } @@ -3733,7 +3778,8 @@ public void OnPropertyFieldChanged_calls_conventions_in_order(bool useBuilder, b Assert.Equal(new[] { null, nameof(Order.IntField) }, convention2.Calls); Assert.Empty(convention3.Calls); - AssertSetOperations(new PropertyFieldChangedConvention(terminate: true), + AssertSetOperations( + new PropertyFieldChangedConvention(terminate: true), conventions, conventions.PropertyFieldChangedConventions); } @@ -3831,7 +3877,8 @@ public void OnPropertyElementTypeChanged_calls_conventions_in_order(bool useBuil Assert.Equal(new (object, object)[] { (null, elementType), (elementType, null) }, convention2.Calls); Assert.Empty(convention3.Calls); - AssertSetOperations(new PropertyElementTypeChangedConvention(terminate: true), + AssertSetOperations( + new PropertyElementTypeChangedConvention(terminate: true), conventions, conventions.PropertyElementTypeChangedConventions); } @@ -3929,7 +3976,8 @@ public void OnPropertyAnnotationChanged_calls_conventions_in_order(bool useBuild Assert.Equal(new[] { "bar", null }, convention1.Calls); - AssertSetOperations(new PropertyAnnotationChangedConvention(terminate: true), + AssertSetOperations( + new PropertyAnnotationChangedConvention(terminate: true), conventions, conventions.PropertyAnnotationChangedConventions); } @@ -4000,7 +4048,8 @@ public void OnPropertyRemoved_calls_conventions_in_order(bool useScope) Assert.Equal(new[] { property }, convention2.Calls); Assert.Empty(convention3.Calls); - AssertSetOperations(new PropertyRemovedConvention(terminate: true), + AssertSetOperations( + new PropertyRemovedConvention(terminate: true), conventions, conventions.PropertyRemovedConventions); } @@ -4499,7 +4548,8 @@ public void OnComplexPropertyAdded_calls_conventions_in_order(bool useBuilder, b Assert.Empty(entityBuilder.Metadata.GetComplexProperties()); - AssertSetOperations(new ComplexPropertyAddedConvention(terminate: true), + AssertSetOperations( + new ComplexPropertyAddedConvention(terminate: true), conventions, conventions.ComplexPropertyAddedConventions); } @@ -4636,7 +4686,8 @@ public void OnComplexPropertyNullabilityChanged_calls_conventions_in_order(bool Assert.Empty(convention3.Calls); - AssertSetOperations(new ComplexPropertyNullabilityChangedConvention(terminate: true), + AssertSetOperations( + new ComplexPropertyNullabilityChangedConvention(terminate: true), conventions, conventions.ComplexPropertyNullabilityChangedConventions); } @@ -4733,7 +4784,8 @@ public void OnComplexPropertyFieldChanged_calls_conventions_in_order(bool useBui Assert.Equal(new[] { null, nameof(Order.OrderDetailsField) }, convention2.Calls); Assert.Empty(convention3.Calls); - AssertSetOperations(new ComplexPropertyFieldChangedConvention(terminate: true), + AssertSetOperations( + new ComplexPropertyFieldChangedConvention(terminate: true), conventions, conventions.ComplexPropertyFieldChangedConventions); } @@ -4831,7 +4883,8 @@ public void OnComplexPropertyAnnotationChanged_calls_conventions_in_order(bool u Assert.Equal(new[] { "bar", null }, convention1.Calls); - AssertSetOperations(new ComplexPropertyAnnotationChangedConvention(terminate: true), + AssertSetOperations( + new ComplexPropertyAnnotationChangedConvention(terminate: true), conventions, conventions.ComplexPropertyAnnotationChangedConventions); } @@ -4902,7 +4955,8 @@ public void OnComplexPropertyRemoved_calls_conventions_in_order(bool useScope) Assert.Equal(new[] { property }, convention2.Calls); Assert.Empty(convention3.Calls); - AssertSetOperations(new ComplexPropertyRemovedConvention(terminate: true), + AssertSetOperations( + new ComplexPropertyRemovedConvention(terminate: true), conventions, conventions.ComplexPropertyRemovedConventions); } @@ -5000,7 +5054,8 @@ public void OnComplexTypeAnnotationChanged_calls_conventions_in_order(bool useBu Assert.Equal(new[] { "bar", null }, convention1.Calls); - AssertSetOperations(new ComplexTypeAnnotationChangedConvention(terminate: true), + AssertSetOperations( + new ComplexTypeAnnotationChangedConvention(terminate: true), conventions, conventions.ComplexTypeAnnotationChangedConventions); } @@ -5101,7 +5156,8 @@ public void OnComplexTypeMemberIgnored_calls_conventions_in_order(bool useBuilde Assert.Empty(entityBuilder.Metadata.GetIgnoredMembers()); - AssertSetOperations(new ComplexTypeMemberIgnoredConvention(terminate: true), + AssertSetOperations( + new ComplexTypeMemberIgnoredConvention(terminate: true), conventions, conventions.ComplexTypeMemberIgnoredConventions); } @@ -5199,7 +5255,8 @@ public void OnElementTypeAnnotationChanged_calls_conventions_in_order(bool useBu Assert.Equal(new[] { "bar", null }, convention1.Calls); - AssertSetOperations(new ElementTypeAnnotationChangedConvention(terminate: true), + AssertSetOperations( + new ElementTypeAnnotationChangedConvention(terminate: true), conventions, conventions.ElementTypeAnnotationChangedConventions); } @@ -5340,7 +5397,8 @@ public void OnElementTypeNullabilityChanged_calls_conventions_in_order(bool useB Assert.Empty(convention3.Calls); - AssertSetOperations(new ElementTypeNullabilityChangedConvention(terminate: true), + AssertSetOperations( + new ElementTypeNullabilityChangedConvention(terminate: true), conventions, conventions.ElementTypeNullabilityChangedConventions); } @@ -5363,7 +5421,9 @@ public void ProcessElementTypeNullabilityChanged( } private static void AssertSetOperations( - TConvention newConvention, ConventionSet conventions, List conventionList) + TConvention newConvention, + ConventionSet conventions, + List conventionList) where TConvention : class, IConvention { Assert.Equal(3, conventionList.Count); @@ -5383,6 +5443,7 @@ private class Order public static readonly PropertyInfo OtherOrderDetailsProperty = typeof(Order).GetProperty(nameof(OtherOrderDetails)); public readonly int IntField = 1; + // ReSharper disable once RedundantDefaultMemberInitializer public readonly OrderDetails OrderDetailsField = default; diff --git a/test/EFCore.Tests/Metadata/Internal/ClrPropertyGetterFactoryTest.cs b/test/EFCore.Tests/Metadata/Internal/ClrPropertyGetterFactoryTest.cs index a94e97b752d..2765c6de396 100644 --- a/test/EFCore.Tests/Metadata/Internal/ClrPropertyGetterFactoryTest.cs +++ b/test/EFCore.Tests/Metadata/Internal/ClrPropertyGetterFactoryTest.cs @@ -189,10 +189,12 @@ public void Delegate_getter_is_returned_for_index_property() Assert.Equal( "ValueA", - ClrPropertyGetterFactory.Instance.Create((IPropertyBase)propertyA).GetClrValueUsingContainingEntity(new IndexedClass { Id = 7 })); + ClrPropertyGetterFactory.Instance.Create((IPropertyBase)propertyA) + .GetClrValueUsingContainingEntity(new IndexedClass { Id = 7 })); Assert.Equal( 123, - ClrPropertyGetterFactory.Instance.Create((IPropertyBase)propertyB).GetClrValueUsingContainingEntity(new IndexedClass { Id = 7 })); + ClrPropertyGetterFactory.Instance.Create((IPropertyBase)propertyB) + .GetClrValueUsingContainingEntity(new IndexedClass { Id = 7 })); } [ConditionalFact] diff --git a/test/EFCore.Tests/Metadata/Internal/EntityTypeTest.cs b/test/EFCore.Tests/Metadata/Internal/EntityTypeTest.cs index 2c41f275e15..4af00967b22 100644 --- a/test/EFCore.Tests/Metadata/Internal/EntityTypeTest.cs +++ b/test/EFCore.Tests/Metadata/Internal/EntityTypeTest.cs @@ -600,7 +600,6 @@ public void Can_add_a_foreign_key_targeting_different_key() Assert.Equal([fk2, fk1], orderType.GetForeignKeys().ToArray()); } - [ConditionalFact] public void Adding_a_foreign_key_throws_if_duplicate() { @@ -3315,6 +3314,7 @@ private class SelfRef public int? SelfRefId { get; set; } public int ForeignKey { get; set; } } + private static IMutableModel CreateEmptyModel() => new Model(); diff --git a/test/EFCore.Tests/Metadata/Internal/PropertyBaseTest.cs b/test/EFCore.Tests/Metadata/Internal/PropertyBaseTest.cs index 400a19c5d07..35561bbc922 100644 --- a/test/EFCore.Tests/Metadata/Internal/PropertyBaseTest.cs +++ b/test/EFCore.Tests/Metadata/Internal/PropertyBaseTest.cs @@ -685,14 +685,19 @@ public void Get_MemberInfos_for_auto_prop_skip_collection_navigations() MemberInfoTest(CreateSkipCollectionNavigation(field), null, field, field, field); MemberInfoTest(CreateSkipCollectionNavigation(field), PropertyAccessMode.Field, field, field, field); MemberInfoTest( - CreateSkipCollectionNavigation(field), PropertyAccessMode.FieldDuringConstruction, field, SkipCollection, SkipCollection); - MemberInfoTest(CreateSkipCollectionNavigation(field), PropertyAccessMode.Property, SkipCollection, SkipCollection, SkipCollection); + CreateSkipCollectionNavigation(field), PropertyAccessMode.FieldDuringConstruction, field, + SkipCollection, SkipCollection); + MemberInfoTest( + CreateSkipCollectionNavigation(field), PropertyAccessMode.Property, SkipCollection, SkipCollection, + SkipCollection); MemberInfoTest(CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferField, field, field, field); MemberInfoTest( - CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferFieldDuringConstruction, field, SkipCollection, + CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferFieldDuringConstruction, field, + SkipCollection, SkipCollection); MemberInfoTest( - CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferProperty, SkipCollection, SkipCollection, SkipCollection); + CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferProperty, SkipCollection, + SkipCollection, SkipCollection); } [ConditionalFact] @@ -703,14 +708,19 @@ public void Get_MemberInfos_for_full_prop_skip_collection_navigations() MemberInfoTest(CreateSkipCollectionNavigation(field), null, field, field, field); MemberInfoTest(CreateSkipCollectionNavigation(field), PropertyAccessMode.Field, field, field, field); MemberInfoTest( - CreateSkipCollectionNavigation(field), PropertyAccessMode.FieldDuringConstruction, field, SkipCollection, SkipCollection); - MemberInfoTest(CreateSkipCollectionNavigation(field), PropertyAccessMode.Property, SkipCollection, SkipCollection, SkipCollection); + CreateSkipCollectionNavigation(field), PropertyAccessMode.FieldDuringConstruction, field, + SkipCollection, SkipCollection); + MemberInfoTest( + CreateSkipCollectionNavigation(field), PropertyAccessMode.Property, SkipCollection, SkipCollection, + SkipCollection); MemberInfoTest(CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferField, field, field, field); MemberInfoTest( - CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferFieldDuringConstruction, field, SkipCollection, + CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferFieldDuringConstruction, field, + SkipCollection, SkipCollection); MemberInfoTest( - CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferProperty, SkipCollection, SkipCollection, SkipCollection); + CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferProperty, SkipCollection, + SkipCollection, SkipCollection); } [ConditionalFact] @@ -719,15 +729,23 @@ public void Get_MemberInfos_for_read_only_prop_skip_collection_navigations() const string field = "_skipCollection"; MemberInfoTest(CreateSkipCollectionNavigation(field), null, field, field, field); - MemberInfoTest(CreateSkipCollectionNavigation(field), PropertyAccessMode.Field, field, field, field); MemberInfoTest( - CreateSkipCollectionNavigation(field), PropertyAccessMode.FieldDuringConstruction, field, field, SkipCollection); - MemberInfoTest(CreateSkipCollectionNavigation(field), PropertyAccessMode.Property, null, null, SkipCollection); - MemberInfoTest(CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferField, field, field, field); + CreateSkipCollectionNavigation(field), PropertyAccessMode.Field, field, field, field); + MemberInfoTest( + CreateSkipCollectionNavigation(field), PropertyAccessMode.FieldDuringConstruction, field, + field, SkipCollection); + MemberInfoTest( + CreateSkipCollectionNavigation(field), PropertyAccessMode.Property, null, null, + SkipCollection); + MemberInfoTest( + CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferField, field, field, field); MemberInfoTest( - CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferFieldDuringConstruction, field, field, + CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferFieldDuringConstruction, field, + field, + SkipCollection); + MemberInfoTest( + CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferProperty, field, field, SkipCollection); - MemberInfoTest(CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferProperty, field, field, SkipCollection); } [ConditionalFact] @@ -736,16 +754,24 @@ public void Get_MemberInfos_for_read_only_auto_prop_skip_collection_navigations( const string field = "k__BackingField"; MemberInfoTest(CreateSkipCollectionNavigation(field), null, field, field, field); - MemberInfoTest(CreateSkipCollectionNavigation(field), PropertyAccessMode.Field, field, field, field); MemberInfoTest( - CreateSkipCollectionNavigation(field), PropertyAccessMode.FieldDuringConstruction, field, field, SkipCollection); - MemberInfoTest(CreateSkipCollectionNavigation(field), PropertyAccessMode.Property, null, null, SkipCollection); - MemberInfoTest(CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferField, field, field, field); + CreateSkipCollectionNavigation(field), PropertyAccessMode.Field, field, field, field); + MemberInfoTest( + CreateSkipCollectionNavigation(field), PropertyAccessMode.FieldDuringConstruction, + field, field, SkipCollection); + MemberInfoTest( + CreateSkipCollectionNavigation(field), PropertyAccessMode.Property, null, null, + SkipCollection); + MemberInfoTest( + CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferField, field, field, + field); MemberInfoTest( - CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferFieldDuringConstruction, + CreateSkipCollectionNavigation(field), + PropertyAccessMode.PreferFieldDuringConstruction, field, field, SkipCollection); MemberInfoTest( - CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferProperty, field, field, SkipCollection); + CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferProperty, field, field, + SkipCollection); } [ConditionalFact] @@ -754,16 +780,25 @@ public void Get_MemberInfos_for_read_only_field_prop_skip_collection_navigations const string field = "_skipCollection"; MemberInfoTest(CreateSkipCollectionNavigation(field), null, field, field, field); - MemberInfoTest(CreateSkipCollectionNavigation(field), PropertyAccessMode.Field, field, field, field); MemberInfoTest( - CreateSkipCollectionNavigation(field), PropertyAccessMode.FieldDuringConstruction, field, field, SkipCollection); - MemberInfoTest(CreateSkipCollectionNavigation(field), PropertyAccessMode.Property, null, null, SkipCollection); - MemberInfoTest(CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferField, field, field, field); + CreateSkipCollectionNavigation(field), PropertyAccessMode.Field, field, field, + field); MemberInfoTest( - CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferFieldDuringConstruction, + CreateSkipCollectionNavigation(field), PropertyAccessMode.FieldDuringConstruction, field, field, SkipCollection); MemberInfoTest( - CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferProperty, field, field, SkipCollection); + CreateSkipCollectionNavigation(field), PropertyAccessMode.Property, null, null, + SkipCollection); + MemberInfoTest( + CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferField, field, field, + field); + MemberInfoTest( + CreateSkipCollectionNavigation(field), + PropertyAccessMode.PreferFieldDuringConstruction, + field, field, SkipCollection); + MemberInfoTest( + CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferProperty, field, + field, SkipCollection); } [ConditionalFact] @@ -772,56 +807,76 @@ public void Get_MemberInfos_for_write_only_prop_skip_collection_navigations() const string field = "_skipCollection"; MemberInfoTest(CreateSkipCollectionNavigation(field), null, field, field, field); - MemberInfoTest(CreateSkipCollectionNavigation(field), PropertyAccessMode.Field, field, field, field); MemberInfoTest( - CreateSkipCollectionNavigation(field), PropertyAccessMode.FieldDuringConstruction, field, SkipCollection, field); + CreateSkipCollectionNavigation(field), PropertyAccessMode.Field, field, field, field); + MemberInfoTest( + CreateSkipCollectionNavigation(field), PropertyAccessMode.FieldDuringConstruction, field, + SkipCollection, field); MemberInfoTest( CreateSkipCollectionNavigation(field), PropertyAccessMode.Property, SkipCollection, SkipCollection, NoGetterSkipColl()); - MemberInfoTest(CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferField, field, field, field); MemberInfoTest( - CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferFieldDuringConstruction, field, SkipCollection, + CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferField, field, field, field); + MemberInfoTest( + CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferFieldDuringConstruction, + field, SkipCollection, field); MemberInfoTest( - CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferProperty, SkipCollection, SkipCollection, field); + CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferProperty, SkipCollection, + SkipCollection, field); } [ConditionalFact] public void Get_MemberInfos_for_full_prop_skip_collection_navigations_with_field_not_found() { - MemberInfoTest(CreateSkipCollectionNavigation(null), null, SkipCollection, SkipCollection, SkipCollection); MemberInfoTest( - CreateSkipCollectionNavigation(null), PropertyAccessMode.Field, null, null, NoFieldSkipColl()); + CreateSkipCollectionNavigation(null), null, SkipCollection, SkipCollection, + SkipCollection); + MemberInfoTest( + CreateSkipCollectionNavigation(null), PropertyAccessMode.Field, null, null, + NoFieldSkipColl()); MemberInfoTest( - CreateSkipCollectionNavigation(null), PropertyAccessMode.FieldDuringConstruction, null, SkipCollection, + CreateSkipCollectionNavigation(null), PropertyAccessMode.FieldDuringConstruction, null, + SkipCollection, SkipCollection); MemberInfoTest( - CreateSkipCollectionNavigation(null), PropertyAccessMode.Property, SkipCollection, SkipCollection, SkipCollection); + CreateSkipCollectionNavigation(null), PropertyAccessMode.Property, SkipCollection, + SkipCollection, SkipCollection); MemberInfoTest( - CreateSkipCollectionNavigation(null), PropertyAccessMode.PreferField, SkipCollection, SkipCollection, SkipCollection); + CreateSkipCollectionNavigation(null), PropertyAccessMode.PreferField, SkipCollection, + SkipCollection, SkipCollection); MemberInfoTest( CreateSkipCollectionNavigation(null), PropertyAccessMode.PreferFieldDuringConstruction, SkipCollection, SkipCollection, SkipCollection); MemberInfoTest( - CreateSkipCollectionNavigation(null), PropertyAccessMode.PreferProperty, SkipCollection, SkipCollection, SkipCollection); + CreateSkipCollectionNavigation(null), PropertyAccessMode.PreferProperty, SkipCollection, + SkipCollection, SkipCollection); } [ConditionalFact] public void Get_MemberInfos_for_read_only_prop_skip_collection_navigations_with_field_not_found() { - MemberInfoTest(CreateSkipCollectionNavigation(null), null, null, null, SkipCollection); + MemberInfoTest( + CreateSkipCollectionNavigation(null), null, null, null, SkipCollection); MemberInfoTest( CreateSkipCollectionNavigation(null), PropertyAccessMode.Field, null, null, NoFieldSkipColl()); MemberInfoTest( - CreateSkipCollectionNavigation(null), PropertyAccessMode.FieldDuringConstruction, null, null, SkipCollection); - MemberInfoTest(CreateSkipCollectionNavigation(null), PropertyAccessMode.Property, null, null, SkipCollection); - MemberInfoTest(CreateSkipCollectionNavigation(null), PropertyAccessMode.PreferField, null, null, SkipCollection); + CreateSkipCollectionNavigation(null), PropertyAccessMode.FieldDuringConstruction, + null, null, SkipCollection); + MemberInfoTest( + CreateSkipCollectionNavigation(null), PropertyAccessMode.Property, null, null, + SkipCollection); + MemberInfoTest( + CreateSkipCollectionNavigation(null), PropertyAccessMode.PreferField, null, null, + SkipCollection); MemberInfoTest( - CreateSkipCollectionNavigation(null), PropertyAccessMode.PreferFieldDuringConstruction, + CreateSkipCollectionNavigation(null), + PropertyAccessMode.PreferFieldDuringConstruction, null, null, SkipCollection); MemberInfoTest( - CreateSkipCollectionNavigation(null), PropertyAccessMode.PreferProperty, null, null, SkipCollection); + CreateSkipCollectionNavigation(null), PropertyAccessMode.PreferProperty, null, + null, SkipCollection); } [ConditionalFact] @@ -834,7 +889,8 @@ public void Get_MemberInfos_for_write_only_prop_skip_collection_navigations_with CreateSkipCollectionNavigation(null), PropertyAccessMode.Field, null, null, NoFieldSkipColl()); MemberInfoTest( - CreateSkipCollectionNavigation(null), PropertyAccessMode.FieldDuringConstruction, + CreateSkipCollectionNavigation(null), + PropertyAccessMode.FieldDuringConstruction, null, SkipCollection, NoFieldOrGetterSkipColl()); MemberInfoTest( CreateSkipCollectionNavigation(null), PropertyAccessMode.Property, @@ -853,15 +909,22 @@ public void Get_MemberInfos_for_full_prop_skip_collection_navigations_private_se const string field = "_skipCollection"; MemberInfoTest(CreateSkipCollectionNavigation(field), null, field, field, field); - MemberInfoTest(CreateSkipCollectionNavigation(field), PropertyAccessMode.Field, field, field, field); MemberInfoTest( - CreateSkipCollectionNavigation(field), PropertyAccessMode.FieldDuringConstruction, field, + CreateSkipCollectionNavigation(field), PropertyAccessMode.Field, field, field, + field); + MemberInfoTest( + CreateSkipCollectionNavigation(field), PropertyAccessMode.FieldDuringConstruction, + field, SkipCollection, SkipCollection); MemberInfoTest( - CreateSkipCollectionNavigation(field), PropertyAccessMode.Property, SkipCollection, SkipCollection, SkipCollection); - MemberInfoTest(CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferField, field, field, field); + CreateSkipCollectionNavigation(field), PropertyAccessMode.Property, SkipCollection, + SkipCollection, SkipCollection); + MemberInfoTest( + CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferField, field, + field, field); MemberInfoTest( - CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferProperty, SkipCollection, SkipCollection, + CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferProperty, + SkipCollection, SkipCollection, SkipCollection); } @@ -871,15 +934,21 @@ public void Get_MemberInfos_for_full_prop_skip_collection_navigations_private_ge const string field = "_skipCollection"; MemberInfoTest(CreateSkipCollectionNavigation(field), null, field, field, field); - MemberInfoTest(CreateSkipCollectionNavigation(field), PropertyAccessMode.Field, field, field, field); + MemberInfoTest( + CreateSkipCollectionNavigation(field), PropertyAccessMode.Field, field, field, + field); MemberInfoTest( CreateSkipCollectionNavigation(field), PropertyAccessMode.FieldDuringConstruction, field, SkipCollection, SkipCollection); MemberInfoTest( - CreateSkipCollectionNavigation(field), PropertyAccessMode.Property, SkipCollection, SkipCollection, SkipCollection); - MemberInfoTest(CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferField, field, field, field); + CreateSkipCollectionNavigation(field), PropertyAccessMode.Property, SkipCollection, + SkipCollection, SkipCollection); + MemberInfoTest( + CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferField, field, + field, field); MemberInfoTest( - CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferProperty, SkipCollection, SkipCollection, + CreateSkipCollectionNavigation(field), PropertyAccessMode.PreferProperty, + SkipCollection, SkipCollection, SkipCollection); } diff --git a/test/EFCore.Tests/Metadata/Internal/PropertyTest.cs b/test/EFCore.Tests/Metadata/Internal/PropertyTest.cs index 21caaca29cf..f5c94dcb3f1 100644 --- a/test/EFCore.Tests/Metadata/Internal/PropertyTest.cs +++ b/test/EFCore.Tests/Metadata/Internal/PropertyTest.cs @@ -549,9 +549,10 @@ public override string FromJsonTyped(ref Utf8JsonReaderManager manager, object e public override void ToJsonTyped(Utf8JsonWriter writer, string value) => writer.WriteStringValue(value); - private readonly Expression> _instanceLambda = () => new(); + private readonly Expression> _instanceLambda = () => new SimpleJasonValueReaderWriter(); - public override Expression ConstructorExpression => _instanceLambda.Body; + public override Expression ConstructorExpression + => _instanceLambda.Body; } private class JasonValueReaderWriterWithPrivateInstance : JsonValueReaderWriter @@ -566,7 +567,8 @@ public override void ToJsonTyped(Utf8JsonWriter writer, string value) private readonly Expression> _instanceLambda = () => Instance; - public override Expression ConstructorExpression => _instanceLambda.Body; + public override Expression ConstructorExpression + => _instanceLambda.Body; } private class JasonValueReaderWriterWithBadInstance : JsonValueReaderWriter @@ -579,7 +581,8 @@ public override string FromJsonTyped(ref Utf8JsonReaderManager manager, object e public override void ToJsonTyped(Utf8JsonWriter writer, string value) => writer.WriteStringValue(value); - public override Expression ConstructorExpression => Expression.Default(typeof(JasonValueReaderWriterWithBadInstance)); + public override Expression ConstructorExpression + => Expression.Default(typeof(JasonValueReaderWriterWithBadInstance)); } private class SimpleJasonValueReaderWriterWithInstance : JsonValueReaderWriter @@ -594,7 +597,8 @@ public override void ToJsonTyped(Utf8JsonWriter writer, string value) private readonly Expression> _instanceLambda = () => Instance; - public override Expression ConstructorExpression => _instanceLambda.Body; + public override Expression ConstructorExpression + => _instanceLambda.Body; } private class SimpleJasonValueReaderWriterWithInstanceAndPrivateConstructor : JsonValueReaderWriter @@ -613,7 +617,8 @@ public override void ToJsonTyped(Utf8JsonWriter writer, string value) private readonly Expression> _instanceLambda = () => Instance; - public override Expression ConstructorExpression => _instanceLambda.Body; + public override Expression ConstructorExpression + => _instanceLambda.Body; } private class NonDerivedJsonValueReaderWriter; @@ -629,9 +634,10 @@ public override void ToJson(Utf8JsonWriter writer, object value) public override Type ValueType => typeof(string); - private readonly Expression> _instanceLambda = () => new(); + private readonly Expression> _instanceLambda = () => new NonGenericJsonValueReaderWriter(); - public override Expression ConstructorExpression => _instanceLambda.Body; + public override Expression ConstructorExpression + => _instanceLambda.Body; } private abstract class AbstractJasonValueReaderWriter : JsonValueReaderWriter; @@ -648,9 +654,10 @@ public override string FromJsonTyped(ref Utf8JsonReaderManager manager, object e public override void ToJsonTyped(Utf8JsonWriter writer, string value) => writer.WriteStringValue(value); - private readonly Expression> _instanceLambda = () => new(); + private readonly Expression> _instanceLambda = () => new PrivateJasonValueReaderWriter(); - public override Expression ConstructorExpression => _instanceLambda.Body; + public override Expression ConstructorExpression + => _instanceLambda.Body; } private class NonParameterlessJsonValueReaderWriter(bool _) : JsonValueReaderWriter @@ -663,8 +670,8 @@ public override void ToJsonTyped(Utf8JsonWriter writer, string value) private readonly ConstructorInfo _constructorInfo = typeof(NonParameterlessJsonValueReaderWriter).GetConstructor([typeof(bool)])!; - public override Expression ConstructorExpression => - Expression.New(_constructorInfo, Expression.Constant(_)); + public override Expression ConstructorExpression + => Expression.New(_constructorInfo, Expression.Constant(_)); } private static IMutableModel CreateModel() diff --git a/test/EFCore.Tests/Query/EntityMaterializerSourceTest.cs b/test/EFCore.Tests/Query/EntityMaterializerSourceTest.cs index de96391c436..59ff9eb5dcc 100644 --- a/test/EFCore.Tests/Query/EntityMaterializerSourceTest.cs +++ b/test/EFCore.Tests/Query/EntityMaterializerSourceTest.cs @@ -3,7 +3,6 @@ using System.ComponentModel.DataAnnotations.Schema; using Microsoft.EntityFrameworkCore.Metadata.Internal; -using Microsoft.EntityFrameworkCore.Proxies.Internal; using Microsoft.EntityFrameworkCore.Query.Internal; // ReSharper disable UnusedMember.Local @@ -519,7 +518,6 @@ private Parameterless() private class WithProperties(int id) { - // ReSharper disable once AutoPropertyCanBeMadeGetOnly.Local public int Id { get; set; } = id; } @@ -531,9 +529,7 @@ public ParameterlessAndWithProperties() } public ParameterlessAndWithProperties(int id) - { - Id = id; - } + => Id = id; // ReSharper disable once AutoPropertyCanBeMadeGetOnly.Local public int Id { get; set; } @@ -567,9 +563,7 @@ private class WithServiceAndWithProperties(ILazyLoader lazyLoader) { public WithServiceAndWithProperties(ILazyLoader lazyLoader, int id) : this(lazyLoader) - { - Id = id; - } + => Id = id; public ILazyLoader LazyLoader { get; } = lazyLoader; diff --git a/test/EFCore.Tests/Storage/ExecutionStrategyTest.cs b/test/EFCore.Tests/Storage/ExecutionStrategyTest.cs index ec9aca9e4e9..587cbf02994 100644 --- a/test/EFCore.Tests/Storage/ExecutionStrategyTest.cs +++ b/test/EFCore.Tests/Storage/ExecutionStrategyTest.cs @@ -12,9 +12,7 @@ public class ExecutionStrategyTest : IDisposable private readonly DbContext Context; public ExecutionStrategyTest() - { - Context = CreateContext(); - } + => Context = CreateContext(); public void Dispose() => Context.Dispose(); diff --git a/test/EFCore.Tests/ValueGeneration/ValueGeneratorSelectorTest.cs b/test/EFCore.Tests/ValueGeneration/ValueGeneratorSelectorTest.cs index 6f14e9207af..7612f79ac0c 100644 --- a/test/EFCore.Tests/ValueGeneration/ValueGeneratorSelectorTest.cs +++ b/test/EFCore.Tests/ValueGeneration/ValueGeneratorSelectorTest.cs @@ -70,7 +70,8 @@ public void Returns_built_in_generators_for_types_setup_for_value_generation_usi var selector = new ValueGeneratorSelector( new ValueGeneratorSelectorDependencies(new ValueGeneratorCache(new ValueGeneratorCacheDependencies()))); - Assert.IsType(selector.TrySelect(entityType.FindProperty("Custom")!, entityType, out var generator) ? generator : null); + Assert.IsType( + selector.TrySelect(entityType.FindProperty("Custom")!, entityType, out var generator) ? generator : null); Assert.Null(selector.TrySelect(entityType.FindProperty("Id")!, entityType, out generator) ? generator : null); Assert.Null(selector.TrySelect(entityType.FindProperty("Long")!, entityType, out generator) ? generator : null); @@ -107,12 +108,16 @@ public void Returns_built_in_generators_for_types_setup_for_value_generation_usi Assert.Null(selector.TrySelect(entityType.FindProperty("DateTimeOffset")!, entityType, out generator) ? generator : null); Assert.Null(selector.TrySelect(entityType.FindProperty("NullableDateTimeOffset")!, entityType, out generator) ? generator : null); - Assert.IsType(selector.TrySelect(entityType.FindProperty("String")!, entityType, out generator) ? generator : null); + Assert.IsType( + selector.TrySelect(entityType.FindProperty("String")!, entityType, out generator) ? generator : null); - Assert.IsType(selector.TrySelect(entityType.FindProperty("Guid")!, entityType, out generator) ? generator : null); - Assert.IsType(selector.TrySelect(entityType.FindProperty("NullableGuid")!, entityType, out generator) ? generator : null); + Assert.IsType( + selector.TrySelect(entityType.FindProperty("Guid")!, entityType, out generator) ? generator : null); + Assert.IsType( + selector.TrySelect(entityType.FindProperty("NullableGuid")!, entityType, out generator) ? generator : null); - Assert.IsType(selector.TrySelect(entityType.FindProperty("Binary")!, entityType, out generator) ? generator : null); + Assert.IsType( + selector.TrySelect(entityType.FindProperty("Binary")!, entityType, out generator) ? generator : null); } [ConditionalFact] diff --git a/test/EFCore.TrimmingTests/EFCore.TrimmingTests.csproj b/test/EFCore.TrimmingTests/EFCore.TrimmingTests.csproj index 03cb1f3e7a3..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 b1cf002ec0c..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 cd813a7b655..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 919bbd88c28..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 0da5603328d..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 aa4bac9747d..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/Shared/ModuleInitializer.cs b/test/Shared/ModuleInitializer.cs index 40dddc20a95..161425373e5 100644 --- a/test/Shared/ModuleInitializer.cs +++ b/test/Shared/ModuleInitializer.cs @@ -8,9 +8,7 @@ internal static class ModuleInitializer { [ModuleInitializer] internal static void Initialize() - { - InitializeLocale(); - } + => InitializeLocale(); private static void InitializeLocale() { 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 @@ - - +