diff --git a/Directory.Packages.props b/Directory.Packages.props index 2a88b69da3e..5975e2b9a33 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -36,7 +36,7 @@ - + @@ -51,14 +51,14 @@ - + - - + + diff --git a/NuGet.config b/NuGet.config index 305904c0315..b24702052c1 100644 --- a/NuGet.config +++ b/NuGet.config @@ -4,7 +4,7 @@ - + @@ -21,7 +21,7 @@ - + diff --git a/azure-pipelines-public.yml b/azure-pipelines-public.yml index d56ef44140b..85b9fbab9e4 100644 --- a/azure-pipelines-public.yml +++ b/azure-pipelines-public.yml @@ -93,7 +93,7 @@ stages: - job: macOS enablePublishTestResults: true pool: - vmImage: macOS-12 + vmImage: macOS-13 variables: # Rely on task Arcade injects, not auto-injected build step. - skipComponentGovernanceDetection: true diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 8741f1c3b71..530b57da6a1 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -139,7 +139,7 @@ extends: - job: macOS pool: name: Azure Pipelines - image: macOS-12 + image: macOS-13 os: macOS variables: # Rely on task Arcade injects, not auto-injected build step. diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 24a836cec81..3fff94bc548 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,83 +1,83 @@ - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 9d5a6a9aa463d6d10b0b0ba6d5982cc82f363dc3 + c8acea22626efab11c13778c028975acdc34678f - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 9d5a6a9aa463d6d10b0b0ba6d5982cc82f363dc3 + c8acea22626efab11c13778c028975acdc34678f - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 9d5a6a9aa463d6d10b0b0ba6d5982cc82f363dc3 + c8acea22626efab11c13778c028975acdc34678f - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 9d5a6a9aa463d6d10b0b0ba6d5982cc82f363dc3 + c8acea22626efab11c13778c028975acdc34678f - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 9d5a6a9aa463d6d10b0b0ba6d5982cc82f363dc3 + c8acea22626efab11c13778c028975acdc34678f - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 9d5a6a9aa463d6d10b0b0ba6d5982cc82f363dc3 + c8acea22626efab11c13778c028975acdc34678f - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 9d5a6a9aa463d6d10b0b0ba6d5982cc82f363dc3 + c8acea22626efab11c13778c028975acdc34678f - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 9d5a6a9aa463d6d10b0b0ba6d5982cc82f363dc3 + c8acea22626efab11c13778c028975acdc34678f - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 9d5a6a9aa463d6d10b0b0ba6d5982cc82f363dc3 + c8acea22626efab11c13778c028975acdc34678f - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 9d5a6a9aa463d6d10b0b0ba6d5982cc82f363dc3 + c8acea22626efab11c13778c028975acdc34678f - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 9d5a6a9aa463d6d10b0b0ba6d5982cc82f363dc3 + c8acea22626efab11c13778c028975acdc34678f - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 9d5a6a9aa463d6d10b0b0ba6d5982cc82f363dc3 + c8acea22626efab11c13778c028975acdc34678f - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 9d5a6a9aa463d6d10b0b0ba6d5982cc82f363dc3 + c8acea22626efab11c13778c028975acdc34678f - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 9d5a6a9aa463d6d10b0b0ba6d5982cc82f363dc3 + c8acea22626efab11c13778c028975acdc34678f - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 9d5a6a9aa463d6d10b0b0ba6d5982cc82f363dc3 + c8acea22626efab11c13778c028975acdc34678f - + https://github.com/dotnet/arcade - 3c393bbd85ae16ddddba20d0b75035b0c6f1a52d + b41381d5cd633471265e9cd72e933a7048e03062 - + https://github.com/dotnet/arcade - 3c393bbd85ae16ddddba20d0b75035b0c6f1a52d + b41381d5cd633471265e9cd72e933a7048e03062 - + https://github.com/dotnet/arcade - 3c393bbd85ae16ddddba20d0b75035b0c6f1a52d + b41381d5cd633471265e9cd72e933a7048e03062 diff --git a/eng/Versions.props b/eng/Versions.props index 858be25e405..dc4ee10c83a 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -1,6 +1,6 @@ - 9.0.0 + 9.0.1 rtm @@ -17,24 +17,24 @@ False - 9.0.0 - 9.0.0 - 9.0.0 - 9.0.0 - 9.0.0 - 9.0.0 - 9.0.0 - 9.0.0-rtm.24528.9 - 9.0.0 - 9.0.0 - 9.0.0 - 9.0.0-rtm.24528.9 - 9.0.0 - 9.0.0 - 9.0.0 + 9.0.1 + 9.0.1 + 9.0.1 + 9.0.1 + 9.0.1 + 9.0.1 + 9.0.1 + 9.0.1-servicing.24610.10 + 9.0.1 + 9.0.1 + 9.0.1 + 9.0.1-servicing.24610.10 + 9.0.1 + 9.0.1 + 9.0.1 - 9.0.0-beta.24516.2 + 9.0.0-beta.24572.2 17.8.3 diff --git a/eng/common/sdk-task.ps1 b/eng/common/sdk-task.ps1 index aab40de3fd9..4f0546dce12 100644 --- a/eng/common/sdk-task.ps1 +++ b/eng/common/sdk-task.ps1 @@ -64,7 +64,7 @@ try { $GlobalJson.tools | Add-Member -Name "vs" -Value (ConvertFrom-Json "{ `"version`": `"16.5`" }") -MemberType NoteProperty } if( -not ($GlobalJson.tools.PSObject.Properties.Name -match "xcopy-msbuild" )) { - $GlobalJson.tools | Add-Member -Name "xcopy-msbuild" -Value "17.10.0-pre.4.0" -MemberType NoteProperty + $GlobalJson.tools | Add-Member -Name "xcopy-msbuild" -Value "17.12.0" -MemberType NoteProperty } if ($GlobalJson.tools."xcopy-msbuild".Trim() -ine "none") { $xcopyMSBuildToolsFolder = InitializeXCopyMSBuild $GlobalJson.tools."xcopy-msbuild" -install $true diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index 22954477a57..aa94fb17459 100644 --- a/eng/common/tools.ps1 +++ b/eng/common/tools.ps1 @@ -383,8 +383,8 @@ function InitializeVisualStudioMSBuild([bool]$install, [object]$vsRequirements = # If the version of msbuild is going to be xcopied, # use this version. Version matches a package here: - # https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/Microsoft.DotNet.Arcade.MSBuild.Xcopy/versions/17.10.0-pre.4.0 - $defaultXCopyMSBuildVersion = '17.10.0-pre.4.0' + # https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/Microsoft.DotNet.Arcade.MSBuild.Xcopy/versions/17.12.0 + $defaultXCopyMSBuildVersion = '17.12.0' if (!$vsRequirements) { if (Get-Member -InputObject $GlobalJson.tools -Name 'vs') { diff --git a/global.json b/global.json index 9cf9fded9e5..90650c26b0b 100644 --- a/global.json +++ b/global.json @@ -1,11 +1,11 @@ { "sdk": { - "version": "9.0.100-rc.2.24474.11", + "version": "9.0.100", "allowPrerelease": true, "rollForward": "latestMajor" }, "tools": { - "dotnet": "9.0.100-rc.2.24474.11", + "dotnet": "9.0.100", "runtimes": { "dotnet": [ "$(MicrosoftNETCoreBrowserDebugHostTransportVersion)" @@ -13,7 +13,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24516.2", - "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24516.2" + "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24572.2", + "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24572.2" } } diff --git a/src/EFCore.Cosmos/Extensions/DistanceFunction.cs b/src/EFCore.Cosmos/Extensions/DistanceFunction.cs deleted file mode 100644 index 2df582e5ca1..00000000000 --- a/src/EFCore.Cosmos/Extensions/DistanceFunction.cs +++ /dev/null @@ -1,36 +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 System.Diagnostics.CodeAnalysis; -using System.Runtime.Serialization; - -// ReSharper disable once CheckNamespace -namespace Microsoft.Azure.Cosmos; - -/// -/// Defines the distance function for a vector index specification in the Azure Cosmos DB service. -/// Warning: this type will be replaced by the type from the Cosmos SDK, when it is available. -/// -/// -/// for usage. -[Experimental(EFDiagnostics.CosmosVectorSearchExperimental)] -public enum DistanceFunction -{ - /// - /// Represents the Euclidean distance function. - /// - [EnumMember(Value = "euclidean")] - Euclidean, - - /// - /// Represents the cosine distance function. - /// - [EnumMember(Value = "cosine")] - Cosine, - - /// - /// Represents the dot product distance function. - /// - [EnumMember(Value = "dotproduct")] - DotProduct, -} diff --git a/src/EFCore.Cosmos/Extensions/Embedding.cs b/src/EFCore.Cosmos/Extensions/Embedding.cs deleted file mode 100644 index e46c274d887..00000000000 --- a/src/EFCore.Cosmos/Extensions/Embedding.cs +++ /dev/null @@ -1,19 +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 System.Diagnostics.CodeAnalysis; - -// ReSharper disable once CheckNamespace -namespace Microsoft.Azure.Cosmos; - -[Experimental(EFDiagnostics.CosmosVectorSearchExperimental)] -internal class Embedding : IEquatable -{ - public string? Path { get; set; } - 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/Extensions/VectorDataType.cs b/src/EFCore.Cosmos/Extensions/VectorDataType.cs deleted file mode 100644 index cb547fd1b3a..00000000000 --- a/src/EFCore.Cosmos/Extensions/VectorDataType.cs +++ /dev/null @@ -1,40 +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 System.Diagnostics.CodeAnalysis; -using System.Runtime.Serialization; - -// ReSharper disable once CheckNamespace -namespace Microsoft.Azure.Cosmos; - -/// -/// Defines the target data type of a vector index specification in the Azure Cosmos DB service. -/// Warning: this type will be replaced by the type from the Cosmos SDK, when it is available. -/// -[Experimental(EFDiagnostics.CosmosVectorSearchExperimental)] -public enum VectorDataType -{ - /// - /// Represents a 16-bit floating point data type. - /// - [EnumMember(Value = "float16")] - Float16, - - /// - /// Represents a 32-bit floating point data type. - /// - [EnumMember(Value = "float32")] - Float32, - - /// - /// Represents an unsigned 8-bit binary data type. - /// - [EnumMember(Value = "uint8")] - Uint8, - - /// - /// Represents a signed 8-bit binary data type. - /// - [EnumMember(Value = "int8")] - Int8, -} diff --git a/src/EFCore.Cosmos/Extensions/VectorIndexPath.cs b/src/EFCore.Cosmos/Extensions/VectorIndexPath.cs deleted file mode 100644 index 8a575c2c40f..00000000000 --- a/src/EFCore.Cosmos/Extensions/VectorIndexPath.cs +++ /dev/null @@ -1,14 +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 System.Diagnostics.CodeAnalysis; - -// ReSharper disable once CheckNamespace -namespace Microsoft.Azure.Cosmos; - -[Experimental(EFDiagnostics.CosmosVectorSearchExperimental)] -internal sealed class VectorIndexPath -{ - public string? Path { get; set; } - public VectorIndexType Type { get; set; } -} diff --git a/src/EFCore.Cosmos/Extensions/VectorIndexType.cs b/src/EFCore.Cosmos/Extensions/VectorIndexType.cs deleted file mode 100644 index 88f71d32a5d..00000000000 --- a/src/EFCore.Cosmos/Extensions/VectorIndexType.cs +++ /dev/null @@ -1,35 +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 System.Diagnostics.CodeAnalysis; -using System.Runtime.Serialization; - -// ReSharper disable once CheckNamespace -namespace Microsoft.Azure.Cosmos; - -/// -/// Defines the target index type of the vector index path specification in the Azure Cosmos DB service. -/// Warning: this type will be replaced by the type from the Cosmos SDK, when it is available. -/// -[Experimental(EFDiagnostics.CosmosVectorSearchExperimental)] -public enum VectorIndexType -{ - /// - /// Represents a flat vector index type. - /// - [EnumMember(Value = "flat")] - Flat, - - /// - /// Represents a Disk ANN vector index type. - /// - [EnumMember(Value = "diskANN")] - // ReSharper disable once InconsistentNaming - DiskANN, - - /// - /// Represents a quantized flat vector index type. - /// - [EnumMember(Value = "quantizedFlat")] - QuantizedFlat, -} diff --git a/src/EFCore.Cosmos/Properties/CosmosStrings.Designer.cs b/src/EFCore.Cosmos/Properties/CosmosStrings.Designer.cs index d9571fc2d05..6c63a1c718e 100644 --- a/src/EFCore.Cosmos/Properties/CosmosStrings.Designer.cs +++ b/src/EFCore.Cosmos/Properties/CosmosStrings.Designer.cs @@ -305,12 +305,6 @@ public static string NoReadItemQueryString(object? resourceId, object? partition public static string NoSubqueryPushdown => GetString("NoSubqueryPushdown"); - /// - /// Container configuration for embeddings is not yet supported by the Cosmos SDK. Instead, configure the container manually. See https://aka.ms/ef-cosmos-vectors for more information. - /// - public static string NoVectorContainerConfig - => GetString("NoVectorContainerConfig"); - /// /// The expression '{sqlExpression}' in the SQL tree does not have a type mapping assigned. /// diff --git a/src/EFCore.Cosmos/Properties/CosmosStrings.resx b/src/EFCore.Cosmos/Properties/CosmosStrings.resx index 171d85f852c..8f9a875524b 100644 --- a/src/EFCore.Cosmos/Properties/CosmosStrings.resx +++ b/src/EFCore.Cosmos/Properties/CosmosStrings.resx @@ -271,9 +271,6 @@ Azure Cosmos DB does not have an appropriate subquery for this translation. - - Container configuration for embeddings is not yet supported by the Cosmos SDK. Instead, configure the container manually. See https://aka.ms/ef-cosmos-vectors for more information. - The expression '{sqlExpression}' in the SQL tree does not have a type mapping assigned. diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitor.cs b/src/EFCore.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitor.cs index 9b446a78152..7ad49bd00c4 100644 --- a/src/EFCore.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitor.cs +++ b/src/EFCore.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitor.cs @@ -16,6 +16,9 @@ namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal; /// public class CosmosQueryableMethodTranslatingExpressionVisitor : QueryableMethodTranslatingExpressionVisitor { + private static readonly bool UseOldBehavior35094 = + AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue35094", out var enabled) && enabled; + private readonly CosmosQueryCompilationContext _queryCompilationContext; private readonly ISqlExpressionFactory _sqlExpressionFactory; private readonly ITypeMappingSource _typeMappingSource; @@ -445,23 +448,29 @@ private ShapedQueryExpression CreateShapedQueryExpression(SelectExpression selec /// protected override ShapedQueryExpression? TranslateAverage(ShapedQueryExpression source, LambdaExpression? selector, Type resultType) { - var selectExpression = (SelectExpression)source.QueryExpression; - if (selectExpression.IsDistinct - || selectExpression.Limit != null - || selectExpression.Offset != null) + if (UseOldBehavior35094) { - return null; - } + var selectExpression = (SelectExpression)source.QueryExpression; + if (selectExpression.IsDistinct + || selectExpression.Limit != null + || selectExpression.Offset != null) + { + return null; + } - if (selector != null) - { - source = TranslateSelect(source, selector); - } + if (selector != null) + { + source = TranslateSelect(source, selector); + } - var projection = (SqlExpression)selectExpression.GetMappedProjection(new ProjectionMember()); - projection = _sqlExpressionFactory.Function("AVG", new[] { projection }, projection.Type, projection.TypeMapping); + var projection = (SqlExpression)selectExpression.GetMappedProjection(new ProjectionMember()); + projection = _sqlExpressionFactory.Function("AVG", new[] { projection }, projection.Type, projection.TypeMapping); - return AggregateResultShaper(source, projection, throwOnNullResult: true, resultType); + return AggregateResultShaper(source, projection, throwOnNullResult: true, resultType); + + } + + return TranslateAggregate(source, selector, resultType, "AVG"); } /// @@ -843,24 +852,29 @@ protected override ShapedQueryExpression TranslateCast(ShapedQueryExpression sou /// protected override ShapedQueryExpression? TranslateMax(ShapedQueryExpression source, LambdaExpression? selector, Type resultType) { - var selectExpression = (SelectExpression)source.QueryExpression; - if (selectExpression.IsDistinct - || selectExpression.Limit != null - || selectExpression.Offset != null) + if (UseOldBehavior35094) { - return null; - } + var selectExpression = (SelectExpression)source.QueryExpression; + if (selectExpression.IsDistinct + || selectExpression.Limit != null + || selectExpression.Offset != null) + { + return null; + } - if (selector != null) - { - source = TranslateSelect(source, selector); - } + if (selector != null) + { + source = TranslateSelect(source, selector); + } - var projection = (SqlExpression)selectExpression.GetMappedProjection(new ProjectionMember()); + var projection = (SqlExpression)selectExpression.GetMappedProjection(new ProjectionMember()); - projection = _sqlExpressionFactory.Function("MAX", new[] { projection }, resultType, projection.TypeMapping); + projection = _sqlExpressionFactory.Function("MAX", new[] { projection }, resultType, projection.TypeMapping); - return AggregateResultShaper(source, projection, throwOnNullResult: true, resultType); + return AggregateResultShaper(source, projection, throwOnNullResult: true, resultType); + } + + return TranslateAggregate(source, selector, resultType, "MAX"); } /// @@ -871,24 +885,29 @@ protected override ShapedQueryExpression TranslateCast(ShapedQueryExpression sou /// protected override ShapedQueryExpression? TranslateMin(ShapedQueryExpression source, LambdaExpression? selector, Type resultType) { - var selectExpression = (SelectExpression)source.QueryExpression; - if (selectExpression.IsDistinct - || selectExpression.Limit != null - || selectExpression.Offset != null) + if (UseOldBehavior35094) { - return null; - } + var selectExpression = (SelectExpression)source.QueryExpression; + if (selectExpression.IsDistinct + || selectExpression.Limit != null + || selectExpression.Offset != null) + { + return null; + } - if (selector != null) - { - source = TranslateSelect(source, selector); - } + if (selector != null) + { + source = TranslateSelect(source, selector); + } - var projection = (SqlExpression)selectExpression.GetMappedProjection(new ProjectionMember()); + var projection = (SqlExpression)selectExpression.GetMappedProjection(new ProjectionMember()); - projection = _sqlExpressionFactory.Function("MIN", new[] { projection }, resultType, projection.TypeMapping); + projection = _sqlExpressionFactory.Function("MIN", new[] { projection }, resultType, projection.TypeMapping); - return AggregateResultShaper(source, projection, throwOnNullResult: true, resultType); + return AggregateResultShaper(source, projection, throwOnNullResult: true, resultType); + } + + return TranslateAggregate(source, selector, resultType, "MIN"); } /// @@ -1520,6 +1539,35 @@ protected override ShapedQueryExpression TranslateSelect(ShapedQueryExpression s #endregion Queryable collection support + private ShapedQueryExpression? TranslateAggregate(ShapedQueryExpression source, LambdaExpression? selector, Type resultType, string functionName) + { + var selectExpression = (SelectExpression)source.QueryExpression; + if (selectExpression.IsDistinct + || selectExpression.Limit != null + || selectExpression.Offset != null) + { + return null; + } + + if (selector != null) + { + source = TranslateSelect(source, selector); + } + + if (!_subquery && resultType.IsNullableType()) + { + // For nullable types, we want to return null from Max, Min, and Average, rather than throwing. See Issue #35094. + // Note that relational databases typically return null, which propagates. Cosmos will instead return no elements, + // and hence for Cosmos only we need to change no elements into null. + source = source.UpdateResultCardinality(ResultCardinality.SingleOrDefault); + } + + var projection = (SqlExpression)selectExpression.GetMappedProjection(new ProjectionMember()); + projection = _sqlExpressionFactory.Function(functionName, [projection], resultType, _typeMappingSource.FindMapping(resultType)); + + return AggregateResultShaper(source, projection, throwOnNullResult: true, resultType); + } + private bool TryApplyPredicate(ShapedQueryExpression source, LambdaExpression predicate) { var select = (SelectExpression)source.QueryExpression; diff --git a/src/EFCore.Cosmos/Storage/Internal/CosmosClientWrapper.cs b/src/EFCore.Cosmos/Storage/Internal/CosmosClientWrapper.cs index a5c89b6b37d..9f2793deeaa 100644 --- a/src/EFCore.Cosmos/Storage/Internal/CosmosClientWrapper.cs +++ b/src/EFCore.Cosmos/Storage/Internal/CosmosClientWrapper.cs @@ -272,17 +272,14 @@ private static async Task CreateContainerIfNotExistsOnceAsync( AnalyticalStoreTimeToLiveInSeconds = parameters.AnalyticalStoreTimeToLiveInSeconds, }; - // TODO: Enable these once they are available in the Cosmos SDK. See #33783. if (embeddings.Any()) { - throw new InvalidOperationException(CosmosStrings.NoVectorContainerConfig); - //containerProperties.VectorEmbeddingPolicy = new VectorEmbeddingPolicy(embeddings); + containerProperties.VectorEmbeddingPolicy = new VectorEmbeddingPolicy(embeddings); } if (vectorIndexes.Any()) { - throw new InvalidOperationException(CosmosStrings.NoVectorContainerConfig); - //containerProperties.IndexingPolicy = new IndexingPolicy { VectorIndexes = vectorIndexes }; + containerProperties.IndexingPolicy = new IndexingPolicy { VectorIndexes = vectorIndexes }; } var response = await wrapper.Client.GetDatabase(wrapper._databaseId).CreateContainerIfNotExistsAsync( diff --git a/src/EFCore.Design/Design/Internal/AppServiceProviderFactory.cs b/src/EFCore.Design/Design/Internal/AppServiceProviderFactory.cs index 2015337b4e6..b797f8a4add 100644 --- a/src/EFCore.Design/Design/Internal/AppServiceProviderFactory.cs +++ b/src/EFCore.Design/Design/Internal/AppServiceProviderFactory.cs @@ -55,23 +55,6 @@ public virtual IServiceProvider Create(string[] args) return null; } - var aspnetCoreEnvironment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"); - var dotnetEnvironment = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT"); - var environment = aspnetCoreEnvironment - ?? dotnetEnvironment - ?? "Development"; - if (aspnetCoreEnvironment == null) - { - Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", environment); - } - - if (dotnetEnvironment == null) - { - Environment.SetEnvironmentVariable("DOTNET_ENVIRONMENT", environment); - } - - _reporter.WriteVerbose(DesignStrings.UsingEnvironment(environment)); - try { var services = serviceProviderFactory(args); diff --git a/src/EFCore.Design/Design/Internal/DbContextOperations.cs b/src/EFCore.Design/Design/Internal/DbContextOperations.cs index da44b15b283..761579c8bdb 100644 --- a/src/EFCore.Design/Design/Internal/DbContextOperations.cs +++ b/src/EFCore.Design/Design/Internal/DbContextOperations.cs @@ -503,6 +503,23 @@ private IDictionary> FindContextTypes(string? name = null, { _reporter.WriteVerbose(DesignStrings.FindingContexts); + var aspnetCoreEnvironment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"); + var dotnetEnvironment = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT"); + var environment = aspnetCoreEnvironment + ?? dotnetEnvironment + ?? "Development"; + if (aspnetCoreEnvironment == null) + { + Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", environment); + } + + if (dotnetEnvironment == null) + { + Environment.SetEnvironmentVariable("DOTNET_ENVIRONMENT", environment); + } + + _reporter.WriteVerbose(DesignStrings.UsingEnvironment(environment)); + var contexts = new Dictionary?>(); try diff --git a/src/EFCore.Relational/Diagnostics/RelationalEventId.cs b/src/EFCore.Relational/Diagnostics/RelationalEventId.cs index c05c73c46a3..0b1f48c5275 100644 --- a/src/EFCore.Relational/Diagnostics/RelationalEventId.cs +++ b/src/EFCore.Relational/Diagnostics/RelationalEventId.cs @@ -81,6 +81,7 @@ private enum Id NonTransactionalMigrationOperationWarning, AcquiringMigrationLock, MigrationsUserTransactionWarning, + ModelSnapshotNotFound, // Query events QueryClientEvaluationWarning = CoreEventId.RelationalBaseId + 500, @@ -778,6 +779,19 @@ private static EventId MakeMigrationsId(Id id) /// public static readonly EventId MigrationsUserTransactionWarning = MakeMigrationsId(Id.MigrationsUserTransactionWarning); + /// + /// Model snapshot was not found. + /// + /// + /// + /// This event is in the category. + /// + /// + /// This event uses the payload when used with a . + /// + /// + public static readonly EventId ModelSnapshotNotFound = MakeMigrationsId(Id.ModelSnapshotNotFound); + private static readonly string _queryPrefix = DbLoggerCategory.Query.Name + "."; private static EventId MakeQueryId(Id id) diff --git a/src/EFCore.Relational/Diagnostics/RelationalLoggerExtensions.cs b/src/EFCore.Relational/Diagnostics/RelationalLoggerExtensions.cs index 177b7e90bba..acecc79ca01 100644 --- a/src/EFCore.Relational/Diagnostics/RelationalLoggerExtensions.cs +++ b/src/EFCore.Relational/Diagnostics/RelationalLoggerExtensions.cs @@ -2343,6 +2343,77 @@ private static string PendingModelChanges(EventDefinitionBase definition, EventD return d.GenerateMessage(p.ContextType.ShortDisplayName()); } + /// + /// Logs for the event. + /// + /// The diagnostics logger to use. + /// The type being used. + public static void NonDeterministicModel( + this IDiagnosticsLogger diagnostics, + Type contextType) + { + var definition = RelationalResources.LogNonDeterministicModel(diagnostics); + + if (diagnostics.ShouldLog(definition)) + { + definition.Log(diagnostics, contextType.ShortDisplayName()); + } + + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) + { + var eventData = new DbContextTypeEventData( + definition, + NonDeterministicModel, + contextType); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); + } + } + + private static string NonDeterministicModel(EventDefinitionBase definition, EventData payload) + { + var d = (EventDefinition)definition; + var p = (DbContextTypeEventData)payload; + return d.GenerateMessage(p.ContextType.ShortDisplayName()); + } + + /// + /// Logs for the event. + /// + /// The diagnostics logger to use. + /// The migrator. + /// The assembly in which migrations are stored. + public static void ModelSnapshotNotFound( + this IDiagnosticsLogger diagnostics, + IMigrator migrator, + IMigrationsAssembly migrationsAssembly) + { + var definition = RelationalResources.LogNoModelSnapshotFound(diagnostics); + + if (diagnostics.ShouldLog(definition)) + { + definition.Log(diagnostics, migrationsAssembly.Assembly.GetName().Name!); + } + + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) + { + var eventData = new MigrationAssemblyEventData( + definition, + ModelSnapshotNotFound, + migrator, + migrationsAssembly); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); + } + } + + private static string ModelSnapshotNotFound(EventDefinitionBase definition, EventData payload) + { + var d = (EventDefinition)definition; + var p = (MigrationAssemblyEventData)payload; + return d.GenerateMessage(p.MigrationsAssembly.Assembly.GetName().Name!); + } + /// /// Logs for the event. /// diff --git a/src/EFCore.Relational/Diagnostics/RelationalLoggingDefinitions.cs b/src/EFCore.Relational/Diagnostics/RelationalLoggingDefinitions.cs index 762172c8944..9634f027bf7 100644 --- a/src/EFCore.Relational/Diagnostics/RelationalLoggingDefinitions.cs +++ b/src/EFCore.Relational/Diagnostics/RelationalLoggingDefinitions.cs @@ -374,7 +374,7 @@ public abstract class RelationalLoggingDefinitions : LoggingDefinitions /// doing so can result in application failures when updating to a new Entity Framework Core release. /// [EntityFrameworkInternal] - public EventDefinitionBase? LogMigrationsUserTransactionWarning; + public EventDefinitionBase? LogMigrationsUserTransaction; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -673,6 +673,24 @@ public abstract class RelationalLoggingDefinitions : LoggingDefinitions [EntityFrameworkInternal] public EventDefinitionBase? LogPendingModelChanges; + /// + /// 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? LogNonDeterministicModel; + + /// + /// 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? LogNoModelSnapshotFound; + /// /// 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/Migrations/HistoryRepository.cs b/src/EFCore.Relational/Migrations/HistoryRepository.cs index 3c1c1b2304e..9aa9d933f9a 100644 --- a/src/EFCore.Relational/Migrations/HistoryRepository.cs +++ b/src/EFCore.Relational/Migrations/HistoryRepository.cs @@ -219,8 +219,7 @@ async Task IHistoryRepository.CreateIfNotExistsAsync(CancellationToken can private IReadOnlyList GetCreateIfNotExistsCommands() => Dependencies.MigrationsSqlGenerator.Generate([new SqlOperation { - Sql = GetCreateIfNotExistsScript(), - SuppressTransaction = true + Sql = GetCreateIfNotExistsScript() }]); /// diff --git a/src/EFCore.Relational/Migrations/Internal/Migrator.cs b/src/EFCore.Relational/Migrations/Internal/Migrator.cs index 4380d89fd82..ea758d2c634 100644 --- a/src/EFCore.Relational/Migrations/Internal/Migrator.cs +++ b/src/EFCore.Relational/Migrations/Internal/Migrator.cs @@ -3,6 +3,7 @@ using System.Transactions; using Microsoft.EntityFrameworkCore.Diagnostics.Internal; +using Microsoft.EntityFrameworkCore.Metadata.Internal; namespace Microsoft.EntityFrameworkCore.Migrations.Internal; @@ -93,24 +94,7 @@ public Migrator( 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); + ValidateMigrations(useTransaction); using var transactionScope = new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled); @@ -235,24 +219,7 @@ public virtual async Task MigrateAsync( 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); + ValidateMigrations(useTransaction); using var transactionScope = new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled); @@ -382,6 +349,48 @@ await _migrationCommandExecutor.ExecuteNonQueryAsync( } } + private void ValidateMigrations(bool useTransaction) + { + if (!useTransaction + && _executionStrategy.RetriesOnFailure) + { + throw new NotSupportedException(RelationalStrings.TransactionSuppressedMigrationInUserTransaction); + } + + if (_migrationsAssembly.Migrations.Count == 0) + { + _logger.MigrationsNotFound(this, _migrationsAssembly); + } + else if (_migrationsAssembly.ModelSnapshot == null) + { + _logger.ModelSnapshotNotFound(this, _migrationsAssembly); + } + else if (RelationalResources.LogPendingModelChanges(_logger).WarningBehavior != WarningBehavior.Ignore + && HasPendingModelChanges()) + { + var modelSource = (ModelSource)_currentContext.Context.GetService(); +#pragma warning disable EF1001 // Internal EF Core API usage. + var newDesignTimeModel = modelSource.CreateModel( + _currentContext.Context, _currentContext.Context.GetService(), designTime: true); +#pragma warning restore EF1001 // Internal EF Core API usage. + if (_migrationsModelDiffer.HasDifferences(newDesignTimeModel.GetRelationalModel(), _designTimeModel.Model.GetRelationalModel())) + { + _logger.NonDeterministicModel(_currentContext.Context.GetType()); + } + else + { + _logger.PendingModelChangesWarning(_currentContext.Context.GetType()); + } + } + + if (!useTransaction) + { + _logger.MigrationsUserTransactionWarning(); + } + + _logger.MigrateUsingConnection(this, _connection); + } + private IEnumerable<(string, Func>)> GetMigrationCommandLists(MigratorData parameters) { var migrationsToApply = parameters.AppliedMigrations; @@ -449,10 +458,6 @@ protected virtual void PopulateMigrations( var appliedMigrations = new Dictionary(); var unappliedMigrations = new Dictionary(); var appliedMigrationEntrySet = new HashSet(appliedMigrationEntries, StringComparer.OrdinalIgnoreCase); - if (_migrationsAssembly.Migrations.Count == 0) - { - _logger.MigrationsNotFound(this, _migrationsAssembly); - } foreach (var (key, typeInfo) in _migrationsAssembly.Migrations) { diff --git a/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs b/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs index 731c62c4ec2..5bbbd42c9d0 100644 --- a/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs +++ b/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs @@ -3429,11 +3429,11 @@ public static EventDefinition LogMigrationAttributeMissingWarning(IDiagn /// public static EventDefinition LogMigrationsUserTransaction(IDiagnosticsLogger logger) { - var definition = ((RelationalLoggingDefinitions)logger.Definitions).LogMigrationsUserTransactionWarning; + var definition = ((RelationalLoggingDefinitions)logger.Definitions).LogMigrationsUserTransaction; if (definition == null) { definition = NonCapturingLazyInitializer.EnsureInitialized( - ref ((RelationalLoggingDefinitions)logger.Definitions).LogMigrationsUserTransactionWarning, + ref ((RelationalLoggingDefinitions)logger.Definitions).LogMigrationsUserTransaction, logger, static logger => new EventDefinition( logger.Options, @@ -3572,7 +3572,7 @@ public static EventDefinition LogNoMigrationsApplied(IDiagnosticsLogger logger) } /// - /// No migrations were found in assembly '{migrationsAssembly}'. + /// No migrations were found in assembly '{migrationsAssembly}'. A migration needs to be added before the database can be updated. /// public static EventDefinition LogNoMigrationsFound(IDiagnosticsLogger logger) { @@ -3585,7 +3585,7 @@ public static EventDefinition LogNoMigrationsFound(IDiagnosticsLogger lo static logger => new EventDefinition( logger.Options, RelationalEventId.MigrationsNotFound, - LogLevel.Debug, + LogLevel.Information, "RelationalEventId.MigrationsNotFound", level => LoggerMessage.Define( level, @@ -3596,6 +3596,56 @@ public static EventDefinition LogNoMigrationsFound(IDiagnosticsLogger lo return (EventDefinition)definition; } + /// + /// Model snapshot was not found in assembly '{migrationsAssembly}'. Skipping pending model changes check. + /// + public static EventDefinition LogNoModelSnapshotFound(IDiagnosticsLogger logger) + { + var definition = ((RelationalLoggingDefinitions)logger.Definitions).LogNoModelSnapshotFound; + if (definition == null) + { + definition = NonCapturingLazyInitializer.EnsureInitialized( + ref ((RelationalLoggingDefinitions)logger.Definitions).LogNoModelSnapshotFound, + logger, + static logger => new EventDefinition( + logger.Options, + RelationalEventId.ModelSnapshotNotFound, + LogLevel.Information, + "RelationalEventId.ModelSnapshotNotFound", + level => LoggerMessage.Define( + level, + RelationalEventId.ModelSnapshotNotFound, + _resourceManager.GetString("LogNoModelSnapshotFound")!))); + } + + return (EventDefinition)definition; + } + + /// + /// The model for context '{contextType}' changes each time it is built. This is usually caused by dynamic values used in a 'HasData' call (e.g. `new DateTime()`, `Guid.NewGuid()`). Add a new migration and examine its contents to locate the cause, and replace the dynamic call with a static, hardcoded value. See https://aka.ms/efcore-docs-pending-changes. + /// + public static EventDefinition LogNonDeterministicModel(IDiagnosticsLogger logger) + { + var definition = ((RelationalLoggingDefinitions)logger.Definitions).LogNonDeterministicModel; + if (definition == null) + { + definition = NonCapturingLazyInitializer.EnsureInitialized( + ref ((RelationalLoggingDefinitions)logger.Definitions).LogNonDeterministicModel, + logger, + static logger => new EventDefinition( + logger.Options, + RelationalEventId.PendingModelChangesWarning, + LogLevel.Error, + "RelationalEventId.PendingModelChangesWarning", + level => LoggerMessage.Define( + level, + RelationalEventId.PendingModelChangesWarning, + _resourceManager.GetString("LogNonDeterministicModel")!))); + } + + return (EventDefinition)definition; + } + /// /// The migration operation '{operation}' from migration '{migration}' cannot be executed in a transaction. If the app is terminated or an unrecoverable error occurs while this operation is being executed then the migration will be left in a partially applied state and would need to be reverted manually before it can be applied again. Create a separate migration that contains just this operation. /// @@ -3610,7 +3660,7 @@ public static EventDefinition LogNonTransactionalMigrationOperat static logger => new EventDefinition( logger.Options, RelationalEventId.NonTransactionalMigrationOperationWarning, - LogLevel.Error, + LogLevel.Warning, "RelationalEventId.NonTransactionalMigrationOperationWarning", level => LoggerMessage.Define( level, @@ -3747,7 +3797,7 @@ public static EventDefinition LogOptionalDependentWithoutIdentifyingProp } /// - /// The model for context '{contextType}' has pending changes. Add a new migration before updating the database. + /// The model for context '{contextType}' has pending changes. Add a new migration before updating the database. See https://aka.ms/efcore-docs-pending-changes. /// public static EventDefinition LogPendingModelChanges(IDiagnosticsLogger logger) { diff --git a/src/EFCore.Relational/Properties/RelationalStrings.resx b/src/EFCore.Relational/Properties/RelationalStrings.resx index 104daf9dafb..2382f648428 100644 --- a/src/EFCore.Relational/Properties/RelationalStrings.resx +++ b/src/EFCore.Relational/Properties/RelationalStrings.resx @@ -811,12 +811,20 @@ Information RelationalEventId.MigrationsNotApplied - No migrations were found in assembly '{migrationsAssembly}'. - Debug RelationalEventId.MigrationsNotFound string + No migrations were found in assembly '{migrationsAssembly}'. A migration needs to be added before the database can be updated. + Information RelationalEventId.MigrationsNotFound string + + + Model snapshot was not found in assembly '{migrationsAssembly}'. Skipping pending model changes check. + Information RelationalEventId.ModelSnapshotNotFound string + + + The model for context '{contextType}' changes each time it is built. This is usually caused by dynamic values used in a 'HasData' call (e.g. `new DateTime()`, `Guid.NewGuid()`). Add a new migration and examine its contents to locate the cause, and replace the dynamic call with a static, hardcoded value. See https://aka.ms/efcore-docs-pending-changes. + Error RelationalEventId.PendingModelChangesWarning string The migration operation '{operation}' from migration '{migration}' cannot be executed in a transaction. If the app is terminated or an unrecoverable error occurs while this operation is being executed then the migration will be left in a partially applied state and would need to be reverted manually before it can be applied again. Create a separate migration that contains just this operation. - Error RelationalEventId.NonTransactionalMigrationOperationWarning string string + Warning RelationalEventId.NonTransactionalMigrationOperationWarning string string Opened connection to database '{database}' on server '{server}'. @@ -839,7 +847,7 @@ Warning RelationalEventId.OptionalDependentWithoutIdentifyingPropertyWarning string - The model for context '{contextType}' has pending changes. Add a new migration before updating the database. + The model for context '{contextType}' has pending changes. Add a new migration before updating the database. See https://aka.ms/efcore-docs-pending-changes. Error RelationalEventId.PendingModelChangesWarning string diff --git a/src/EFCore.Relational/Query/RelationalLiftableConstantProcessor.cs b/src/EFCore.Relational/Query/RelationalLiftableConstantProcessor.cs index 2d0b9fa8c0c..32445d46a71 100644 --- a/src/EFCore.Relational/Query/RelationalLiftableConstantProcessor.cs +++ b/src/EFCore.Relational/Query/RelationalLiftableConstantProcessor.cs @@ -36,7 +36,7 @@ protected override ConstantExpression InlineConstant(LiftableConstantExpression if (liftableConstant.ResolverExpression is Expression> resolverExpression) { - var resolver = resolverExpression.Compile(preferInterpretation: true); + var resolver = resolverExpression.Compile(preferInterpretation: UseOldBehavior35208); var value = resolver(_relationalMaterializerLiftableConstantContext); return Expression.Constant(value, liftableConstant.Type); } diff --git a/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.cs b/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.cs index 60b910af18a..1f8da845072 100644 --- a/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.cs +++ b/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.cs @@ -24,6 +24,9 @@ public partial class RelationalShapedQueryCompilingExpressionVisitor /// public sealed partial class ShaperProcessingExpressionVisitor : ExpressionVisitor { + private static readonly bool UseOldBehavior35212 = + AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue35212", out var enabled35212) && enabled35212; + /// /// Reading database values /// @@ -858,16 +861,46 @@ when GetProjectionIndex(collectionResultExpression.ProjectionBindingExpression) QueryCompilationContext.QueryContextParameter, _dataReaderParameter); + var parentIdentifierExpression = UseOldBehavior35212 + ? parentIdentifierLambda + : _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant( + parentIdentifierLambda.Compile(), + Lambda>( + parentIdentifierLambda, + Parameter(typeof(MaterializerLiftableConstantContext), "_")), + "parentIdentifierLambda", + typeof(Func)); + var outerIdentifierLambda = Lambda( Visit(relationalCollectionShaperExpression.OuterIdentifier), QueryCompilationContext.QueryContextParameter, _dataReaderParameter); + var outerIdentifierExpression = UseOldBehavior35212 + ? outerIdentifierLambda + : _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant( + outerIdentifierLambda.Compile(), + Lambda>( + outerIdentifierLambda, + Parameter(typeof(MaterializerLiftableConstantContext), "_")), + "outerIdentifierLambda", + typeof(Func)); + var selfIdentifierLambda = Lambda( Visit(relationalCollectionShaperExpression.SelfIdentifier), QueryCompilationContext.QueryContextParameter, _dataReaderParameter); + var selfIdentifierExpression = UseOldBehavior35212 + ? selfIdentifierLambda + : _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant( + selfIdentifierLambda.Compile(), + Lambda>( + selfIdentifierLambda, + Parameter(typeof(MaterializerLiftableConstantContext), "_")), + "selfIdentifierLambda", + typeof(Func)); + _inline = false; _includeExpressions.Add( @@ -878,8 +911,8 @@ when GetProjectionIndex(collectionResultExpression.ProjectionBindingExpression) _dataReaderParameter, _resultCoordinatorParameter, entity, - parentIdentifierLambda, - outerIdentifierLambda, + parentIdentifierExpression, + outerIdentifierExpression, _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant( navigation, LiftableConstantExpressionHelpers.BuildNavigationAccessLambda(navigation), @@ -907,9 +940,9 @@ when GetProjectionIndex(collectionResultExpression.ProjectionBindingExpression) QueryCompilationContext.QueryContextParameter, _dataReaderParameter, _resultCoordinatorParameter, - parentIdentifierLambda, - outerIdentifierLambda, - selfIdentifierLambda, + parentIdentifierExpression, + outerIdentifierExpression, + selfIdentifierExpression, _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant( relationalCollectionShaperExpression.ParentIdentifierValueComparers .Select(x => (Func)x.Equals).ToArray(), @@ -982,6 +1015,16 @@ when GetProjectionIndex(collectionResultExpression.ProjectionBindingExpression) QueryCompilationContext.QueryContextParameter, _dataReaderParameter); + var parentIdentifierExpression = UseOldBehavior35212 + ? parentIdentifierLambda + : _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant( + parentIdentifierLambda.Compile(), + Lambda>( + parentIdentifierLambda, + Parameter(typeof(MaterializerLiftableConstantContext), "_")), + "parentIdentifierLambda", + typeof(Func)); + _inline = false; innerProcessor._inline = true; @@ -991,6 +1034,16 @@ when GetProjectionIndex(collectionResultExpression.ProjectionBindingExpression) QueryCompilationContext.QueryContextParameter, innerProcessor._dataReaderParameter); + var childIdentifierExpression = UseOldBehavior35212 + ? childIdentifierLambda + : _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant( + childIdentifierLambda.Compile(), + Lambda>( + childIdentifierLambda, + Parameter(typeof(MaterializerLiftableConstantContext), "_")), + "childIdentifierLambda", + typeof(Func)); + innerProcessor._inline = false; _includeExpressions.Add( @@ -1001,7 +1054,7 @@ when GetProjectionIndex(collectionResultExpression.ProjectionBindingExpression) _dataReaderParameter, _resultCoordinatorParameter, entity, - parentIdentifierLambda, + parentIdentifierExpression, _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant( navigation, LiftableConstantExpressionHelpers.BuildNavigationAccessLambda(navigation), @@ -1031,7 +1084,7 @@ when GetProjectionIndex(collectionResultExpression.ProjectionBindingExpression) CreateReaderColumnsExpression(readerColumns, _parentVisitor.Dependencies.LiftableConstantFactory), Constant(_detailedErrorsEnabled), _resultCoordinatorParameter, - childIdentifierLambda, + childIdentifierExpression, _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant( relationalSplitCollectionShaperExpression.IdentifierValueComparers .Select(x => (Func)x.Equals).ToArray(), @@ -1150,16 +1203,46 @@ when GetProjectionIndex(collectionResultExpression.ProjectionBindingExpression) QueryCompilationContext.QueryContextParameter, _dataReaderParameter); + var parentIdentifierExpression = UseOldBehavior35212 + ? parentIdentifierLambda + : _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant( + parentIdentifierLambda.Compile(), + Lambda>( + parentIdentifierLambda, + Parameter(typeof(MaterializerLiftableConstantContext), "_")), + "parentIdentifierLambda", + typeof(Func)); + var outerIdentifierLambda = Lambda( Visit(relationalCollectionShaperExpression.OuterIdentifier), QueryCompilationContext.QueryContextParameter, _dataReaderParameter); + var outerIdentifierExpression = UseOldBehavior35212 + ? outerIdentifierLambda + : _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant( + outerIdentifierLambda.Compile(), + Lambda>( + outerIdentifierLambda, + Parameter(typeof(MaterializerLiftableConstantContext), "_")), + "outerIdentifierLambda", + typeof(Func)); + var selfIdentifierLambda = Lambda( Visit(relationalCollectionShaperExpression.SelfIdentifier), QueryCompilationContext.QueryContextParameter, _dataReaderParameter); + var selfIdentifierExpression = UseOldBehavior35212 + ? selfIdentifierLambda + : _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant( + selfIdentifierLambda.Compile(), + Lambda>( + selfIdentifierLambda, + Parameter(typeof(MaterializerLiftableConstantContext), "_")), + "selfIdentifierLambda", + typeof(Func)); + _inline = false; var collectionParameter = Parameter(relationalCollectionShaperExpression.Type); @@ -1173,8 +1256,8 @@ when GetProjectionIndex(collectionResultExpression.ProjectionBindingExpression) QueryCompilationContext.QueryContextParameter, _dataReaderParameter, _resultCoordinatorParameter, - parentIdentifierLambda, - outerIdentifierLambda, + parentIdentifierExpression, + outerIdentifierExpression, _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant( collectionAccessor, LiftableConstantExpressionHelpers.BuildClrCollectionAccessorLambda(navigation), @@ -1195,9 +1278,9 @@ when GetProjectionIndex(collectionResultExpression.ProjectionBindingExpression) QueryCompilationContext.QueryContextParameter, _dataReaderParameter, _resultCoordinatorParameter, - parentIdentifierLambda, - outerIdentifierLambda, - selfIdentifierLambda, + parentIdentifierExpression, + outerIdentifierExpression, + selfIdentifierExpression, _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant( relationalCollectionShaperExpression.ParentIdentifierValueComparers .Select(x => (Func)x.Equals).ToArray(), @@ -1267,6 +1350,16 @@ when GetProjectionIndex(collectionResultExpression.ProjectionBindingExpression) QueryCompilationContext.QueryContextParameter, _dataReaderParameter); + var parentIdentifierExpression = UseOldBehavior35212 + ? parentIdentifierLambda + : _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant( + parentIdentifierLambda.Compile(), + Lambda>( + parentIdentifierLambda, + Parameter(typeof(MaterializerLiftableConstantContext), "_")), + "parentIdentifierLambda", + typeof(Func)); + _inline = false; innerProcessor._inline = true; @@ -1276,6 +1369,16 @@ when GetProjectionIndex(collectionResultExpression.ProjectionBindingExpression) QueryCompilationContext.QueryContextParameter, innerProcessor._dataReaderParameter); + var childIdentifierExpression = UseOldBehavior35212 + ? childIdentifierLambda + : _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant( + childIdentifierLambda.Compile(), + Lambda>( + childIdentifierLambda, + Parameter(typeof(MaterializerLiftableConstantContext), "_")), + "childIdentifierLambda", + typeof(Func)); + innerProcessor._inline = false; var collectionParameter = Parameter(collectionType); @@ -1290,7 +1393,7 @@ when GetProjectionIndex(collectionResultExpression.ProjectionBindingExpression) QueryCompilationContext.QueryContextParameter, _dataReaderParameter, _resultCoordinatorParameter, - parentIdentifierLambda, + parentIdentifierExpression, _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant( collectionAccessor, LiftableConstantExpressionHelpers.BuildClrCollectionAccessorLambda(navigation), @@ -1315,7 +1418,7 @@ when GetProjectionIndex(collectionResultExpression.ProjectionBindingExpression) CreateReaderColumnsExpression(readerColumns, _parentVisitor.Dependencies.LiftableConstantFactory), Constant(_detailedErrorsEnabled), _resultCoordinatorParameter, - childIdentifierLambda, + childIdentifierExpression, _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant( relationalSplitCollectionShaperExpression.IdentifierValueComparers .Select(x => (Func)x.Equals).ToArray(), diff --git a/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs index b466aba6cb4..a482de4adb0 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.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.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Query.Internal; @@ -52,6 +53,9 @@ public sealed partial class SelectExpression : TableExpressionBase private static ConstructorInfo? _quotingConstructor; + private static readonly bool UseOldBehavior35118 = + AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue35118", out var enabled35118) && enabled35118; + /// /// 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 @@ -1550,7 +1554,8 @@ public void ApplyPredicate(SqlExpression sqlExpression) Left: ColumnExpression leftColumn, Right: SqlConstantExpression { Value: string s1 } } - when GetTable(leftColumn) is TpcTablesExpression + when (UseOldBehavior35118 ? GetTable(leftColumn) : TryGetTable(leftColumn, out var table, out _) ? table : null) + is TpcTablesExpression { DiscriminatorColumn: var discriminatorColumn, DiscriminatorValues: var discriminatorValues @@ -1573,7 +1578,8 @@ when GetTable(leftColumn) is TpcTablesExpression Left: SqlConstantExpression { Value: string s2 }, Right: ColumnExpression rightColumn } - when GetTable(rightColumn) is TpcTablesExpression + when (UseOldBehavior35118 ? GetTable(rightColumn) : TryGetTable(rightColumn, out var table, out _) ? table : null) + is TpcTablesExpression { DiscriminatorColumn: var discriminatorColumn, DiscriminatorValues: var discriminatorValues @@ -1597,7 +1603,8 @@ when GetTable(rightColumn) is TpcTablesExpression Item: ColumnExpression itemColumn, Values: IReadOnlyList valueExpressions } - when GetTable(itemColumn) is TpcTablesExpression + when (UseOldBehavior35118 ? GetTable(itemColumn) : TryGetTable(itemColumn, out var table, out _) ? table : null) + is TpcTablesExpression { DiscriminatorColumn: var discriminatorColumn, DiscriminatorValues: var discriminatorValues @@ -2724,6 +2731,24 @@ private bool ContainsReferencedTable(ColumnExpression column) return false; } + private bool TryGetTable(ColumnExpression column, [NotNullWhen(true)] out TableExpressionBase? table, out int tableIndex) + { + for (var i = 0; i < _tables.Count; i++) + { + var t = _tables[i]; + if (t.UnwrapJoin().Alias == column.TableAlias) + { + table = t; + tableIndex = i; + return true; + } + } + + table = null; + tableIndex = 0; + return false; + } + private enum JoinType { InnerJoin, diff --git a/src/EFCore.SqlServer/Migrations/SqlServerMigrationsSqlGenerator.cs b/src/EFCore.SqlServer/Migrations/SqlServerMigrationsSqlGenerator.cs index a46d20ce58c..28362b77761 100644 --- a/src/EFCore.SqlServer/Migrations/SqlServerMigrationsSqlGenerator.cs +++ b/src/EFCore.SqlServer/Migrations/SqlServerMigrationsSqlGenerator.cs @@ -29,7 +29,7 @@ namespace Microsoft.EntityFrameworkCore.Migrations; public class SqlServerMigrationsSqlGenerator : MigrationsSqlGenerator { private IReadOnlyList _operations = null!; - private int _variableCounter; + private int _variableCounter = -1; private readonly ICommandBatchPreparer _commandBatchPreparer; @@ -643,6 +643,8 @@ protected override void Generate( subBuilder.Append(")"); + var historyTableName = operation[SqlServerAnnotationNames.TemporalHistoryTableName] as string; + string historyTable; if (needsExec) { subBuilder @@ -650,18 +652,14 @@ protected override void Generate( var execBody = subBuilder.GetCommandList().Single().CommandText.Replace("'", "''"); + var schemaVariable = Uniquify("@historyTableSchema"); builder - .AppendLine("DECLARE @historyTableSchema sysname = SCHEMA_NAME()") + .AppendLine($"DECLARE {schemaVariable} sysname = SCHEMA_NAME()") .Append("EXEC(N'") .Append(execBody); - } - var historyTableName = operation[SqlServerAnnotationNames.TemporalHistoryTableName] as string; - string historyTable; - if (needsExec) - { historyTable = Dependencies.SqlGenerationHelper.DelimitIdentifier(historyTableName!); - tableCreationOptions.Add($"SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema + N'].{historyTable})"); + tableCreationOptions.Add($"SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + {schemaVariable} + N'].{historyTable})"); } else { @@ -1116,10 +1114,11 @@ protected override void Generate( { if (operation[SqlServerAnnotationNames.EditionOptions] is string editionOptions) { + var dbVariable = Uniquify("@db_name"); builder .AppendLine("BEGIN") - .AppendLine("DECLARE @db_name nvarchar(max) = DB_NAME();") - .AppendLine("EXEC(N'ALTER DATABASE [' + @db_name + '] MODIFY ( ") + .AppendLine($"DECLARE {dbVariable} nvarchar(max) = DB_NAME();") + .AppendLine($"EXEC(N'ALTER DATABASE [' + {dbVariable} + '] MODIFY ( ") .Append(editionOptions.Replace("'", "''")) .AppendLine(" );');") .AppendLine("END") @@ -1128,19 +1127,21 @@ protected override void Generate( if (operation.Collation != operation.OldDatabase.Collation) { + var dbVariable = Uniquify("@db_name"); builder .AppendLine("BEGIN") - .AppendLine("DECLARE @db_name nvarchar(max) = DB_NAME();"); + .AppendLine($"DECLARE {dbVariable} nvarchar(max) = DB_NAME();"); + var collation = operation.Collation; if (operation.Collation == null) { - builder.AppendLine("DECLARE @defaultCollation nvarchar(max) = CAST(SERVERPROPERTY('Collation') AS nvarchar(max));"); + var collationVariable = Uniquify("@defaultCollation"); + builder.AppendLine($"DECLARE {collationVariable} nvarchar(max) = CAST(SERVERPROPERTY('Collation') AS nvarchar(max));"); + collation = "' + " + collationVariable + " + N'"; } builder - .Append("EXEC(N'ALTER DATABASE [' + @db_name + '] COLLATE ") - .Append(operation.Collation ?? "' + @defaultCollation + N'") - .AppendLine(";');") + .AppendLine($"EXEC(N'ALTER DATABASE [' + {dbVariable} + '] COLLATE {collation};');") .AppendLine("END") .AppendLine(); } @@ -1167,10 +1168,11 @@ protected override void Generate( using (builder.Indent()) { + var dbVariable = Uniquify("@db_name"); builder .AppendLine("BEGIN") .AppendLine("ALTER DATABASE CURRENT SET AUTO_CLOSE OFF;") - .AppendLine("DECLARE @db_name nvarchar(max) = DB_NAME();") + .AppendLine($"DECLARE {dbVariable} nvarchar(max) = DB_NAME();") .AppendLine("DECLARE @fg_name nvarchar(max);") .AppendLine("SELECT TOP(1) @fg_name = [name] FROM [sys].[filegroups] WHERE [type] = N'FX';") .AppendLine() @@ -1180,20 +1182,21 @@ protected override void Generate( { builder .AppendLine("BEGIN") - .AppendLine("SET @fg_name = @db_name + N'_MODFG';") + .AppendLine($"SET @fg_name = {dbVariable} + N'_MODFG';") .AppendLine("EXEC(N'ALTER DATABASE CURRENT ADD FILEGROUP [' + @fg_name + '] CONTAINS MEMORY_OPTIMIZED_DATA;');") .AppendLine("END"); } + var pathVariable = Uniquify("@path"); builder .AppendLine() - .AppendLine("DECLARE @path nvarchar(max);") - .Append("SELECT TOP(1) @path = [physical_name] FROM [sys].[database_files] ") + .AppendLine($"DECLARE {pathVariable} nvarchar(max);") + .Append($"SELECT TOP(1) {pathVariable} = [physical_name] FROM [sys].[database_files] ") .AppendLine("WHERE charindex('\\', [physical_name]) > 0 ORDER BY [file_id];") - .AppendLine("IF (@path IS NULL)") - .IncrementIndent().AppendLine("SET @path = '\\' + @db_name;").DecrementIndent() + .AppendLine($"IF ({pathVariable} IS NULL)") + .IncrementIndent().AppendLine($"SET {pathVariable} = '\\' + {dbVariable};").DecrementIndent() .AppendLine() - .AppendLine("DECLARE @filename nvarchar(max) = right(@path, charindex('\\', reverse(@path)) - 1);") + .AppendLine($"DECLARE @filename nvarchar(max) = right({pathVariable}, charindex('\\', reverse({pathVariable})) - 1);") .AppendLine( "SET @filename = REPLACE(left(@filename, len(@filename) - charindex('.', reverse(@filename))), '''', '''''') + N'_MOD';") .AppendLine( @@ -1739,10 +1742,11 @@ protected virtual void Transfer( { var stringTypeMapping = Dependencies.TypeMappingSource.GetMapping(typeof(string)); + var schemaVariable = Uniquify("@defaultSchema"); builder - .AppendLine("DECLARE @defaultSchema sysname = SCHEMA_NAME();") + .AppendLine($"DECLARE {schemaVariable} sysname = SCHEMA_NAME();") .Append("EXEC(") - .Append("N'ALTER SCHEMA [' + @defaultSchema + ") + .Append($"N'ALTER SCHEMA [' + {schemaVariable} + ") .Append( stringTypeMapping.GenerateSqlLiteral( "] TRANSFER " + Dependencies.SqlGenerationHelper.DelimitIdentifier(name, schema) + ";")) @@ -1908,7 +1912,7 @@ protected virtual void DropDefaultConstraint( { var stringTypeMapping = Dependencies.TypeMappingSource.GetMapping(typeof(string)); - var variable = "@var" + _variableCounter++; + var variable = Uniquify("@var"); builder .Append("DECLARE ") @@ -2039,18 +2043,18 @@ protected virtual void AddDescription( string? column = null, bool omitVariableDeclarations = false) { - string schemaLiteral; + var schemaLiteral = Uniquify("@defaultSchema", increase: !omitVariableDeclarations); + var descriptionVariable = Uniquify("@description", increase: false); + if (schema == null) { if (!omitVariableDeclarations) { - builder.Append("DECLARE @defaultSchema AS sysname") + builder.Append($"DECLARE {schemaLiteral} AS sysname") .AppendLine(Dependencies.SqlGenerationHelper.StatementTerminator); - builder.Append("SET @defaultSchema = SCHEMA_NAME()") + builder.Append($"SET {schemaLiteral} = SCHEMA_NAME()") .AppendLine(Dependencies.SqlGenerationHelper.StatementTerminator); } - - schemaLiteral = "@defaultSchema"; } else { @@ -2059,16 +2063,15 @@ protected virtual void AddDescription( if (!omitVariableDeclarations) { - builder.Append("DECLARE @description AS sql_variant") + builder.Append($"DECLARE {descriptionVariable} AS sql_variant") .AppendLine(Dependencies.SqlGenerationHelper.StatementTerminator); } - builder.Append("SET @description = ") - .Append(Literal(description)) + builder.Append($"SET {descriptionVariable} = {Literal(description)}") .AppendLine(Dependencies.SqlGenerationHelper.StatementTerminator); builder .Append("EXEC sp_addextendedproperty 'MS_Description', ") - .Append("@description") + .Append(descriptionVariable) .Append(", 'SCHEMA', ") .Append(schemaLiteral) .Append(", 'TABLE', ") @@ -2221,18 +2224,17 @@ protected virtual void DropDescription( { var stringTypeMapping = Dependencies.TypeMappingSource.GetMapping(typeof(string)); - string schemaLiteral; + var schemaLiteral = Uniquify("@defaultSchema", increase: !omitVariableDeclarations); + var descriptionVariable = Uniquify("@description", increase: false); if (schema == null) { if (!omitVariableDeclarations) { - builder.Append("DECLARE @defaultSchema AS sysname") + builder.Append($"DECLARE {schemaLiteral} AS sysname") .AppendLine(Dependencies.SqlGenerationHelper.StatementTerminator); - builder.Append("SET @defaultSchema = SCHEMA_NAME()") + builder.Append($"SET {schemaLiteral} = SCHEMA_NAME()") .AppendLine(Dependencies.SqlGenerationHelper.StatementTerminator); } - - schemaLiteral = "@defaultSchema"; } else { @@ -2241,7 +2243,7 @@ protected virtual void DropDescription( if (!omitVariableDeclarations) { - builder.Append("DECLARE @description AS sql_variant") + builder.Append($"DECLARE {descriptionVariable} AS sql_variant") .AppendLine(Dependencies.SqlGenerationHelper.StatementTerminator); } @@ -2351,6 +2353,16 @@ private static bool HasDifferences(IEnumerable source, IEnumerable< return count != targetAnnotations.Count; } + private string Uniquify(string variableName, bool increase = true) + { + if (increase) + { + _variableCounter++; + } + + return _variableCounter == 0 ? variableName : variableName + _variableCounter; + } + private IReadOnlyList RewriteOperations( IReadOnlyList migrationOperations, IModel? model, @@ -3043,10 +3055,12 @@ void EnableVersioning(string table, string? schema, string historyTableName, str { var stringBuilder = new StringBuilder(); + string? schemaVariable = null; if (historyTableSchema == null) { + schemaVariable = Uniquify("@historyTableSchema"); // need to run command using EXEC to inject default schema - stringBuilder.AppendLine("DECLARE @historyTableSchema sysname = SCHEMA_NAME()"); + stringBuilder.AppendLine($"DECLARE {schemaVariable} sysname = SCHEMA_NAME()"); stringBuilder.Append("EXEC(N'"); } @@ -3065,7 +3079,7 @@ void EnableVersioning(string table, string? schema, string historyTableName, str else { stringBuilder.AppendLine( - $" SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema + '].{historyTable}))')"); + $" SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + {schemaVariable} + '].{historyTable}))')"); } operations.Add( diff --git a/src/EFCore.SqlServer/Query/Internal/SearchConditionConvertingExpressionVisitor.cs b/src/EFCore.SqlServer/Query/Internal/SearchConditionConvertingExpressionVisitor.cs index 16073c7e512..1ad9fefde8b 100644 --- a/src/EFCore.SqlServer/Query/Internal/SearchConditionConvertingExpressionVisitor.cs +++ b/src/EFCore.SqlServer/Query/Internal/SearchConditionConvertingExpressionVisitor.cs @@ -16,6 +16,9 @@ public class SearchConditionConvertingExpressionVisitor : SqlExpressionVisitor private bool _isSearchCondition; private readonly ISqlExpressionFactory _sqlExpressionFactory; + private static readonly bool UseOldBehavior35093 = + AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue35093", out var enabled35093) && enabled35093; + /// /// 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 @@ -344,9 +347,12 @@ protected override Expression VisitSqlBinary(SqlBinaryExpression sqlBinaryExpres _isSearchCondition = parentIsSearchCondition; + var leftType = UseOldBehavior35093 ? newLeft.Type : newLeft.TypeMapping?.Converter?.ProviderClrType ?? newLeft.Type; + var rightType = UseOldBehavior35093 ? newRight.Type : newRight.TypeMapping?.Converter?.ProviderClrType ?? newRight.Type; + if (!parentIsSearchCondition - && (newLeft.Type == typeof(bool) || newLeft.Type.IsEnum || newLeft.Type.IsInteger()) - && (newRight.Type == typeof(bool) || newRight.Type.IsEnum || newRight.Type.IsInteger()) + && (leftType == typeof(bool) || leftType.IsEnum || leftType.IsInteger()) + && (rightType == typeof(bool) || rightType.IsEnum || rightType.IsInteger()) && sqlBinaryExpression.OperatorType is ExpressionType.NotEqual or ExpressionType.Equal) { // "lhs != rhs" is the same as "CAST(lhs ^ rhs AS BIT)", except that @@ -410,7 +416,10 @@ protected override Expression VisitSqlUnary(SqlUnaryExpression sqlUnaryExpressio switch (sqlUnaryExpression.OperatorType) { case ExpressionType.Not - when sqlUnaryExpression.Type == typeof(bool): + when (UseOldBehavior35093 + ? sqlUnaryExpression.Type + : (sqlUnaryExpression.TypeMapping?.Converter?.ProviderClrType ?? sqlUnaryExpression.Type)) + == typeof(bool): { // when possible, avoid converting to/from predicate form if (!_isSearchCondition && sqlUnaryExpression.Operand is not (ExistsExpression or InExpression or LikeExpression)) diff --git a/src/EFCore/ChangeTracking/ValueComparer`.cs b/src/EFCore/ChangeTracking/ValueComparer`.cs index d6eb5da40d8..4deec681b6f 100644 --- a/src/EFCore/ChangeTracking/ValueComparer`.cs +++ b/src/EFCore/ChangeTracking/ValueComparer`.cs @@ -44,6 +44,9 @@ public class ValueComparer private static readonly PropertyInfo StructuralComparisonsStructuralEqualityComparerProperty = typeof(StructuralComparisons).GetProperty(nameof(StructuralComparisons.StructuralEqualityComparer))!; + private static readonly bool UseOldBehavior35206 = + AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue35206", out var enabled35206) && enabled35206; + /// /// Creates a new with a default comparison /// expression and a shallow copy for the snapshot. @@ -263,18 +266,38 @@ public override LambdaExpression ObjectEqualsExpression var left = Parameter(typeof(object), "left"); var right = Parameter(typeof(object), "right"); - _objectEqualsExpression = Lambda>( - Condition( - Equal(left, Constant(null)), - Equal(right, Constant(null)), - AndAlso( - NotEqual(right, Constant(null)), - Invoke( - EqualsExpression, - Convert(left, typeof(T)), - Convert(right, typeof(T))))), - left, - right); + if (!UseOldBehavior35206) + { + var remap = ReplacingExpressionVisitor.Replace( + [EqualsExpression.Parameters[0], EqualsExpression.Parameters[1]], + [Convert(left, typeof(T)), Convert(right, typeof(T))], + EqualsExpression.Body); + + _objectEqualsExpression = Lambda>( + Condition( + Equal(left, Constant(null)), + Equal(right, Constant(null)), + AndAlso( + NotEqual(right, Constant(null)), + remap)), + left, + right); + } + else + { + _objectEqualsExpression = Lambda>( + Condition( + Equal(left, Constant(null)), + Equal(right, Constant(null)), + AndAlso( + NotEqual(right, Constant(null)), + Invoke( + EqualsExpression, + Convert(left, typeof(T)), + Convert(right, typeof(T))))), + left, + right); + } } return _objectEqualsExpression; diff --git a/src/EFCore/Infrastructure/ModelSource.cs b/src/EFCore/Infrastructure/ModelSource.cs index d1113d8bd27..e69a0e42e3a 100644 --- a/src/EFCore/Infrastructure/ModelSource.cs +++ b/src/EFCore/Infrastructure/ModelSource.cs @@ -65,11 +65,7 @@ public virtual IModel GetModel( { if (!cache.TryGetValue(cacheKey, out model)) { - model = CreateModel( - context, modelCreationDependencies.ConventionSetBuilder, modelCreationDependencies.ModelDependencies); - - var designTimeModel = modelCreationDependencies.ModelRuntimeInitializer.Initialize( - model, designTime: true, modelCreationDependencies.ValidationLogger); + var designTimeModel = CreateModel(context, modelCreationDependencies, designTime: true); var runtimeModel = (IModel)designTimeModel.FindRuntimeAnnotationValue(CoreAnnotationNames.ReadOnlyModel)!; @@ -88,6 +84,23 @@ public virtual IModel GetModel( return model!; } + /// + /// 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 IModel CreateModel( + DbContext context, + ModelCreationDependencies modelCreationDependencies, + bool designTime) + { + var model = CreateModel(context, modelCreationDependencies.ConventionSetBuilder, modelCreationDependencies.ModelDependencies); + return modelCreationDependencies.ModelRuntimeInitializer.Initialize( + model, designTime, modelCreationDependencies.ValidationLogger); + } + /// /// Creates the model. This method is called when the model was not found in the cache. /// diff --git a/src/EFCore/Metadata/Conventions/ForeignKeyPropertyDiscoveryConvention.cs b/src/EFCore/Metadata/Conventions/ForeignKeyPropertyDiscoveryConvention.cs index 45194d0a2a1..beb97f2b1b1 100644 --- a/src/EFCore/Metadata/Conventions/ForeignKeyPropertyDiscoveryConvention.cs +++ b/src/EFCore/Metadata/Conventions/ForeignKeyPropertyDiscoveryConvention.cs @@ -50,6 +50,9 @@ public class ForeignKeyPropertyDiscoveryConvention : IPropertyFieldChangedConvention, IModelFinalizingConvention { + private static readonly bool UseOldBehavior35110 = + AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue35110", out var enabled) && enabled; + /// /// Creates a new instance of . /// @@ -81,13 +84,17 @@ private IConventionForeignKeyBuilder ProcessForeignKey( IConventionContext context) { var shouldBeRequired = true; - foreach (var property in relationshipBuilder.Metadata.Properties) + if (!relationshipBuilder.Metadata.IsOwnership + || UseOldBehavior35110) { - if (property.IsNullable) + foreach (var property in relationshipBuilder.Metadata.Properties) { - shouldBeRequired = false; - relationshipBuilder = relationshipBuilder.IsRequired(false) ?? relationshipBuilder; - break; + if (property.IsNullable) + { + shouldBeRequired = false; + relationshipBuilder = relationshipBuilder.IsRequired(false) ?? relationshipBuilder; + break; + } } } diff --git a/src/EFCore/Metadata/Internal/InternalEntityTypeBuilder.cs b/src/EFCore/Metadata/Internal/InternalEntityTypeBuilder.cs index dfeeb09c785..53d96998377 100644 --- a/src/EFCore/Metadata/Internal/InternalEntityTypeBuilder.cs +++ b/src/EFCore/Metadata/Internal/InternalEntityTypeBuilder.cs @@ -15,6 +15,9 @@ namespace Microsoft.EntityFrameworkCore.Metadata.Internal; /// public class InternalEntityTypeBuilder : InternalTypeBaseBuilder, IConventionEntityTypeBuilder { + private static readonly bool UseOldBehavior35110 = + AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue35110", out var enabled) && enabled; + /// /// 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 @@ -3161,17 +3164,9 @@ public static InternalIndexBuilder DetachIndex(Index indexToDetach) && targetEntityType.Name == existingTargetType.ClrType.DisplayName()))) { relationship = existingNavigation.ForeignKey.Builder; - if (existingNavigation.ForeignKey.IsOwnership) - { - relationship = relationship.IsOwnership(true, configurationSource) - ?.HasNavigations(inverse, navigation, configurationSource); - - relationship?.Metadata.UpdateConfigurationSource(configurationSource); - return relationship; - } - Check.DebugAssert( - !existingTargetType.IsOwned() + existingNavigation.ForeignKey.IsOwnership + || !existingTargetType.IsOwned() || existingNavigation.DeclaringEntityType.IsInOwnershipPath(existingTargetType) || (existingTargetType.IsInOwnershipPath(existingNavigation.DeclaringEntityType) && existingTargetType.FindOwnership()!.PrincipalEntityType != existingNavigation.DeclaringEntityType), @@ -3181,6 +3176,11 @@ public static InternalIndexBuilder DetachIndex(Index indexToDetach) relationship = relationship.IsOwnership(true, configurationSource) ?.HasNavigations(inverse, navigation, configurationSource); + if (!UseOldBehavior35110) + { + relationship = relationship?.IsRequired(true, configurationSource); + } + relationship?.Metadata.UpdateConfigurationSource(configurationSource); return relationship; } diff --git a/src/EFCore/Query/Internal/ExpressionTreeFuncletizer.cs b/src/EFCore/Query/Internal/ExpressionTreeFuncletizer.cs index d301f12df10..3d70a71491f 100644 --- a/src/EFCore/Query/Internal/ExpressionTreeFuncletizer.cs +++ b/src/EFCore/Query/Internal/ExpressionTreeFuncletizer.cs @@ -100,6 +100,15 @@ public class ExpressionTreeFuncletizer : ExpressionVisitor private static readonly IReadOnlySet EmptyStringSet = new HashSet(); + private static readonly bool UseOldBehavior35095 = + AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue35095", out var enabled35095) && enabled35095; + + private static readonly bool UseOldBehavior35152 = + AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue35152", out var enabled35152) && enabled35152; + + private static readonly bool UseOldBehavior35111 = + AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue35111", out var enabled35111) && enabled35111; + private static readonly MethodInfo ReadOnlyCollectionIndexerGetter = typeof(ReadOnlyCollection).GetProperties() .Single(p => p.GetIndexParameters() is { Length: 1 } indexParameters && indexParameters[0].ParameterType == typeof(int)).GetMethod!; @@ -379,17 +388,23 @@ protected override Expression VisitBinary(BinaryExpression binary) case ExpressionType.Coalesce: leftValue = Evaluate(left); + Expression returnValue; switch (leftValue) { case null: - return Visit(binary.Right, out _state); + returnValue = Visit(binary.Right, out _state); + break; case bool b: _state = leftState with { StateType = StateType.EvaluatableWithoutCapturedVariable }; - return Constant(b); + returnValue = Constant(b); + break; default: - return left; + returnValue = left; + break; } + return UseOldBehavior35095 ? returnValue : ConvertIfNeeded(returnValue, binary.Type); + case ExpressionType.OrElse or ExpressionType.AndAlso when Evaluate(left) is bool leftBoolValue: { left = Constant(leftBoolValue); @@ -511,9 +526,10 @@ protected override Expression VisitConditional(ConditionalExpression conditional // If the test evaluates, simplify the conditional away by bubbling up the leg that remains if (testState.IsEvaluatable && Evaluate(test) is bool testBoolValue) { - return testBoolValue + var returnValue = testBoolValue ? Visit(conditional.IfTrue, out _state) : Visit(conditional.IfFalse, out _state); + return UseOldBehavior35095 ? returnValue : ConvertIfNeeded(returnValue, conditional.Type); } var ifTrue = Visit(conditional.IfTrue, out var ifTrueState); @@ -539,7 +555,11 @@ protected override Expression VisitConditional(ConditionalExpression conditional goto case StateType.ContainsEvaluatable; case StateType.ContainsEvaluatable: - // The case where the test is evaluatable has been handled above + if (testState.IsEvaluatable) + { + test = UseOldBehavior35111 ? test : ProcessEvaluatableRoot(test, ref testState); + } + if (ifTrueState.IsEvaluatable) { ifTrue = ProcessEvaluatableRoot(ifTrue, ref ifTrueState); @@ -1548,9 +1568,20 @@ UnaryExpression EvaluateOperand(UnaryExpression unary, Expression operand, State operand = ProcessEvaluatableRoot(operand, ref operandState); } - if (_state.ContainsEvaluatable) + if (UseOldBehavior35152) + { + if (_state.ContainsEvaluatable) + { + _state = _calculatingPath + ? State.CreateContainsEvaluatable( + typeof(UnaryExpression), + [_state.Path! with { PathFromParent = static e => Property(e, nameof(UnaryExpression.Operand)) }]) + : State.NoEvaluatability; + } + } + else { - _state = _calculatingPath + _state = operandState.ContainsEvaluatable && _calculatingPath ? State.CreateContainsEvaluatable( typeof(UnaryExpression), [_state.Path! with { PathFromParent = static e => Property(e, nameof(UnaryExpression.Operand)) }]) @@ -2101,6 +2132,9 @@ static Expression RemoveConvert(Expression expression) } } + private static Expression ConvertIfNeeded(Expression expression, Type type) + => expression.Type == type ? expression : Convert(expression, type); + private bool IsGenerallyEvaluatable(Expression expression) => _evaluatableExpressionFilter.IsEvaluatableExpression(expression, _model) && (_parameterize diff --git a/src/EFCore/Query/Internal/QueryableMethodNormalizingExpressionVisitor.cs b/src/EFCore/Query/Internal/QueryableMethodNormalizingExpressionVisitor.cs index ad9d12fc3ae..7a43eab9d98 100644 --- a/src/EFCore/Query/Internal/QueryableMethodNormalizingExpressionVisitor.cs +++ b/src/EFCore/Query/Internal/QueryableMethodNormalizingExpressionVisitor.cs @@ -20,6 +20,9 @@ public class QueryableMethodNormalizingExpressionVisitor : ExpressionVisitor private readonly SelectManyVerifyingExpressionVisitor _selectManyVerifyingExpressionVisitor = new(); private readonly GroupJoinConvertingExpressionVisitor _groupJoinConvertingExpressionVisitor = new(); + private static readonly bool UseOldBehavior35102 = + AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue35102", out var enabled35102) && enabled35102; + /// /// 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 @@ -489,12 +492,16 @@ private Expression TryConvertCollectionContainsToQueryableContains(MethodCallExp var sourceType = methodCallExpression.Method.DeclaringType!.GetGenericArguments()[0]; + var objectExpression = methodCallExpression.Object!.Type.IsValueType && !UseOldBehavior35102 + ? Expression.Convert(methodCallExpression.Object!, typeof(IEnumerable<>).MakeGenericType(sourceType)) + : methodCallExpression.Object!; + return VisitMethodCall( Expression.Call( QueryableMethods.Contains.MakeGenericMethod(sourceType), Expression.Call( QueryableMethods.AsQueryable.MakeGenericMethod(sourceType), - methodCallExpression.Object!), + objectExpression), methodCallExpression.Arguments[0])); } diff --git a/src/EFCore/Query/LiftableConstantProcessor.cs b/src/EFCore/Query/LiftableConstantProcessor.cs index 5e384638cd8..973601369bc 100644 --- a/src/EFCore/Query/LiftableConstantProcessor.cs +++ b/src/EFCore/Query/LiftableConstantProcessor.cs @@ -31,6 +31,9 @@ private sealed record LiftedConstant( private readonly LiftedConstantOptimizer _liftedConstantOptimizer = new(); private ParameterExpression? _contextParameter; + protected static readonly bool UseOldBehavior35208 = + AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue35208", out var enabled35208) && enabled35208; + /// /// Exposes all constants that have been lifted during the last invocation of . /// @@ -198,7 +201,7 @@ protected virtual ConstantExpression InlineConstant(LiftableConstantExpression l // Make sure there aren't any problematic un-lifted constants within the resolver expression. _unsupportedConstantChecker.Check(resolverExpression); - var resolver = resolverExpression.Compile(preferInterpretation: true); + var resolver = resolverExpression.Compile(preferInterpretation: UseOldBehavior35208); var value = resolver(_materializerLiftableConstantContext); return Expression.Constant(value, liftableConstant.Type); diff --git a/src/EFCore/Query/QueryRootProcessor.cs b/src/EFCore/Query/QueryRootProcessor.cs index ec87a57f35d..79b6597476c 100644 --- a/src/EFCore/Query/QueryRootProcessor.cs +++ b/src/EFCore/Query/QueryRootProcessor.cs @@ -13,6 +13,9 @@ public class QueryRootProcessor : ExpressionVisitor { private readonly QueryCompilationContext _queryCompilationContext; + private static readonly bool UseOldBehavior35102 = + AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue35102", out var enabled35102) && enabled35102; + /// /// Creates a new instance of the class with associated query provider. /// @@ -85,7 +88,21 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp private Expression VisitQueryRootCandidate(Expression expression, Type elementClrType) { - switch (expression) + var candidateExpression = expression; + + if (!UseOldBehavior35102) + { + // In case the collection was value type, in order to call methods like AsQueryable, + // we need to convert it to IEnumerable which requires boxing. + // We do that with Convert expression which we need to unwrap here. + if (expression is UnaryExpression { NodeType: ExpressionType.Convert } convertExpression + && convertExpression.Type.GetGenericTypeDefinition() == typeof(IEnumerable<>)) + { + candidateExpression = convertExpression.Operand; + } + } + + switch (candidateExpression) { // An array containing only constants is represented as a ConstantExpression with the array as the value. // Convert that into a NewArrayExpression for use with InlineQueryRootExpression diff --git a/test/EFCore.AspNet.InMemory.FunctionalTests/AppServiceProviderFactoryTest.cs b/test/EFCore.AspNet.InMemory.FunctionalTests/AppServiceProviderFactoryTest.cs index 84b3f4c2c46..02bf4c65e98 100644 --- a/test/EFCore.AspNet.InMemory.FunctionalTests/AppServiceProviderFactoryTest.cs +++ b/test/EFCore.AspNet.InMemory.FunctionalTests/AppServiceProviderFactoryTest.cs @@ -21,8 +21,6 @@ private static void TestCreateServices(Type programType) var factory = new TestAppServiceProviderFactory( MockAssembly.Create(programType)); - Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", null); - Environment.SetEnvironmentVariable("DOTNET_ENVIRONMENT", null); var services = factory.Create(["arg1"]); Assert.NotNull(services.GetRequiredService()); @@ -66,8 +64,6 @@ public void Create_with_no_builder_method() [typeof(ProgramWithNoHostBuilder)], new MockMethodInfo(typeof(ProgramWithNoHostBuilder), InjectHostIntoDiagnostics))); - Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", null); - Environment.SetEnvironmentVariable("DOTNET_ENVIRONMENT", null); var services = factory.Create(["arg1"]); Assert.NotNull(services.GetRequiredService()); @@ -75,8 +71,6 @@ public void Create_with_no_builder_method() private static void InjectHostIntoDiagnostics(object[] args) { - Assert.Equal("Development", Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")); - Assert.Equal("Development", Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT")); Assert.Single(args); Assert.Equal((string[])args[0], new[] { "arg1", "--applicationName", "MockAssembly" }); @@ -91,8 +85,6 @@ private class ProgramWithNoHostBuilder; private static void ValidateEnvironmentAndArgs(string[] args) { - Assert.Equal("Development", Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")); - Assert.Equal("Development", Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT")); Assert.Equal(args, new[] { "arg1" }); } diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/AdHocMiscellaneousQueryCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/AdHocMiscellaneousQueryCosmosTest.cs index 7fc328c16fd..e2dd2b90904 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/AdHocMiscellaneousQueryCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/AdHocMiscellaneousQueryCosmosTest.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.Query; #nullable disable @@ -50,6 +52,115 @@ public enum MemberType #endregion 34911 + #region 35094 + + // TODO: Move these tests to a better location. They require nullable properties with nulls in the database. + + [ConditionalFact] + public virtual async Task Min_over_value_type_containing_nulls() + { + await using var context = (await InitializeAsync()).CreateContext(); + Assert.Null(await context.Set().MinAsync(p => p.NullableVal)); + } + + [ConditionalFact] + public virtual async Task Min_over_value_type_containing_all_nulls() + { + await using var context = (await InitializeAsync()).CreateContext(); + Assert.Null(await context.Set().Where(e => e.NullableVal == null).MinAsync(p => p.NullableVal)); + } + + [ConditionalFact] + public virtual async Task Min_over_reference_type_containing_nulls() + { + await using var context = (await InitializeAsync()).CreateContext(); + Assert.Null(await context.Set().MinAsync(p => p.NullableRef)); + } + + [ConditionalFact] + public virtual async Task Min_over_reference_type_containing_all_nulls() + { + await using var context = (await InitializeAsync()).CreateContext(); + Assert.Null(await context.Set().Where(e => e.NullableRef == null).MinAsync(p => p.NullableRef)); + } + + [ConditionalFact] + public virtual async Task Min_over_reference_type_containing_no_data() + { + await using var context = (await InitializeAsync()).CreateContext(); + Assert.Null(await context.Set().Where(e => e.Id < 0).MinAsync(p => p.NullableRef)); + } + + [ConditionalFact] + public virtual async Task Max_over_value_type_containing_nulls() + { + await using var context = (await InitializeAsync()).CreateContext(); + Assert.Equal(3.14, await context.Set().MaxAsync(p => p.NullableVal)); + } + + [ConditionalFact] + public virtual async Task Max_over_value_type_containing_all_nulls() + { + await using var context = (await InitializeAsync()).CreateContext(); + Assert.Null(await context.Set().Where(e => e.NullableVal == null).MaxAsync(p => p.NullableVal)); + } + + [ConditionalFact] + public virtual async Task Max_over_reference_type_containing_nulls() + { + await using var context = (await InitializeAsync()).CreateContext(); + Assert.Equal("Value", await context.Set().MaxAsync(p => p.NullableRef)); + } + + [ConditionalFact] + public virtual async Task Max_over_reference_type_containing_all_nulls() + { + await using var context = (await InitializeAsync()).CreateContext(); + Assert.Null(await context.Set().Where(e => e.NullableRef == null).MaxAsync(p => p.NullableRef)); + } + + [ConditionalFact] + public virtual async Task Max_over_reference_type_containing_no_data() + { + await using var context = (await InitializeAsync()).CreateContext(); + Assert.Null(await context.Set().Where(e => e.Id < 0).MaxAsync(p => p.NullableRef)); + } + + [ConditionalFact] + public virtual async Task Average_over_value_type_containing_nulls() + { + await using var context = (await InitializeAsync()).CreateContext(); + Assert.Null(await context.Set().AverageAsync(p => p.NullableVal)); + } + + [ConditionalFact] + public virtual async Task Average_over_value_type_containing_all_nulls() + { + await using var context = (await InitializeAsync()).CreateContext(); + Assert.Null(await context.Set().Where(e => e.NullableVal == null).AverageAsync(p => p.NullableVal)); + } + + protected class Context35094(DbContextOptions options) : DbContext(options) + { + public DbSet Products { get; set; } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + => modelBuilder.Entity().HasData( + new Product { Id = 1, NullableRef = "Value", NullableVal = 3.14 }, + new Product { Id = 2, NullableVal = 3.14 }, + new Product { Id = 3, NullableRef = "Value" }); + + public class Product + { + [DatabaseGenerated(DatabaseGeneratedOption.None)] + public int Id { get; set; } + public double? NullableVal { get; set; } + public string NullableRef { get; set; } + } + } + + #endregion 35094 + protected override string StoreName => "AdHocMiscellaneousQueryTests"; diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindAggregateOperatorsQueryCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindAggregateOperatorsQueryCosmosTest.cs index 2d30fc87c90..6f1291dbecd 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindAggregateOperatorsQueryCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindAggregateOperatorsQueryCosmosTest.cs @@ -555,49 +555,33 @@ FROM root c } } - public override async Task Average_no_data_nullable(bool async) - { - // Sync always throws before getting to exception being tested. - if (async) - { - await Fixture.NoSyncTest( - async, async a => - { - Assert.Equal( - CoreStrings.SequenceContainsNoElements, - (await Assert.ThrowsAsync(() => base.Average_no_data_nullable(a))).Message); + public override Task Average_no_data_nullable(bool async) + => Fixture.NoSyncTest( + async, async a => + { + await base.Average_no_data_nullable(a); - AssertSql( - """ + AssertSql( + """ SELECT VALUE AVG(c["SupplierID"]) FROM root c WHERE ((c["$type"] = "Product") AND (c["SupplierID"] = -1)) """); - }); - } - } + }); - public override async Task Average_no_data_cast_to_nullable(bool async) - { - // Sync always throws before getting to exception being tested. - if (async) - { - await Fixture.NoSyncTest( - async, async a => - { - Assert.Equal( - CoreStrings.SequenceContainsNoElements, - (await Assert.ThrowsAsync(() => base.Average_no_data_cast_to_nullable(a))).Message); + public override Task Average_no_data_cast_to_nullable(bool async) + => Fixture.NoSyncTest( + async, async a => + { + await base.Average_no_data_cast_to_nullable(a); - AssertSql( - """ + AssertSql( + """ SELECT VALUE AVG(c["OrderID"]) FROM root c WHERE ((c["$type"] = "Order") AND (c["OrderID"] = -1)) """); - }); - } - } + }); public override async Task Min_no_data(bool async) { @@ -647,49 +631,33 @@ public override async Task Max_no_data_subquery(bool async) AssertSql(); } - public override async Task Max_no_data_nullable(bool async) - { - // Sync always throws before getting to exception being tested. - if (async) - { - await Fixture.NoSyncTest( - async, async a => - { - Assert.Equal( - CoreStrings.SequenceContainsNoElements, - (await Assert.ThrowsAsync(() => base.Max_no_data_nullable(a))).Message); + public override Task Max_no_data_nullable(bool async) + => Fixture.NoSyncTest( + async, async a => + { + await base.Max_no_data_nullable(a); - AssertSql( - """ + AssertSql( + """ SELECT VALUE MAX(c["SupplierID"]) FROM root c WHERE ((c["$type"] = "Product") AND (c["SupplierID"] = -1)) """); - }); - } - } + }); - public override async Task Max_no_data_cast_to_nullable(bool async) - { - // Sync always throws before getting to exception being tested. - if (async) - { - await Fixture.NoSyncTest( - async, async a => - { - Assert.Equal( - CoreStrings.SequenceContainsNoElements, - (await Assert.ThrowsAsync(() => base.Max_no_data_cast_to_nullable(a))).Message); + public override Task Max_no_data_cast_to_nullable(bool async) + => Fixture.NoSyncTest( + async, async a => + { + await base.Max_no_data_cast_to_nullable(a); - AssertSql( - """ + AssertSql( + """ SELECT VALUE MAX(c["OrderID"]) FROM root c WHERE ((c["$type"] = "Order") AND (c["OrderID"] = -1)) """); - }); - } - } + }); public override async Task Min_no_data_subquery(bool async) { @@ -699,22 +667,19 @@ public override async Task Min_no_data_subquery(bool async) AssertSql(); } - public override async Task Average_with_no_arg(bool async) - { - // Always throws for sync. - if (async) - { - // Average truncates. Issue #26378. - await Assert.ThrowsAsync(async () => await base.Average_with_no_arg(async)); + public override Task Average_with_no_arg(bool async) + => Fixture.NoSyncTest( + async, async a => + { + await base.Average_with_no_arg(a); - AssertSql( - """ + AssertSql( + """ SELECT VALUE AVG(c["OrderID"]) FROM root c WHERE (c["$type"] = "Order") """); - } - } + }); public override Task Average_with_binary_expression(bool async) => Fixture.NoSyncTest( @@ -730,22 +695,19 @@ FROM root c """); }); - public override async Task Average_with_arg(bool async) - { - // Always throws for sync. - if (async) - { - // Average truncates. Issue #26378. - await Assert.ThrowsAsync(async () => await base.Average_with_arg(async)); + public override Task Average_with_arg(bool async) + => Fixture.NoSyncTest( + async, async a => + { + await base.Average_with_arg(a); - AssertSql( - """ + AssertSql( + """ SELECT VALUE AVG(c["OrderID"]) FROM root c WHERE (c["$type"] = "Order") """); - } - } + }); public override Task Average_with_arg_expression(bool async) => Fixture.NoSyncTest( @@ -874,49 +836,33 @@ FROM root c """); }); - public override async Task Min_no_data_nullable(bool async) - { - // Sync always throws before getting to exception being tested. - if (async) - { - await Fixture.NoSyncTest( - async, async a => - { - Assert.Equal( - CoreStrings.SequenceContainsNoElements, - (await Assert.ThrowsAsync(() => base.Min_no_data_nullable(a))).Message); + public override Task Min_no_data_nullable(bool async) + => Fixture.NoSyncTest( + async, async a => + { + await base.Min_no_data_nullable(a); - AssertSql( - """ + AssertSql( + """ SELECT VALUE MIN(c["SupplierID"]) FROM root c WHERE ((c["$type"] = "Product") AND (c["SupplierID"] = -1)) """); - }); - } - } + }); - public override async Task Min_no_data_cast_to_nullable(bool async) - { - // Sync always throws before getting to exception being tested. - if (async) - { - await Fixture.NoSyncTest( - async, async a => - { - Assert.Equal( - CoreStrings.SequenceContainsNoElements, - (await Assert.ThrowsAsync(() => base.Min_no_data_cast_to_nullable(a))).Message); + public override Task Min_no_data_cast_to_nullable(bool async) + => Fixture.NoSyncTest( + async, async a => + { + await base.Min_no_data_cast_to_nullable(a); - AssertSql( - """ + AssertSql( + """ SELECT VALUE MIN(c["OrderID"]) FROM root c WHERE ((c["$type"] = "Order") AND (c["OrderID"] = -1)) """); - }); - } - } + }); public override Task Min_with_coalesce(bool async) => Fixture.NoSyncTest( diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindMiscellaneousQueryCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindMiscellaneousQueryCosmosTest.cs index 2b0278d4aa2..9d74bed0e7a 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindMiscellaneousQueryCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindMiscellaneousQueryCosmosTest.cs @@ -5276,6 +5276,25 @@ public virtual async Task ToPageAsync_in_subquery_throws() #endregion ToPageAsync + public override async Task Column_access_inside_subquery_predicate(bool async) + { + // Uncorrelated subquery, not supported by Cosmos + await AssertTranslationFailed(() => base.Column_access_inside_subquery_predicate(async)); + + AssertSql(); + } + + public override async Task Cast_to_object_over_parameter_directly_in_lambda(bool async) + { + // Sync always throws before getting to exception being tested. + if (async) + { + // Cosmos doesn't support ORDER BY over parameter/constant: + // Unsupported ORDER BY clause. ORDER BY item expression could not be mapped to a document path. + await Assert.ThrowsAsync(() => base.Cast_to_object_over_parameter_directly_in_lambda(async: true)); + } + } + private void AssertSql(params string[] expected) => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindWhereQueryCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindWhereQueryCosmosTest.cs index 81298094b74..93ac1555485 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindWhereQueryCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindWhereQueryCosmosTest.cs @@ -3303,6 +3303,18 @@ FROM root c SELECT VALUE c["OrderID"] FROM root c WHERE ((c["$type"] = "Order") AND (c["OrderID"] = 10252)) +"""); + }); + + public override Task Simplifiable_coalesce_over_nullable(bool async) + => Fixture.NoSyncTest( + async, async a => + { + await base.Simplifiable_coalesce_over_nullable(a); + + AssertSql( + """ +ReadItem(None, Order|10248) """); }); diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/PrimitiveCollectionsQueryCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/PrimitiveCollectionsQueryCosmosTest.cs index 78dd12d771c..ea203a234b2 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/PrimitiveCollectionsQueryCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/PrimitiveCollectionsQueryCosmosTest.cs @@ -613,6 +613,30 @@ WHERE ARRAY_CONTAINS(@__ints_0, c["Int"]) """ @__ints_0='[10,999]' +SELECT VALUE c +FROM root c +WHERE NOT(ARRAY_CONTAINS(@__ints_0, c["Int"])) +"""); + }); + + public override Task Parameter_collection_ImmutableArray_of_ints_Contains_int(bool async) + => CosmosTestHelpers.Instance.NoSyncTest( + async, async a => + { + await base.Parameter_collection_ImmutableArray_of_ints_Contains_int(a); + + AssertSql( + """ +@__ints_0='[10,999]' + +SELECT VALUE c +FROM root c +WHERE ARRAY_CONTAINS(@__ints_0, c["Int"]) +""", + // + """ +@__ints_0='[10,999]' + SELECT VALUE c FROM root c WHERE NOT(ARRAY_CONTAINS(@__ints_0, c["Int"])) diff --git a/test/EFCore.Cosmos.FunctionalTests/VectorSearchCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/VectorSearchCosmosTest.cs index 04da9fd280c..92d4aacb0f9 100644 --- a/test/EFCore.Cosmos.FunctionalTests/VectorSearchCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/VectorSearchCosmosTest.cs @@ -9,8 +9,7 @@ namespace Microsoft.EntityFrameworkCore; #pragma warning disable EF9103 -// These tests are skipped for now because we cannot create a compatible test container until the SDK supports it. -internal class VectorSearchCosmosTest : IClassFixture +public class VectorSearchCosmosTest : IClassFixture { public VectorSearchCosmosTest(VectorSearchFixture fixture, ITestOutputHelper testOutputHelper) { diff --git a/test/EFCore.Design.Tests/Design/Internal/DbContextOperationsTest.cs b/test/EFCore.Design.Tests/Design/Internal/DbContextOperationsTest.cs index 990345659b5..4120e9ad05f 100644 --- a/test/EFCore.Design.Tests/Design/Internal/DbContextOperationsTest.cs +++ b/test/EFCore.Design.Tests/Design/Internal/DbContextOperationsTest.cs @@ -414,6 +414,8 @@ public TestContext() public TestContext(DbContextOptions options) : base(options) { + Assert.Equal("Development", Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")); + Assert.Equal("Development", Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT")); } } @@ -425,6 +427,8 @@ private TestContextFromFactory() public TestContextFromFactory(DbContextOptions options) : base(options) { + Assert.Equal("Development", Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")); + Assert.Equal("Development", Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT")); } } diff --git a/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.ModelSnapshot.cs b/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.ModelSnapshot.cs index d9216f9dfe5..ce667239197 100644 --- a/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.ModelSnapshot.cs +++ b/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.ModelSnapshot.cs @@ -8570,10 +8570,7 @@ protected CSharpMigrationsGenerator CreateMigrationsGenerator() var sqlServerTypeMappingSource = new SqlServerTypeMappingSource( TestServiceFactory.Instance.Create(), new RelationalTypeMappingSourceDependencies( - new IRelationalTypeMappingSourcePlugin[] - { - new SqlServerNetTopologySuiteTypeMappingSourcePlugin(NtsGeometryServices.Instance) - })); + [new SqlServerNetTopologySuiteTypeMappingSourcePlugin(NtsGeometryServices.Instance)])); var codeHelper = new CSharpHelper(sqlServerTypeMappingSource); diff --git a/test/EFCore.Relational.Specification.Tests/Migrations/MigrationsInfrastructureTestBase.cs b/test/EFCore.Relational.Specification.Tests/Migrations/MigrationsInfrastructureTestBase.cs index 20ca2928a65..da798d53875 100644 --- a/test/EFCore.Relational.Specification.Tests/Migrations/MigrationsInfrastructureTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Migrations/MigrationsInfrastructureTestBase.cs @@ -154,8 +154,8 @@ public virtual void Can_apply_one_migration() x => Assert.Equal("00000000000001_Migration1", x.MigrationId)); Assert.Equal( - LogLevel.Error, - Fixture.TestSqlLoggerFactory.Log.Single(l => l.Id == RelationalEventId.PendingModelChangesWarning).Level); + LogLevel.Information, + Fixture.TestSqlLoggerFactory.Log.Single(l => l.Id == RelationalEventId.ModelSnapshotNotFound).Level); } [ConditionalFact] @@ -286,21 +286,85 @@ await history.GetAppliedMigrationsAsync(), } [ConditionalFact] - public virtual void Can_generate_no_migration_script() + public virtual void Can_apply_two_migrations_in_transaction() + { + using var db = Fixture.CreateContext(); + db.Database.EnsureDeleted(); + GiveMeSomeTime(db); + db.GetService().Create(); + + var strategy = db.Database.CreateExecutionStrategy(); + strategy.Execute(() => + { + using var transaction = db.Database.BeginTransaction(); + var migrator = db.GetService(); + migrator.Migrate("Migration1"); + migrator.Migrate("Migration2"); + + var history = db.GetService(); + Assert.Collection( + history.GetAppliedMigrations(), + x => Assert.Equal("00000000000001_Migration1", x.MigrationId), + x => Assert.Equal("00000000000002_Migration2", x.MigrationId)); + }); + + Assert.Equal( + LogLevel.Warning, + Fixture.TestSqlLoggerFactory.Log.First(l => l.Id == RelationalEventId.MigrationsUserTransactionWarning).Level); + } + + [ConditionalFact] + public virtual async Task Can_apply_two_migrations_in_transaction_async() + { + using var db = Fixture.CreateContext(); + await db.Database.EnsureDeletedAsync(); + await GiveMeSomeTimeAsync(db); + await db.GetService().CreateAsync(); + + var strategy = db.Database.CreateExecutionStrategy(); + await strategy.ExecuteAsync(async () => + { + using var transaction = db.Database.BeginTransactionAsync(); + var migrator = db.GetService(); + await migrator.MigrateAsync("Migration1"); + await migrator.MigrateAsync("Migration2"); + + var history = db.GetService(); + Assert.Collection( + await history.GetAppliedMigrationsAsync(), + x => Assert.Equal("00000000000001_Migration1", x.MigrationId), + x => Assert.Equal("00000000000002_Migration2", x.MigrationId)); + }); + + Assert.Equal( + LogLevel.Warning, + Fixture.TestSqlLoggerFactory.Log.First(l => l.Id == RelationalEventId.MigrationsUserTransactionWarning).Level); + } + + [ConditionalFact] + public virtual async Task Can_generate_no_migration_script() { using var db = Fixture.CreateEmptyContext(); var migrator = db.GetService(); - SetAndExecuteSqlAsync(migrator.GenerateScript()); + await db.Database.EnsureDeletedAsync(); + await GiveMeSomeTimeAsync(db); + await db.GetService().CreateAsync(); + + await SetAndExecuteSqlAsync(migrator.GenerateScript()); } [ConditionalFact] - public virtual void Can_generate_migration_from_initial_database_to_initial() + public virtual async Task Can_generate_migration_from_initial_database_to_initial() { using var db = Fixture.CreateContext(); var migrator = db.GetService(); - SetAndExecuteSqlAsync(migrator.GenerateScript(fromMigration: Migration.InitialDatabase, toMigration: Migration.InitialDatabase)); + await db.Database.EnsureDeletedAsync(); + await GiveMeSomeTimeAsync(db); + await db.GetService().CreateAsync(); + + await SetAndExecuteSqlAsync(migrator.GenerateScript(fromMigration: Migration.InitialDatabase, toMigration: Migration.InitialDatabase)); } [ConditionalFact] @@ -310,6 +374,7 @@ public virtual async Task Can_generate_up_and_down_scripts() var migrator = db.GetService(); await db.Database.EnsureDeletedAsync(); + await GiveMeSomeTimeAsync(db); await db.GetService().CreateAsync(); await SetAndExecuteSqlAsync(migrator.GenerateScript()); @@ -327,6 +392,7 @@ public virtual async Task Can_generate_up_and_down_scripts_noTransactions() var migrator = db.GetService(); await db.Database.EnsureDeletedAsync(); + await GiveMeSomeTimeAsync(db); await db.GetService().CreateAsync(); await SetAndExecuteSqlAsync(migrator.GenerateScript(options: MigrationsSqlGenerationOptions.NoTransactions)); @@ -345,6 +411,7 @@ public virtual async Task Can_generate_one_up_and_down_script() var migrator = db.GetService(); await db.Database.EnsureDeletedAsync(); + await GiveMeSomeTimeAsync(db); await db.GetService().CreateAsync(); await ExecuteSqlAsync(migrator.GenerateScript( @@ -367,6 +434,7 @@ public virtual async Task Can_generate_up_and_down_script_using_names() var migrator = db.GetService(); await db.Database.EnsureDeletedAsync(); + await GiveMeSomeTimeAsync(db); await db.GetService().CreateAsync(); await ExecuteSqlAsync(migrator.GenerateScript( @@ -389,6 +457,7 @@ public virtual async Task Can_generate_idempotent_up_and_down_scripts() var migrator = db.GetService(); await db.Database.EnsureDeletedAsync(); + await GiveMeSomeTimeAsync(db); await db.GetService().CreateAsync(); await SetAndExecuteSqlAsync(migrator.GenerateScript( @@ -409,6 +478,7 @@ public virtual async Task Can_generate_idempotent_up_and_down_scripts_noTransact var migrator = db.GetService(); await db.Database.EnsureDeletedAsync(); + await GiveMeSomeTimeAsync(db); await db.GetService().CreateAsync(); await SetAndExecuteSqlAsync(migrator.GenerateScript( @@ -535,6 +605,7 @@ public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder build e => e .Log(RelationalEventId.PendingModelChangesWarning) .Log(RelationalEventId.NonTransactionalMigrationOperationWarning) + .Log(RelationalEventId.MigrationsUserTransactionWarning) ); protected override bool ShouldLogCategory(string logCategory) diff --git a/test/EFCore.Relational.Tests/Migrations/Internal/MigrationsModelDifferTest.cs b/test/EFCore.Relational.Tests/Migrations/Internal/MigrationsModelDifferTest.cs index 3c00a36a40b..5ca1a781feb 100644 --- a/test/EFCore.Relational.Tests/Migrations/Internal/MigrationsModelDifferTest.cs +++ b/test/EFCore.Relational.Tests/Migrations/Internal/MigrationsModelDifferTest.cs @@ -9763,6 +9763,62 @@ public void Update_AK_seed_value_with_a_referencing_foreign_key() v => Assert.Equal(4242, v)); })); + [ConditionalFact] + public void Owned_collection_with_explicit_id() + => Execute( + modelBuilder => + { + }, + source => + { + source.Entity("Microsoft.EntityFrameworkCore.Migrations.Internal.Account", b => + { + b.Property("Id"); + b.HasKey("Id"); + b.ToTable("account"); + }); + + source.Entity("Microsoft.EntityFrameworkCore.Migrations.Internal.Account", b => + { + b.OwnsMany("Microsoft.EntityFrameworkCore.Migrations.Internal.AccountHolder", "AccountHolders", b1 => + { + b1.Property("Id"); + b1.Property("account_id"); + b1.HasKey("Id"); + b1.HasIndex("account_id"); + b1.ToTable("account_holder"); + b1.WithOwner().HasForeignKey("account_id"); + }); + }); + }, + target => + { + target.Entity(builder => + { + builder.ToTable("account"); + builder.HasKey("Id"); + builder.OwnsMany(a => a.AccountHolders, navigationBuilder => + { + navigationBuilder.ToTable("account_holder"); + navigationBuilder.Property("Id"); + navigationBuilder.HasKey("Id"); + navigationBuilder.Property("account_id"); + navigationBuilder.WithOwner().HasForeignKey("account_id"); + }); + }); + }, + Assert.Empty); + + public class Account + { + public string Id { get; set; } + public IEnumerable AccountHolders { get; set; } = []; + } + + public class AccountHolder + { + } + [ConditionalFact] public void SeedData_with_guid_AK_and_multiple_owned_types() => Execute( diff --git a/test/EFCore.Relational.Tests/Migrations/MigrationCommandExecutorTest.cs b/test/EFCore.Relational.Tests/Migrations/MigrationCommandExecutorTest.cs index f1ca15a4b7b..6f491c81db3 100644 --- a/test/EFCore.Relational.Tests/Migrations/MigrationCommandExecutorTest.cs +++ b/test/EFCore.Relational.Tests/Migrations/MigrationCommandExecutorTest.cs @@ -122,16 +122,14 @@ 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); + async () => await migrationCommandExecutor.ExecuteNonQueryAsync(commandList, fakeConnection))).Message); } else { Assert.Equal( RelationalStrings.TransactionSuppressedMigrationInUserTransaction, Assert.Throws( - () - => migrationCommandExecutor.ExecuteNonQuery(commandList, fakeConnection)).Message); + () => migrationCommandExecutor.ExecuteNonQuery(commandList, fakeConnection)).Message); } tx.Rollback(); diff --git a/test/EFCore.Specification.Tests/CustomConvertersTestBase.cs b/test/EFCore.Specification.Tests/CustomConvertersTestBase.cs index 5dffaf88d9a..a94b718bf99 100644 --- a/test/EFCore.Specification.Tests/CustomConvertersTestBase.cs +++ b/test/EFCore.Specification.Tests/CustomConvertersTestBase.cs @@ -1184,8 +1184,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con b.Property(e => e.ByteArray5) .HasConversion( new ValueConverter( - v => v.Reverse().Concat(new byte[] { 4, 20 }).ToArray(), - v => v.Reverse().Skip(2).ToArray()), + v => ((IEnumerable)v).Reverse().Concat(new byte[] { 4, 20 }).ToArray(), + v => ((IEnumerable)v).Reverse().Skip(2).ToArray()), bytesComparer) .HasMaxLength(7); diff --git a/test/EFCore.Specification.Tests/Query/AdHocQueryFiltersQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/AdHocQueryFiltersQueryTestBase.cs index c9cd6ab37f2..6754eb275f3 100644 --- a/test/EFCore.Specification.Tests/Query/AdHocQueryFiltersQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/AdHocQueryFiltersQueryTestBase.cs @@ -730,4 +730,42 @@ public class ChildFilter2 } #endregion + + #region 35111 + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual async Task Query_filter_with_context_accessor_with_constant(bool async) + { + var contextFactory = await InitializeAsync(); + using var context = contextFactory.CreateContext(); + + var data = async + ? await context.Set().ToListAsync() + : context.Set().ToList(); + } + + protected class Context35111(DbContextOptions options) : DbContext(options) + { + public int Foo { get; set; } + public long? Bar { get; set; } + public List Baz { get; set; } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity() + .HasQueryFilter(e => + Foo == 1 + ? Baz.Contains(e.Bar) + : e.Bar == Bar); + } + } + + public class FooBar35111 + { + public long Id { get; set; } + public long Bar { get; set; } + } + + #endregion } diff --git a/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs index ec8180be84c..93ffe9f0cfb 100644 --- a/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs @@ -8047,6 +8047,13 @@ public virtual Task Comparison_with_value_converted_subclass(bool async) async, ss => ss.Set().Where(f => f.ServerAddress == IPAddress.Loopback)); + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Project_equality_with_value_converted_property(bool async) + => AssertQuery( + async, + ss => ss.Set().Select(m => m.Difficulty == MissionDifficulty.Unknown)); + private static readonly IEnumerable _weaponTypes = new AmmunitionType?[] { AmmunitionType.Cartridge }; [ConditionalTheory] diff --git a/test/EFCore.Specification.Tests/Query/NorthwindMiscellaneousQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/NorthwindMiscellaneousQueryTestBase.cs index b04c427891e..f0b8346fcb4 100644 --- a/test/EFCore.Specification.Tests/Query/NorthwindMiscellaneousQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/NorthwindMiscellaneousQueryTestBase.cs @@ -5849,4 +5849,22 @@ public virtual Task Static_member_access_gets_parameterized_within_larger_evalua private static string StaticProperty => "ALF"; + + [ConditionalTheory] // #35118 + [MemberData(nameof(IsAsyncData))] + public virtual Task Column_access_inside_subquery_predicate(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(c => ss.Set().Where(o => c.CustomerID == "ALFKI").Any())); + + [ConditionalTheory] // #35152 + [MemberData(nameof(IsAsyncData))] + public virtual Task Cast_to_object_over_parameter_directly_in_lambda(bool async) + { + var i = 8; + + return AssertQuery( + async, + ss => ss.Set().OrderBy(o => (object)i).Select(o => o)); + } } diff --git a/test/EFCore.Specification.Tests/Query/NorthwindWhereQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/NorthwindWhereQueryTestBase.cs index c1de5a6b834..dbf562f66e0 100644 --- a/test/EFCore.Specification.Tests/Query/NorthwindWhereQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/NorthwindWhereQueryTestBase.cs @@ -2536,7 +2536,18 @@ await AssertQuery( elementAsserter: (e, a) => AssertEqual(e.Id, a.Id)); } - #region Evaluation order of predicates + [ConditionalTheory] // #35095 + [MemberData(nameof(IsAsyncData))] + public virtual Task Simplifiable_coalesce_over_nullable(bool async) + { + int? orderId = 10248; + + return AssertQuery( + async, + ss => ss.Set().Where(o => o.OrderID == (orderId ?? 0))); + } + + #region Evaluation order of operators [ConditionalTheory] [MemberData(nameof(IsAsyncData))] @@ -2559,5 +2570,5 @@ public virtual Task Take_and_Distinct_evaluation_order(bool async) async, ss => ss.Set().Select(c => c.ContactTitle).OrderBy(t => t).Take(3).Distinct()); - #endregion Evaluation order of predicates + #endregion Evaluation order of operators } diff --git a/test/EFCore.Specification.Tests/Query/PrimitiveCollectionsQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/PrimitiveCollectionsQueryTestBase.cs index 2304ac3db4c..60e7cd24697 100644 --- a/test/EFCore.Specification.Tests/Query/PrimitiveCollectionsQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/PrimitiveCollectionsQueryTestBase.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.Collections.Immutable; + namespace Microsoft.EntityFrameworkCore.Query; public abstract class PrimitiveCollectionsQueryTestBase(TFixture fixture) : QueryTestBase(fixture) @@ -363,6 +365,20 @@ await AssertQuery( ss => ss.Set().Where(c => !ints.Contains(c.Int))); } + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual async Task Parameter_collection_ImmutableArray_of_ints_Contains_int(bool async) + { + var ints = ImmutableArray.Create([10, 999]); + + await AssertQuery( + async, + ss => ss.Set().Where(c => ints.Contains(c.Int))); + await AssertQuery( + async, + ss => ss.Set().Where(c => !ints.Contains(c.Int))); + } + [ConditionalTheory] [MemberData(nameof(IsAsyncData))] public virtual async Task Parameter_collection_of_ints_Contains_nullable_int(bool async) diff --git a/test/EFCore.SqlServer.FunctionalTests/Migrations/MigrationsInfrastructureSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Migrations/MigrationsInfrastructureSqlServerTest.cs index 5399e2b5766..491a5e86ab6 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Migrations/MigrationsInfrastructureSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Migrations/MigrationsInfrastructureSqlServerTest.cs @@ -8,6 +8,7 @@ using Microsoft.EntityFrameworkCore.Diagnostics.Internal; using Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal; using Microsoft.EntityFrameworkCore.TestModels.AspNetIdentity; +using static Microsoft.EntityFrameworkCore.Migrations.MigrationsInfrastructureFixtureBase; // ReSharper disable InconsistentNaming namespace Microsoft.EntityFrameworkCore.Migrations @@ -35,9 +36,9 @@ public override void Can_apply_range_of_migrations() Fixture.TestSqlLoggerFactory.Log.Single(l => l.Id == RelationalEventId.NonTransactionalMigrationOperationWarning).Message); } - public override void Can_generate_migration_from_initial_database_to_initial() + public override async Task Can_generate_migration_from_initial_database_to_initial() { - base.Can_generate_migration_from_initial_database_to_initial(); + await base.Can_generate_migration_from_initial_database_to_initial(); Assert.Equal( """ @@ -57,9 +58,9 @@ CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY ([MigrationId]) ignoreLineEndingDifferences: true); } - public override void Can_generate_no_migration_script() + public override async Task Can_generate_no_migration_script() { - base.Can_generate_no_migration_script(); + await base.Can_generate_no_migration_script(); Assert.Equal( """ @@ -650,12 +651,136 @@ public override void Can_get_active_provider() Assert.Equal("Microsoft.EntityFrameworkCore.SqlServer", ActiveProvider); } + [ConditionalFact] + public void Throws_when_no_migrations() + { + using var context = new DbContext( + Fixture.TestStore.AddProviderOptions( + new DbContextOptionsBuilder().EnableServiceProviderCaching(false) + .ConfigureWarnings(e => e.Throw(RelationalEventId.MigrationsNotFound))).Options); + + context.Database.EnsureDeleted(); + GiveMeSomeTime(context); + + Assert.Equal( + CoreStrings.WarningAsErrorTemplate( + RelationalEventId.MigrationsNotFound.ToString(), + RelationalResources.LogNoMigrationsFound(new TestLogger()) + .GenerateMessage(typeof(DbContext).Assembly.GetName().Name), + "RelationalEventId.MigrationsNotFound"), + (Assert.Throws(context.Database.Migrate)).Message); + } + + [ConditionalFact] + public async Task Throws_when_no_migrations_async() + { + using var context = new DbContext( + Fixture.TestStore.AddProviderOptions( + new DbContextOptionsBuilder().EnableServiceProviderCaching(false) + .ConfigureWarnings(e => e.Throw(RelationalEventId.MigrationsNotFound))).Options); + + await context.Database.EnsureDeletedAsync(); + await GiveMeSomeTimeAsync(context); + + Assert.Equal( + CoreStrings.WarningAsErrorTemplate( + RelationalEventId.MigrationsNotFound.ToString(), + RelationalResources.LogNoMigrationsFound(new TestLogger()) + .GenerateMessage(typeof(DbContext).Assembly.GetName().Name), + "RelationalEventId.MigrationsNotFound"), + (await Assert.ThrowsAsync(() => context.Database.MigrateAsync())).Message); + } + + [ConditionalFact] + public void Throws_when_no_snapshot() + { + using var context = new MigrationsContext( + Fixture.TestStore.AddProviderOptions( + new DbContextOptionsBuilder().EnableServiceProviderCaching(false) + .ConfigureWarnings(e => e.Throw(RelationalEventId.ModelSnapshotNotFound))).Options); + + context.Database.EnsureDeleted(); + GiveMeSomeTime(context); + + Assert.Equal( + CoreStrings.WarningAsErrorTemplate( + RelationalEventId.ModelSnapshotNotFound.ToString(), + RelationalResources.LogNoModelSnapshotFound(new TestLogger()) + .GenerateMessage(typeof(MigrationsContext).Assembly.GetName().Name), + "RelationalEventId.ModelSnapshotNotFound"), + (Assert.Throws(context.Database.Migrate)).Message); + } + + [ConditionalFact] + public async Task Throws_when_no_snapshot_async() + { + using var context = new MigrationsContext( + Fixture.TestStore.AddProviderOptions( + new DbContextOptionsBuilder().EnableServiceProviderCaching(false) + .ConfigureWarnings(e => e.Throw(RelationalEventId.ModelSnapshotNotFound))).Options); + + await context.Database.EnsureDeletedAsync(); + await GiveMeSomeTimeAsync(context); + + Assert.Equal( + CoreStrings.WarningAsErrorTemplate( + RelationalEventId.ModelSnapshotNotFound.ToString(), + RelationalResources.LogNoModelSnapshotFound(new TestLogger()) + .GenerateMessage(typeof(MigrationsContext).Assembly.GetName().Name), + "RelationalEventId.ModelSnapshotNotFound"), + (await Assert.ThrowsAsync(() => context.Database.MigrateAsync())).Message); + } + + [ConditionalFact] + public void Throws_for_nondeterministic_HasData() + { + using var context = new BloggingContext( + Fixture.TestStore.AddProviderOptions( + new DbContextOptionsBuilder().EnableServiceProviderCaching(false)).Options, + randomData: true); + + context.Database.EnsureDeleted(); + GiveMeSomeTime(context); + + Assert.Equal( + CoreStrings.WarningAsErrorTemplate( + RelationalEventId.PendingModelChangesWarning.ToString(), + RelationalResources.LogNonDeterministicModel(new TestLogger()) + .GenerateMessage(nameof(BloggingContext)), + "RelationalEventId.PendingModelChangesWarning"), + (Assert.Throws(context.Database.Migrate)).Message); + } + + [ConditionalFact] + public async Task Throws_for_nondeterministic_HasData_async() + { + using var context = new BloggingContext( + Fixture.TestStore.AddProviderOptions( + new DbContextOptionsBuilder().EnableServiceProviderCaching(false)).Options, + randomData: true); + + await context.Database.EnsureDeletedAsync(); + await GiveMeSomeTimeAsync(context); + + Assert.Equal( + CoreStrings.WarningAsErrorTemplate( + RelationalEventId.PendingModelChangesWarning.ToString(), + RelationalResources.LogNonDeterministicModel(new TestLogger()) + .GenerateMessage(nameof(BloggingContext)), + "RelationalEventId.PendingModelChangesWarning"), + (await Assert.ThrowsAsync(() => context.Database.MigrateAsync())).Message); + } + [ConditionalFact] public void Throws_for_pending_model_changes() { using var context = new BloggingContext( Fixture.TestStore.AddProviderOptions( - new DbContextOptionsBuilder().EnableServiceProviderCaching(false)).Options); + new DbContextOptionsBuilder().EnableServiceProviderCaching(false)).Options, + randomData: false); + + context.Database.EnsureDeleted(); + GiveMeSomeTime(context); Assert.Equal( CoreStrings.WarningAsErrorTemplate( @@ -671,7 +796,11 @@ public async Task Throws_for_pending_model_changes_async() { using var context = new BloggingContext( Fixture.TestStore.AddProviderOptions( - new DbContextOptionsBuilder().EnableServiceProviderCaching(false)).Options); + new DbContextOptionsBuilder().EnableServiceProviderCaching(false)).Options, + randomData: false); + + await context.Database.EnsureDeletedAsync(); + await GiveMeSomeTimeAsync(context); Assert.Equal( CoreStrings.WarningAsErrorTemplate( @@ -755,7 +884,7 @@ FROM [__EFMigrationsHistory] ORDER BY [MigrationId]; INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) -VALUES (N'00000000000000_Empty', N'9.0.0'); +VALUES (N'00000000000000_Empty', N'7.0.0-test'); --Before @@ -798,18 +927,18 @@ CONSTRAINT [PK_Blogs] PRIMARY KEY ([Id]) END INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) -VALUES (N'00000000000001_Migration1', N'9.0.0'); +VALUES (N'00000000000001_Migration1', N'7.0.0-test'); --After INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) -VALUES (N'00000000000002_Migration2', N'9.0.0'); +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, + Fixture.TestSqlLoggerFactory.Sql.Replace(ProductInfo.GetVersion(), "7.0.0-test"), ignoreLineEndingDifferences: true); } @@ -867,7 +996,7 @@ FROM [__EFMigrationsHistory] ORDER BY [MigrationId]; INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) -VALUES (N'00000000000000_Empty', N'9.0.0'); +VALUES (N'00000000000000_Empty', N'7.0.0-test'); --Before @@ -910,22 +1039,22 @@ CONSTRAINT [PK_Blogs] PRIMARY KEY ([Id]) END INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) -VALUES (N'00000000000001_Migration1', N'9.0.0'); +VALUES (N'00000000000001_Migration1', N'7.0.0-test'); --After INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) -VALUES (N'00000000000002_Migration2', N'9.0.0'); +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, + Fixture.TestSqlLoggerFactory.Sql.Replace(ProductInfo.GetVersion(), "7.0.0-test"), ignoreLineEndingDifferences: true); } - private class BloggingContext(DbContextOptions options) : DbContext(options) + private class BloggingContext(DbContextOptions options, bool? randomData = null) : DbContext(options) { // ReSharper disable once UnusedMember.Local public DbSet Blogs { get; set; } @@ -939,6 +1068,46 @@ public class Blog public string Name { get; set; } // ReSharper restore UnusedMember.Local } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + if (randomData != null) + { + modelBuilder.Entity().HasData( + new Blog { Id = randomData.Value ? (int)new Random().NextInt64(int.MaxValue) : 1, Name = "HalfADonkey" }); + } + } + } + + [DbContext(typeof(BloggingContext))] + partial class BloggingContextSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "9.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Microsoft.EntityFrameworkCore.Migrations.MigrationsInfrastructureSqlServerTest+BloggingContext+Blog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Blogs"); + }); +#pragma warning restore 612, 618 + } } [DbContext(typeof(BloggingContext))] diff --git a/test/EFCore.SqlServer.FunctionalTests/Migrations/MigrationsSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Migrations/MigrationsSqlServerTest.cs index 65a90ea1f54..bce6e263c9a 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Migrations/MigrationsSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Migrations/MigrationsSqlServerTest.cs @@ -432,12 +432,12 @@ public override async Task Alter_table_change_comment() AssertSql( """ -DECLARE @defaultSchema AS sysname; -SET @defaultSchema = SCHEMA_NAME(); -DECLARE @description AS sql_variant; -EXEC sp_dropextendedproperty 'MS_Description', 'SCHEMA', @defaultSchema, 'TABLE', N'People'; -SET @description = N'Table comment2'; -EXEC sp_addextendedproperty 'MS_Description', @description, 'SCHEMA', @defaultSchema, 'TABLE', N'People'; +DECLARE @defaultSchema1 AS sysname; +SET @defaultSchema1 = SCHEMA_NAME(); +DECLARE @description1 AS sql_variant; +EXEC sp_dropextendedproperty 'MS_Description', 'SCHEMA', @defaultSchema1, 'TABLE', N'People'; +SET @description1 = N'Table comment2'; +EXEC sp_addextendedproperty 'MS_Description', @description1, 'SCHEMA', @defaultSchema1, 'TABLE', N'People'; """); } @@ -447,10 +447,10 @@ public override async Task Alter_table_remove_comment() AssertSql( """ -DECLARE @defaultSchema AS sysname; -SET @defaultSchema = SCHEMA_NAME(); -DECLARE @description AS sql_variant; -EXEC sp_dropextendedproperty 'MS_Description', 'SCHEMA', @defaultSchema, 'TABLE', N'People'; +DECLARE @defaultSchema1 AS sysname; +SET @defaultSchema1 = SCHEMA_NAME(); +DECLARE @description1 AS sql_variant; +EXEC sp_dropextendedproperty 'MS_Description', 'SCHEMA', @defaultSchema1, 'TABLE', N'People'; """); } @@ -1110,12 +1110,12 @@ public override async Task Alter_column_change_type() AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'SomeColumn'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] ALTER COLUMN [SomeColumn] bigint NOT NULL; """); } @@ -1126,12 +1126,12 @@ public override async Task Alter_column_make_required() AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'SomeColumn'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); UPDATE [People] SET [SomeColumn] = N'' WHERE [SomeColumn] IS NULL; ALTER TABLE [People] ALTER COLUMN [SomeColumn] nvarchar(max) NOT NULL; ALTER TABLE [People] ADD DEFAULT N'' FOR [SomeColumn]; @@ -1144,12 +1144,12 @@ public override async Task Alter_column_make_required_with_null_data() AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'SomeColumn'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); UPDATE [People] SET [SomeColumn] = N'' WHERE [SomeColumn] IS NULL; ALTER TABLE [People] ALTER COLUMN [SomeColumn] nvarchar(max) NOT NULL; ALTER TABLE [People] ADD DEFAULT N'' FOR [SomeColumn]; @@ -1164,12 +1164,12 @@ public override async Task Alter_column_make_required_with_index() AssertSql( """ DROP INDEX [IX_People_SomeColumn] ON [People]; -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'SomeColumn'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); UPDATE [People] SET [SomeColumn] = N'' WHERE [SomeColumn] IS NULL; ALTER TABLE [People] ALTER COLUMN [SomeColumn] nvarchar(450) NOT NULL; ALTER TABLE [People] ADD DEFAULT N'' FOR [SomeColumn]; @@ -1185,12 +1185,12 @@ public override async Task Alter_column_make_required_with_composite_index() AssertSql( """ DROP INDEX [IX_People_FirstName_LastName] ON [People]; -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'FirstName'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); UPDATE [People] SET [FirstName] = N'' WHERE [FirstName] IS NULL; ALTER TABLE [People] ALTER COLUMN [FirstName] nvarchar(450) NOT NULL; ALTER TABLE [People] ADD DEFAULT N'' FOR [FirstName]; @@ -1206,12 +1206,12 @@ public override async Task Alter_column_make_computed(bool? stored) AssertSql( $""" -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'Sum'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] DROP COLUMN [Sum]; ALTER TABLE [People] ADD [Sum] AS [X] + [Y]{computedColumnTypeSql}; """); @@ -1223,12 +1223,12 @@ public override async Task Alter_column_change_computed() AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'Sum'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] DROP COLUMN [Sum]; ALTER TABLE [People] ADD [Sum] AS [X] - [Y]; """); @@ -1241,12 +1241,12 @@ public override async Task Alter_column_change_computed_recreates_indexes() AssertSql( """ DROP INDEX [IX_People_Sum] ON [People]; -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'Sum'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] DROP COLUMN [Sum]; ALTER TABLE [People] ADD [Sum] AS [X] - [Y]; """, @@ -1262,12 +1262,12 @@ public override async Task Alter_column_change_computed_type() AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'Sum'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] DROP COLUMN [Sum]; ALTER TABLE [People] ADD [Sum] AS [X] + [Y] PERSISTED; """); @@ -1279,12 +1279,12 @@ public override async Task Alter_column_make_non_computed() AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'Sum'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] DROP COLUMN [Sum]; ALTER TABLE [People] ADD [Sum] int NOT NULL; """); @@ -1327,12 +1327,12 @@ public override async Task Alter_column_change_comment() AssertSql( """ -DECLARE @defaultSchema AS sysname; -SET @defaultSchema = SCHEMA_NAME(); -DECLARE @description AS sql_variant; -EXEC sp_dropextendedproperty 'MS_Description', 'SCHEMA', @defaultSchema, 'TABLE', N'People', 'COLUMN', N'Id'; -SET @description = N'Some comment2'; -EXEC sp_addextendedproperty 'MS_Description', @description, 'SCHEMA', @defaultSchema, 'TABLE', N'People', 'COLUMN', N'Id'; +DECLARE @defaultSchema1 AS sysname; +SET @defaultSchema1 = SCHEMA_NAME(); +DECLARE @description1 AS sql_variant; +EXEC sp_dropextendedproperty 'MS_Description', 'SCHEMA', @defaultSchema1, 'TABLE', N'People', 'COLUMN', N'Id'; +SET @description1 = N'Some comment2'; +EXEC sp_addextendedproperty 'MS_Description', @description1, 'SCHEMA', @defaultSchema1, 'TABLE', N'People', 'COLUMN', N'Id'; """); } @@ -1343,10 +1343,10 @@ public override async Task Alter_column_remove_comment() AssertSql( """ -DECLARE @defaultSchema AS sysname; -SET @defaultSchema = SCHEMA_NAME(); -DECLARE @description AS sql_variant; -EXEC sp_dropextendedproperty 'MS_Description', 'SCHEMA', @defaultSchema, 'TABLE', N'People', 'COLUMN', N'Id'; +DECLARE @defaultSchema1 AS sysname; +SET @defaultSchema1 = SCHEMA_NAME(); +DECLARE @description1 AS sql_variant; +EXEC sp_dropextendedproperty 'MS_Description', 'SCHEMA', @defaultSchema1, 'TABLE', N'People', 'COLUMN', N'Id'; """); } @@ -1357,12 +1357,12 @@ public override async Task Alter_column_set_collation() AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] ALTER COLUMN [Name] nvarchar(max) COLLATE German_PhoneBook_CI_AS NULL; """); } @@ -1389,12 +1389,12 @@ await Test( AssertSql( """ DROP INDEX [IX_People_Name] ON [People]; -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] ALTER COLUMN [Name] nvarchar(450) COLLATE German_PhoneBook_CI_AS NULL; CREATE INDEX [IX_People_Name] ON [People] ([Name]); """); @@ -1407,12 +1407,12 @@ public override async Task Alter_column_reset_collation() AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] ALTER COLUMN [Name] nvarchar(max) NULL; """); } @@ -1423,12 +1423,12 @@ public override async Task Convert_json_entities_to_regular_owned() AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Entity]') AND [c].[name] = N'OwnedCollection'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Entity] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [Entity] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [Entity] DROP COLUMN [OwnedCollection]; """, // @@ -1501,12 +1501,12 @@ public override async Task Convert_regular_owned_entities_to_json() """, // """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Entity]') AND [c].[name] = N'OwnedReference_Date'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Entity] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [Entity] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [Entity] DROP COLUMN [OwnedReference_Date]; """, // @@ -1542,12 +1542,12 @@ public override async Task Convert_string_column_to_a_json_column_containing_req AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Entity]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Entity] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [Entity] DROP CONSTRAINT [' + @var + '];'); UPDATE [Entity] SET [Name] = N'{}' WHERE [Name] IS NULL; ALTER TABLE [Entity] ALTER COLUMN [Name] nvarchar(max) NOT NULL; ALTER TABLE [Entity] ADD DEFAULT N'{}' FOR [Name]; @@ -1590,12 +1590,12 @@ await Test( AssertSql( """ DROP INDEX [IX_People_SomeColumn] ON [People]; -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'SomeColumn'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); UPDATE [People] SET [SomeColumn] = N'' WHERE [SomeColumn] IS NULL; ALTER TABLE [People] ALTER COLUMN [SomeColumn] nvarchar(450) NOT NULL; ALTER TABLE [People] ADD DEFAULT N'' FOR [SomeColumn]; @@ -1629,12 +1629,12 @@ await Test( AssertSql( """ ALTER TABLE [People] DROP INDEX [IX_People_Name]; -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] ALTER COLUMN [Name] nvarchar(30) NULL; ALTER TABLE [People] ADD INDEX [IX_People_Name] NONCLUSTERED ([Name]); """); @@ -1662,12 +1662,12 @@ await Test( AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] ALTER COLUMN [Name] nvarchar(450) NULL; """); } @@ -1701,12 +1701,12 @@ await Test( AssertSql( """ DROP INDEX [IX_People_FirstName_LastName] ON [People]; -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] ALTER COLUMN [Name] nvarchar(30) NULL; CREATE INDEX [IX_People_FirstName_LastName] ON [People] ([FirstName], [LastName]) INCLUDE ([Name]); """); @@ -1758,12 +1758,12 @@ await Test( AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'IdentityColumn'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] ALTER COLUMN [IdentityColumn] bigint NOT NULL; """); } @@ -1803,12 +1803,12 @@ await Test( AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] ADD DEFAULT N'Doe' FOR [Name]; """); } @@ -1854,12 +1854,12 @@ await Test( AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'SomeProperty'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] ALTER COLUMN [SomeProperty] nvarchar(max) SPARSE NULL; """); } @@ -1870,12 +1870,12 @@ public override async Task Drop_column() AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'SomeColumn'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] DROP COLUMN [SomeColumn]; """); } @@ -1890,12 +1890,12 @@ public override async Task Drop_column_primary_key() """, // """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'Id'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] DROP COLUMN [Id]; """); } @@ -1906,12 +1906,12 @@ public override async Task Drop_column_computed_and_non_computed_with_dependency AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'Y'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] DROP COLUMN [Y]; """, // @@ -1932,12 +1932,12 @@ public override async Task Drop_json_columns_from_existing_table() AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Entity]') AND [c].[name] = N'OwnedCollection'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Entity] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [Entity] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [Entity] DROP COLUMN [OwnedCollection]; """, // @@ -1982,12 +1982,12 @@ public override async Task Create_index() AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'FirstName'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] ALTER COLUMN [FirstName] nvarchar(450) NULL; """, // @@ -2002,12 +2002,12 @@ public override async Task Create_index_unique() AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'LastName'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] ALTER COLUMN [LastName] nvarchar(450) NULL; """, // @@ -2080,12 +2080,12 @@ public override async Task Create_index_with_filter() AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] ALTER COLUMN [Name] nvarchar(450) NULL; """, // @@ -2117,12 +2117,12 @@ await Test( AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] ALTER COLUMN [Name] nvarchar(450) NULL; """, // @@ -2137,12 +2137,12 @@ public override async Task Create_unique_index_with_filter() AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] ALTER COLUMN [Name] nvarchar(450) NULL; """, // @@ -2168,12 +2168,12 @@ await Test( AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'FirstName'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] ALTER COLUMN [FirstName] nvarchar(450) NULL; """, // @@ -2201,12 +2201,12 @@ await Test( AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'FirstName'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] ALTER COLUMN [FirstName] nvarchar(450) NULL; """, // @@ -2242,12 +2242,12 @@ await Test( AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] ALTER COLUMN [Name] nvarchar(450) NULL; """, // @@ -2285,12 +2285,12 @@ await Test( AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] ALTER COLUMN [Name] nvarchar(450) NULL; """, // @@ -2328,12 +2328,12 @@ await Test( AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] ALTER COLUMN [Name] nvarchar(450) NOT NULL; """, // @@ -2373,12 +2373,12 @@ await Test( AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] ALTER COLUMN [Name] nvarchar(450) NOT NULL; """, // @@ -2421,12 +2421,12 @@ await Test( AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] ALTER COLUMN [Name] nvarchar(450) NOT NULL; """, // @@ -2470,12 +2470,12 @@ await Test( AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] ALTER COLUMN [Name] nvarchar(450) NOT NULL; """, // @@ -2517,12 +2517,12 @@ await Test( AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] ALTER COLUMN [Name] nvarchar(450) NOT NULL; """, // @@ -2565,12 +2565,12 @@ await Test( AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] ALTER COLUMN [Name] nvarchar(450) NOT NULL; """, // @@ -2618,12 +2618,12 @@ await Test( AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] ALTER COLUMN [Name] nvarchar(450) NOT NULL; """, // @@ -2657,12 +2657,12 @@ await Test( AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] ALTER COLUMN [Name] nvarchar(450) NULL; """, // @@ -2697,12 +2697,12 @@ await Test( AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] ALTER COLUMN [Name] nvarchar(450) NULL; """, // @@ -2773,12 +2773,12 @@ public override async Task Add_primary_key_string() AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'SomeField'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] ALTER COLUMN [SomeField] nvarchar(450) NOT NULL; """, // @@ -2793,12 +2793,12 @@ public override async Task Add_primary_key_with_name() AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'SomeField'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); UPDATE [People] SET [SomeField] = N'' WHERE [SomeField] IS NULL; ALTER TABLE [People] ALTER COLUMN [SomeField] nvarchar(450) NOT NULL; ALTER TABLE [People] ADD DEFAULT N'' FOR [SomeField]; @@ -2903,12 +2903,12 @@ public override async Task Drop_primary_key_string() """, // """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'SomeField'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] ALTER COLUMN [SomeField] nvarchar(max) NOT NULL; """); } @@ -3255,12 +3255,12 @@ await Test( AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'SeqProp'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] DROP COLUMN [SeqProp]; """, // @@ -4437,8 +4437,8 @@ ALTER TABLE [Customers] SET (SYSTEM_VERSIONING = OFF) """, // """ -DECLARE @historyTableSchema sysname = SCHEMA_NAME() -EXEC(N'ALTER TABLE [RenamedCustomers] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema + '].[HistoryTable]))') +DECLARE @historyTableSchema1 sysname = SCHEMA_NAME() +EXEC(N'ALTER TABLE [RenamedCustomers] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema1 + '].[HistoryTable]))') """); } @@ -4519,19 +4519,19 @@ ALTER TABLE [Customers] SET (SYSTEM_VERSIONING = OFF) """, // """ -DECLARE @defaultSchema AS sysname; -SET @defaultSchema = SCHEMA_NAME(); -DECLARE @description AS sql_variant; -SET @description = N'for VIP only'; -EXEC sp_addextendedproperty 'MS_Description', @description, 'SCHEMA', @defaultSchema, 'TABLE', N'RenamedCustomers', 'COLUMN', N'Discount'; +DECLARE @defaultSchema2 AS sysname; +SET @defaultSchema2 = SCHEMA_NAME(); +DECLARE @description2 AS sql_variant; +SET @description2 = N'for VIP only'; +EXEC sp_addextendedproperty 'MS_Description', @description2, 'SCHEMA', @defaultSchema2, 'TABLE', N'RenamedCustomers', 'COLUMN', N'Discount'; """, // """ -DECLARE @defaultSchema AS sysname; -SET @defaultSchema = SCHEMA_NAME(); -DECLARE @description AS sql_variant; -SET @description = N'for VIP only'; -EXEC sp_addextendedproperty 'MS_Description', @description, 'SCHEMA', @defaultSchema, 'TABLE', N'HistoryTable', 'COLUMN', N'Discount'; +DECLARE @defaultSchema3 AS sysname; +SET @defaultSchema3 = SCHEMA_NAME(); +DECLARE @description3 AS sql_variant; +SET @description3 = N'for VIP only'; +EXEC sp_addextendedproperty 'MS_Description', @description3, 'SCHEMA', @defaultSchema3, 'TABLE', N'HistoryTable', 'COLUMN', N'Discount'; """, // """ @@ -4539,8 +4539,8 @@ ALTER TABLE [Customers] SET (SYSTEM_VERSIONING = OFF) """, // """ -DECLARE @historyTableSchema sysname = SCHEMA_NAME() -EXEC(N'ALTER TABLE [RenamedCustomers] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema + '].[HistoryTable]))') +DECLARE @historyTableSchema1 sysname = SCHEMA_NAME() +EXEC(N'ALTER TABLE [RenamedCustomers] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema1 + '].[HistoryTable]))') """); } @@ -5356,48 +5356,48 @@ ALTER TABLE [Customers] SET (SYSTEM_VERSIONING = OFF) """, // """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var2 sysname; +SELECT @var2 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customers]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var0 + '];'); +IF @var2 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var2 + '];'); ALTER TABLE [Customers] DROP COLUMN [Name]; """, // """ -DECLARE @var1 sysname; -SELECT @var1 = [d].[name] +DECLARE @var3 sysname; +SELECT @var3 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[HistoryTable]') AND [c].[name] = N'Name'); -IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [HistoryTable] DROP CONSTRAINT [' + @var1 + '];'); +IF @var3 IS NOT NULL EXEC(N'ALTER TABLE [HistoryTable] DROP CONSTRAINT [' + @var3 + '];'); ALTER TABLE [HistoryTable] DROP COLUMN [Name]; """, // """ -DECLARE @var2 sysname; -SELECT @var2 = [d].[name] +DECLARE @var4 sysname; +SELECT @var4 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customers]') AND [c].[name] = N'Number'); -IF @var2 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var2 + '];'); +IF @var4 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var4 + '];'); ALTER TABLE [Customers] DROP COLUMN [Number]; """, // """ -DECLARE @var3 sysname; -SELECT @var3 = [d].[name] +DECLARE @var5 sysname; +SELECT @var5 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[HistoryTable]') AND [c].[name] = N'Number'); -IF @var3 IS NOT NULL EXEC(N'ALTER TABLE [HistoryTable] DROP CONSTRAINT [' + @var3 + '];'); +IF @var5 IS NOT NULL EXEC(N'ALTER TABLE [HistoryTable] DROP CONSTRAINT [' + @var5 + '];'); ALTER TABLE [HistoryTable] DROP COLUMN [Number]; """, // """ -DECLARE @historyTableSchema sysname = SCHEMA_NAME() -EXEC(N'ALTER TABLE [Customers] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema + '].[HistoryTable]))') +DECLARE @historyTableSchema1 sysname = SCHEMA_NAME() +EXEC(N'ALTER TABLE [Customers] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema1 + '].[HistoryTable]))') """); } @@ -5454,12 +5454,12 @@ ALTER TABLE [Customers] SET (SYSTEM_VERSIONING = OFF) """, // """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customers]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [Customers] DROP COLUMN [Name]; """, // @@ -5551,12 +5551,12 @@ ALTER TABLE [mySchema].[Customers] SET (SYSTEM_VERSIONING = OFF) """, // """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[mySchema].[Customers]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [mySchema].[Customers] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [mySchema].[Customers] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [mySchema].[Customers] DROP COLUMN [Name]; """, // @@ -5652,12 +5652,12 @@ ALTER TABLE [mySchema].[Customers] SET (SYSTEM_VERSIONING = OFF) """, // """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[mySchema].[Customers]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [mySchema].[Customers] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [mySchema].[Customers] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [mySchema].[Customers] DROP COLUMN [Name]; """, // @@ -5753,12 +5753,12 @@ ALTER TABLE [mySchema].[Customers] SET (SYSTEM_VERSIONING = OFF) """, // """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[mySchema].[Customers]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [mySchema].[Customers] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [mySchema].[Customers] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [mySchema].[Customers] DROP COLUMN [Name]; """, // @@ -5972,22 +5972,22 @@ ALTER TABLE [Customer] DROP PERIOD FOR SYSTEM_TIME """, // """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var1 sysname; +SELECT @var1 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customer]') AND [c].[name] = N'PeriodEnd'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Customer] DROP CONSTRAINT [' + @var0 + '];'); +IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [Customer] DROP CONSTRAINT [' + @var1 + '];'); ALTER TABLE [Customer] DROP COLUMN [PeriodEnd]; """, // """ -DECLARE @var1 sysname; -SELECT @var1 = [d].[name] +DECLARE @var2 sysname; +SELECT @var2 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customer]') AND [c].[name] = N'PeriodStart'); -IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [Customer] DROP CONSTRAINT [' + @var1 + '];'); +IF @var2 IS NOT NULL EXEC(N'ALTER TABLE [Customer] DROP CONSTRAINT [' + @var2 + '];'); ALTER TABLE [Customer] DROP COLUMN [PeriodStart]; """, // @@ -6051,22 +6051,22 @@ ALTER TABLE [Customer] DROP PERIOD FOR SYSTEM_TIME """, // """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var1 sysname; +SELECT @var1 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customer]') AND [c].[name] = N'PeriodEnd'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Customer] DROP CONSTRAINT [' + @var0 + '];'); +IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [Customer] DROP CONSTRAINT [' + @var1 + '];'); ALTER TABLE [Customer] DROP COLUMN [PeriodEnd]; """, // """ -DECLARE @var1 sysname; -SELECT @var1 = [d].[name] +DECLARE @var2 sysname; +SELECT @var2 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customer]') AND [c].[name] = N'PeriodStart'); -IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [Customer] DROP CONSTRAINT [' + @var1 + '];'); +IF @var2 IS NOT NULL EXEC(N'ALTER TABLE [Customer] DROP CONSTRAINT [' + @var2 + '];'); ALTER TABLE [Customer] DROP COLUMN [PeriodStart]; """, // @@ -6926,11 +6926,11 @@ await Test( AssertSql( """ -DECLARE @defaultSchema AS sysname; -SET @defaultSchema = SCHEMA_NAME(); -DECLARE @description AS sql_variant; -SET @description = N'My comment'; -EXEC sp_addextendedproperty 'MS_Description', @description, 'SCHEMA', @defaultSchema, 'TABLE', N'Customers', 'COLUMN', N'End'; +DECLARE @defaultSchema1 AS sysname; +SET @defaultSchema1 = SCHEMA_NAME(); +DECLARE @description1 AS sql_variant; +SET @description1 = N'My comment'; +EXEC sp_addextendedproperty 'MS_Description', @description1, 'SCHEMA', @defaultSchema1, 'TABLE', N'Customers', 'COLUMN', N'End'; """); } @@ -7050,32 +7050,32 @@ ALTER TABLE [Customer] SET (SYSTEM_VERSIONING = OFF) """, // """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var2 sysname; +SELECT @var2 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customer]') AND [c].[name] = N'IsVip'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Customer] DROP CONSTRAINT [' + @var0 + '];'); +IF @var2 IS NOT NULL EXEC(N'ALTER TABLE [Customer] DROP CONSTRAINT [' + @var2 + '];'); UPDATE [Customer] SET [IsVip] = CAST(0 AS bit) WHERE [IsVip] IS NULL; 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] +DECLARE @var3 sysname; +SELECT @var3 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[HistoryTable]') AND [c].[name] = N'IsVip'); -IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [HistoryTable] DROP CONSTRAINT [' + @var1 + '];'); +IF @var3 IS NOT NULL EXEC(N'ALTER TABLE [HistoryTable] DROP CONSTRAINT [' + @var3 + '];'); UPDATE [HistoryTable] SET [IsVip] = CAST(0 AS bit) WHERE [IsVip] IS NULL; 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]))') +DECLARE @historyTableSchema1 sysname = SCHEMA_NAME() +EXEC(N'ALTER TABLE [Customer] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema1 + '].[HistoryTable]))') """); } @@ -7196,8 +7196,8 @@ ALTER TABLE [Customer] SET (SYSTEM_VERSIONING = OFF) """, // """ -DECLARE @historyTableSchema sysname = SCHEMA_NAME() -EXEC(N'ALTER TABLE [Customer] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema + '].[HistoryTable]))') +DECLARE @historyTableSchema1 sysname = SCHEMA_NAME() +EXEC(N'ALTER TABLE [Customer] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema1 + '].[HistoryTable]))') """); } @@ -7260,8 +7260,8 @@ ALTER TABLE [Customer] SET (SYSTEM_VERSIONING = OFF) """, // """ -DECLARE @historyTableSchema sysname = SCHEMA_NAME() -EXEC(N'ALTER TABLE [Customer] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema + '].[HistoryTable]))') +DECLARE @historyTableSchema1 sysname = SCHEMA_NAME() +EXEC(N'ALTER TABLE [Customer] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema1 + '].[HistoryTable]))') """); } @@ -7315,28 +7315,28 @@ ALTER TABLE [Customer] SET (SYSTEM_VERSIONING = OFF) """, // """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var2 sysname; +SELECT @var2 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customer]') AND [c].[name] = N'IdPlusFive'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Customer] DROP CONSTRAINT [' + @var0 + '];'); +IF @var2 IS NOT NULL EXEC(N'ALTER TABLE [Customer] DROP CONSTRAINT [' + @var2 + '];'); ALTER TABLE [Customer] DROP COLUMN [IdPlusFive]; """, // """ -DECLARE @var1 sysname; -SELECT @var1 = [d].[name] +DECLARE @var3 sysname; +SELECT @var3 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[HistoryTable]') AND [c].[name] = N'IdPlusFive'); -IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [HistoryTable] DROP CONSTRAINT [' + @var1 + '];'); +IF @var3 IS NOT NULL EXEC(N'ALTER TABLE [HistoryTable] DROP CONSTRAINT [' + @var3 + '];'); ALTER TABLE [HistoryTable] DROP COLUMN [IdPlusFive]; """, // """ -DECLARE @historyTableSchema sysname = SCHEMA_NAME() -EXEC(N'ALTER TABLE [Customer] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema + '].[HistoryTable]))') +DECLARE @historyTableSchema1 sysname = SCHEMA_NAME() +EXEC(N'ALTER TABLE [Customer] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema1 + '].[HistoryTable]))') """); } @@ -7506,28 +7506,28 @@ ALTER TABLE [Customer] SET (SYSTEM_VERSIONING = OFF) """, // """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var2 sysname; +SELECT @var2 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customer]') AND [c].[name] = N'Number'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Customer] DROP CONSTRAINT [' + @var0 + '];'); +IF @var2 IS NOT NULL EXEC(N'ALTER TABLE [Customer] DROP CONSTRAINT [' + @var2 + '];'); ALTER TABLE [Customer] DROP COLUMN [Number]; """, // """ -DECLARE @var1 sysname; -SELECT @var1 = [d].[name] +DECLARE @var3 sysname; +SELECT @var3 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[HistoryTable]') AND [c].[name] = N'Number'); -IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [HistoryTable] DROP CONSTRAINT [' + @var1 + '];'); +IF @var3 IS NOT NULL EXEC(N'ALTER TABLE [HistoryTable] DROP CONSTRAINT [' + @var3 + '];'); ALTER TABLE [HistoryTable] DROP COLUMN [Number]; """, // """ -DECLARE @historyTableSchema sysname = SCHEMA_NAME() -EXEC(N'ALTER TABLE [Customer] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema + '].[HistoryTable]))') +DECLARE @historyTableSchema1 sysname = SCHEMA_NAME() +EXEC(N'ALTER TABLE [Customer] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema1 + '].[HistoryTable]))') """); } @@ -7652,8 +7652,8 @@ IF EXISTS (SELECT 1 FROM [sys].[tables] [t] INNER JOIN [sys].[partitions] [p] ON """, // """ -DECLARE @historyTableSchema sysname = SCHEMA_NAME() -EXEC(N'ALTER TABLE [Customer] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema + '].[HistoryTable]))') +DECLARE @historyTableSchema1 sysname = SCHEMA_NAME() +EXEC(N'ALTER TABLE [Customer] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema1 + '].[HistoryTable]))') """); } @@ -7793,28 +7793,28 @@ IF EXISTS (SELECT 1 FROM [sys].[tables] [t] INNER JOIN [sys].[partitions] [p] ON """, // """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var2 sysname; +SELECT @var2 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customer]') AND [c].[name] = N'MyColumn'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Customer] DROP CONSTRAINT [' + @var0 + '];'); +IF @var2 IS NOT NULL EXEC(N'ALTER TABLE [Customer] DROP CONSTRAINT [' + @var2 + '];'); ALTER TABLE [Customer] ALTER COLUMN [MyColumn] int SPARSE NULL; """, // """ -DECLARE @var1 sysname; -SELECT @var1 = [d].[name] +DECLARE @var3 sysname; +SELECT @var3 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[HistoryTable]') AND [c].[name] = N'MyColumn'); -IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [HistoryTable] DROP CONSTRAINT [' + @var1 + '];'); +IF @var3 IS NOT NULL EXEC(N'ALTER TABLE [HistoryTable] DROP CONSTRAINT [' + @var3 + '];'); 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]))') +DECLARE @historyTableSchema1 sysname = SCHEMA_NAME() +EXEC(N'ALTER TABLE [Customer] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema1 + '].[HistoryTable]))') """); } @@ -7874,12 +7874,12 @@ await Test( AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var1 sysname; +SELECT @var1 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customer]') AND [c].[name] = N'MyColumn'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Customer] DROP CONSTRAINT [' + @var0 + '];'); +IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [Customer] DROP CONSTRAINT [' + @var1 + '];'); ALTER TABLE [Customer] ALTER COLUMN [MyColumn] int NULL; """); } @@ -8017,13 +8017,13 @@ [Name] nvarchar(max) NULL, CONSTRAINT [PK_Customer] PRIMARY KEY ([Id]), PERIOD FOR SYSTEM_TIME([SystemTimeStart], [SystemTimeEnd]) ) WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema + N'].[CustomerHistory]))'); -DECLARE @defaultSchema AS sysname; -SET @defaultSchema = SCHEMA_NAME(); -DECLARE @description AS sql_variant; -SET @description = N'Table comment'; -EXEC sp_addextendedproperty 'MS_Description', @description, 'SCHEMA', @defaultSchema, 'TABLE', N'Customer'; -SET @description = N'Column comment'; -EXEC sp_addextendedproperty 'MS_Description', @description, 'SCHEMA', @defaultSchema, 'TABLE', N'Customer', 'COLUMN', N'Name'; +DECLARE @defaultSchema1 AS sysname; +SET @defaultSchema1 = SCHEMA_NAME(); +DECLARE @description1 AS sql_variant; +SET @description1 = N'Table comment'; +EXEC sp_addextendedproperty 'MS_Description', @description1, 'SCHEMA', @defaultSchema1, 'TABLE', N'Customer'; +SET @description1 = N'Column comment'; +EXEC sp_addextendedproperty 'MS_Description', @description1, 'SCHEMA', @defaultSchema1, 'TABLE', N'Customer', 'COLUMN', N'Name'; """); } @@ -8077,18 +8077,18 @@ await Test( AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var1 sysname; +SELECT @var1 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customer]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Customer] DROP CONSTRAINT [' + @var0 + '];'); +IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [Customer] DROP CONSTRAINT [' + @var1 + '];'); ALTER TABLE [Customer] ALTER COLUMN [Name] nvarchar(450) NULL; -DECLARE @defaultSchema AS sysname; -SET @defaultSchema = SCHEMA_NAME(); -DECLARE @description AS sql_variant; -SET @description = N'Column comment'; -EXEC sp_addextendedproperty 'MS_Description', @description, 'SCHEMA', @defaultSchema, 'TABLE', N'Customer', 'COLUMN', N'Name'; +DECLARE @defaultSchema2 AS sysname; +SET @defaultSchema2 = SCHEMA_NAME(); +DECLARE @description2 AS sql_variant; +SET @description2 = N'Column comment'; +EXEC sp_addextendedproperty 'MS_Description', @description2, 'SCHEMA', @defaultSchema2, 'TABLE', N'Customer', 'COLUMN', N'Name'; """, // """ @@ -8174,21 +8174,21 @@ await Test( AssertSql( """ -DECLARE @defaultSchema AS sysname; -SET @defaultSchema = SCHEMA_NAME(); -DECLARE @description AS sql_variant; -EXEC sp_dropextendedproperty 'MS_Description', 'SCHEMA', @defaultSchema, 'TABLE', N'Customer'; -SET @description = N'Modified table comment'; -EXEC sp_addextendedproperty 'MS_Description', @description, 'SCHEMA', @defaultSchema, 'TABLE', N'Customer'; +DECLARE @defaultSchema2 AS sysname; +SET @defaultSchema2 = SCHEMA_NAME(); +DECLARE @description2 AS sql_variant; +EXEC sp_dropextendedproperty 'MS_Description', 'SCHEMA', @defaultSchema2, 'TABLE', N'Customer'; +SET @description2 = N'Modified table comment'; +EXEC sp_addextendedproperty 'MS_Description', @description2, 'SCHEMA', @defaultSchema2, 'TABLE', N'Customer'; """, // """ -DECLARE @defaultSchema AS sysname; -SET @defaultSchema = SCHEMA_NAME(); -DECLARE @description AS sql_variant; -EXEC sp_dropextendedproperty 'MS_Description', 'SCHEMA', @defaultSchema, 'TABLE', N'Customer', 'COLUMN', N'Name'; -SET @description = N'Modified column comment'; -EXEC sp_addextendedproperty 'MS_Description', @description, 'SCHEMA', @defaultSchema, 'TABLE', N'Customer', 'COLUMN', N'Name'; +DECLARE @defaultSchema3 AS sysname; +SET @defaultSchema3 = SCHEMA_NAME(); +DECLARE @description3 AS sql_variant; +EXEC sp_dropextendedproperty 'MS_Description', 'SCHEMA', @defaultSchema3, 'TABLE', N'Customer', 'COLUMN', N'Name'; +SET @description3 = N'Modified column comment'; +EXEC sp_addextendedproperty 'MS_Description', @description3, 'SCHEMA', @defaultSchema3, 'TABLE', N'Customer', 'COLUMN', N'Name'; """); } @@ -8244,12 +8244,12 @@ await Test( AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var1 sysname; +SELECT @var1 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customers]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var0 + '];'); +IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var1 + '];'); ALTER TABLE [Customers] ALTER COLUMN [Name] nvarchar(450) NULL; """, // @@ -8316,12 +8316,12 @@ await Test( AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var1 sysname; +SELECT @var1 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customers]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var0 + '];'); +IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var1 + '];'); ALTER TABLE [Customers] ALTER COLUMN [Name] nvarchar(450) NULL; """, // @@ -8804,22 +8804,22 @@ ALTER TABLE [Customers] SET (SYSTEM_VERSIONING = OFF) """, // """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var2 sysname; +SELECT @var2 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customers]') AND [c].[name] = N'Number'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var0 + '];'); +IF @var2 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var2 + '];'); ALTER TABLE [Customers] DROP COLUMN [Number]; """, // """ -DECLARE @var1 sysname; -SELECT @var1 = [d].[name] +DECLARE @var3 sysname; +SELECT @var3 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[HistoryTable]') AND [c].[name] = N'Number'); -IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [HistoryTable] DROP CONSTRAINT [' + @var1 + '];'); +IF @var3 IS NOT NULL EXEC(N'ALTER TABLE [HistoryTable] DROP CONSTRAINT [' + @var3 + '];'); ALTER TABLE [HistoryTable] DROP COLUMN [Number]; """, // @@ -8840,8 +8840,8 @@ FROM [sys].[default_constraints] [d] """, // """ -DECLARE @historyTableSchema sysname = SCHEMA_NAME() -EXEC(N'ALTER TABLE [Customers] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema + '].[HistoryTable]))') +DECLARE @historyTableSchema1 sysname = SCHEMA_NAME() +EXEC(N'ALTER TABLE [Customers] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema1 + '].[HistoryTable]))') """); } @@ -8916,22 +8916,22 @@ ALTER TABLE [Customers] SET (SYSTEM_VERSIONING = OFF) """, // """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var2 sysname; +SELECT @var2 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customers]') AND [c].[name] = N'Number'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var0 + '];'); +IF @var2 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var2 + '];'); ALTER TABLE [Customers] DROP COLUMN [Number]; """, // """ -DECLARE @var1 sysname; -SELECT @var1 = [d].[name] +DECLARE @var3 sysname; +SELECT @var3 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[HistoryTable]') AND [c].[name] = N'Number'); -IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [HistoryTable] DROP CONSTRAINT [' + @var1 + '];'); +IF @var3 IS NOT NULL EXEC(N'ALTER TABLE [HistoryTable] DROP CONSTRAINT [' + @var3 + '];'); ALTER TABLE [HistoryTable] DROP COLUMN [Number]; """, // @@ -8952,8 +8952,8 @@ FROM [sys].[default_constraints] [d] """, // """ -DECLARE @historyTableSchema sysname = SCHEMA_NAME() -EXEC(N'ALTER TABLE [ModifiedCustomers] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema + '].[HistoryTable]))') +DECLARE @historyTableSchema1 sysname = SCHEMA_NAME() +EXEC(N'ALTER TABLE [ModifiedCustomers] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema1 + '].[HistoryTable]))') """); } @@ -9024,22 +9024,22 @@ ALTER TABLE [Customers] SET (SYSTEM_VERSIONING = OFF) """, // """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var2 sysname; +SELECT @var2 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customers]') AND [c].[name] = N'Number'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var0 + '];'); +IF @var2 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var2 + '];'); ALTER TABLE [Customers] DROP COLUMN [Number]; """, // """ -DECLARE @var1 sysname; -SELECT @var1 = [d].[name] +DECLARE @var3 sysname; +SELECT @var3 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[HistoryTable]') AND [c].[name] = N'Number'); -IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [HistoryTable] DROP CONSTRAINT [' + @var1 + '];'); +IF @var3 IS NOT NULL EXEC(N'ALTER TABLE [HistoryTable] DROP CONSTRAINT [' + @var3 + '];'); ALTER TABLE [HistoryTable] DROP COLUMN [Number]; """, // @@ -9056,8 +9056,8 @@ FROM [sys].[default_constraints] [d] """, // """ -DECLARE @historyTableSchema sysname = SCHEMA_NAME() -EXEC(N'ALTER TABLE [Customers] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema + '].[ModifiedHistoryTable]))') +DECLARE @historyTableSchema1 sysname = SCHEMA_NAME() +EXEC(N'ALTER TABLE [Customers] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema1 + '].[ModifiedHistoryTable]))') """); } @@ -9119,22 +9119,22 @@ ALTER TABLE [Customers] SET (SYSTEM_VERSIONING = OFF) """, // """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var2 sysname; +SELECT @var2 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customers]') AND [c].[name] = N'Number'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var0 + '];'); +IF @var2 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var2 + '];'); ALTER TABLE [Customers] DROP COLUMN [Number]; """, // """ -DECLARE @var1 sysname; -SELECT @var1 = [d].[name] +DECLARE @var3 sysname; +SELECT @var3 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[HistoryTable]') AND [c].[name] = N'Number'); -IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [HistoryTable] DROP CONSTRAINT [' + @var1 + '];'); +IF @var3 IS NOT NULL EXEC(N'ALTER TABLE [HistoryTable] DROP CONSTRAINT [' + @var3 + '];'); ALTER TABLE [HistoryTable] DROP COLUMN [Number]; """, // @@ -9147,8 +9147,8 @@ FROM [sys].[default_constraints] [d] """, // """ -DECLARE @historyTableSchema sysname = SCHEMA_NAME() -EXEC(N'ALTER TABLE [Customers] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema + '].[HistoryTable]))') +DECLARE @historyTableSchema1 sysname = SCHEMA_NAME() +EXEC(N'ALTER TABLE [Customers] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema1 + '].[HistoryTable]))') """); } @@ -9211,44 +9211,44 @@ ALTER TABLE [Customers] SET (SYSTEM_VERSIONING = OFF) """, // """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var2 sysname; +SELECT @var2 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customers]') AND [c].[name] = N'Number'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var0 + '];'); +IF @var2 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var2 + '];'); ALTER TABLE [Customers] DROP COLUMN [Number]; """, // """ -DECLARE @var1 sysname; -SELECT @var1 = [d].[name] +DECLARE @var3 sysname; +SELECT @var3 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[HistoryTable]') AND [c].[name] = N'Number'); -IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [HistoryTable] DROP CONSTRAINT [' + @var1 + '];'); +IF @var3 IS NOT NULL EXEC(N'ALTER TABLE [HistoryTable] DROP CONSTRAINT [' + @var3 + '];'); ALTER TABLE [HistoryTable] DROP COLUMN [Number]; """, // """ -DECLARE @defaultSchema AS sysname; -SET @defaultSchema = SCHEMA_NAME(); -DECLARE @description AS sql_variant; -SET @description = N'My comment'; -EXEC sp_addextendedproperty 'MS_Description', @description, 'SCHEMA', @defaultSchema, 'TABLE', N'Customers', 'COLUMN', N'Name'; +DECLARE @defaultSchema4 AS sysname; +SET @defaultSchema4 = SCHEMA_NAME(); +DECLARE @description4 AS sql_variant; +SET @description4 = N'My comment'; +EXEC sp_addextendedproperty 'MS_Description', @description4, 'SCHEMA', @defaultSchema4, 'TABLE', N'Customers', 'COLUMN', N'Name'; """, // """ -DECLARE @defaultSchema AS sysname; -SET @defaultSchema = SCHEMA_NAME(); -DECLARE @description AS sql_variant; -SET @description = N'My comment'; -EXEC sp_addextendedproperty 'MS_Description', @description, 'SCHEMA', @defaultSchema, 'TABLE', N'HistoryTable', 'COLUMN', N'Name'; +DECLARE @defaultSchema5 AS sysname; +SET @defaultSchema5 = SCHEMA_NAME(); +DECLARE @description5 AS sql_variant; +SET @description5 = N'My comment'; +EXEC sp_addextendedproperty 'MS_Description', @description5, 'SCHEMA', @defaultSchema5, 'TABLE', N'HistoryTable', 'COLUMN', N'Name'; """, // """ -DECLARE @historyTableSchema sysname = SCHEMA_NAME() -EXEC(N'ALTER TABLE [Customers] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema + '].[HistoryTable]))') +DECLARE @historyTableSchema1 sysname = SCHEMA_NAME() +EXEC(N'ALTER TABLE [Customers] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema1 + '].[HistoryTable]))') """); } @@ -9314,11 +9314,11 @@ await Test( """, // """ -DECLARE @defaultSchema AS sysname; -SET @defaultSchema = SCHEMA_NAME(); -DECLARE @description AS sql_variant; -SET @description = N'My comment'; -EXEC sp_addextendedproperty 'MS_Description', @description, 'SCHEMA', @defaultSchema, 'TABLE', N'Customers', 'COLUMN', N'End'; +DECLARE @defaultSchema1 AS sysname; +SET @defaultSchema1 = SCHEMA_NAME(); +DECLARE @description1 AS sql_variant; +SET @description1 = N'My comment'; +EXEC sp_addextendedproperty 'MS_Description', @description1, 'SCHEMA', @defaultSchema1, 'TABLE', N'Customers', 'COLUMN', N'End'; """); } @@ -9385,22 +9385,22 @@ ALTER TABLE [Customers] SET (SYSTEM_VERSIONING = OFF) """, // """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var2 sysname; +SELECT @var2 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customers]') AND [c].[name] = N'DateOfBirth'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var0 + '];'); +IF @var2 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var2 + '];'); ALTER TABLE [Customers] DROP COLUMN [DateOfBirth]; """, // """ -DECLARE @var1 sysname; -SELECT @var1 = [d].[name] +DECLARE @var3 sysname; +SELECT @var3 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[HistoryTable]') AND [c].[name] = N'DateOfBirth'); -IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [HistoryTable] DROP CONSTRAINT [' + @var1 + '];'); +IF @var3 IS NOT NULL EXEC(N'ALTER TABLE [HistoryTable] DROP CONSTRAINT [' + @var3 + '];'); ALTER TABLE [HistoryTable] DROP COLUMN [DateOfBirth]; """, // @@ -9413,24 +9413,24 @@ FROM [sys].[default_constraints] [d] """, // """ -DECLARE @defaultSchema AS sysname; -SET @defaultSchema = SCHEMA_NAME(); -DECLARE @description AS sql_variant; -SET @description = N'My comment'; -EXEC sp_addextendedproperty 'MS_Description', @description, 'SCHEMA', @defaultSchema, 'TABLE', N'Customers', 'COLUMN', N'End'; +DECLARE @defaultSchema4 AS sysname; +SET @defaultSchema4 = SCHEMA_NAME(); +DECLARE @description4 AS sql_variant; +SET @description4 = N'My comment'; +EXEC sp_addextendedproperty 'MS_Description', @description4, 'SCHEMA', @defaultSchema4, 'TABLE', N'Customers', 'COLUMN', N'End'; """, // """ -DECLARE @defaultSchema AS sysname; -SET @defaultSchema = SCHEMA_NAME(); -DECLARE @description AS sql_variant; -SET @description = N'My comment'; -EXEC sp_addextendedproperty 'MS_Description', @description, 'SCHEMA', @defaultSchema, 'TABLE', N'HistoryTable', 'COLUMN', N'End'; +DECLARE @defaultSchema5 AS sysname; +SET @defaultSchema5 = SCHEMA_NAME(); +DECLARE @description5 AS sql_variant; +SET @description5 = N'My comment'; +EXEC sp_addextendedproperty 'MS_Description', @description5, 'SCHEMA', @defaultSchema5, 'TABLE', N'HistoryTable', 'COLUMN', N'End'; """, // """ -DECLARE @historyTableSchema sysname = SCHEMA_NAME() -EXEC(N'ALTER TABLE [Customers] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema + '].[HistoryTable]))') +DECLARE @historyTableSchema1 sysname = SCHEMA_NAME() +EXEC(N'ALTER TABLE [Customers] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema1 + '].[HistoryTable]))') """); } @@ -9797,12 +9797,12 @@ await Test( AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var1 sysname; +SELECT @var1 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customers]') AND [c].[name] = N'Number'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var0 + '];'); +IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var1 + '];'); ALTER TABLE [Customers] DROP COLUMN [Number]; """, // @@ -9968,22 +9968,22 @@ ALTER TABLE [Customers] DROP PERIOD FOR SYSTEM_TIME """, // """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var1 sysname; +SELECT @var1 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customers]') AND [c].[name] = N'End'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var0 + '];'); +IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var1 + '];'); ALTER TABLE [Customers] DROP COLUMN [End]; """, // """ -DECLARE @var1 sysname; -SELECT @var1 = [d].[name] +DECLARE @var2 sysname; +SELECT @var2 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customers]') AND [c].[name] = N'Start'); -IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var1 + '];'); +IF @var2 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var2 + '];'); ALTER TABLE [Customers] DROP COLUMN [Start]; """, // @@ -10050,42 +10050,42 @@ ALTER TABLE [Customers] DROP PERIOD FOR SYSTEM_TIME """, // """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var1 sysname; +SELECT @var1 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customers]') AND [c].[name] = N'End'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var0 + '];'); +IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var1 + '];'); ALTER TABLE [Customers] DROP COLUMN [End]; """, // """ -DECLARE @var1 sysname; -SELECT @var1 = [d].[name] +DECLARE @var2 sysname; +SELECT @var2 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customers]') AND [c].[name] = N'Number'); -IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var1 + '];'); +IF @var2 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var2 + '];'); ALTER TABLE [Customers] DROP COLUMN [Number]; """, // """ -DECLARE @var2 sysname; -SELECT @var2 = [d].[name] +DECLARE @var3 sysname; +SELECT @var3 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[HistoryTable]') AND [c].[name] = N'Number'); -IF @var2 IS NOT NULL EXEC(N'ALTER TABLE [HistoryTable] DROP CONSTRAINT [' + @var2 + '];'); +IF @var3 IS NOT NULL EXEC(N'ALTER TABLE [HistoryTable] DROP CONSTRAINT [' + @var3 + '];'); ALTER TABLE [HistoryTable] DROP COLUMN [Number]; """, // """ -DECLARE @var3 sysname; -SELECT @var3 = [d].[name] +DECLARE @var4 sysname; +SELECT @var4 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customers]') AND [c].[name] = N'Start'); -IF @var3 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var3 + '];'); +IF @var4 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var4 + '];'); ALTER TABLE [Customers] DROP COLUMN [Start]; """, // @@ -10150,22 +10150,22 @@ ALTER TABLE [Customers] DROP PERIOD FOR SYSTEM_TIME """, // """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var1 sysname; +SELECT @var1 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customers]') AND [c].[name] = N'End'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var0 + '];'); +IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var1 + '];'); ALTER TABLE [Customers] DROP COLUMN [End]; """, // """ -DECLARE @var1 sysname; -SELECT @var1 = [d].[name] +DECLARE @var2 sysname; +SELECT @var2 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customers]') AND [c].[name] = N'Start'); -IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var1 + '];'); +IF @var2 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var2 + '];'); ALTER TABLE [Customers] DROP COLUMN [Start]; """, // @@ -10324,12 +10324,12 @@ await Test( """, // """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var1 sysname; +SELECT @var1 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customers]') AND [c].[name] = N'Number'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var0 + '];'); +IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var1 + '];'); ALTER TABLE [Customers] DROP COLUMN [Number]; """, // @@ -10519,22 +10519,22 @@ ALTER TABLE [Customers] DROP PERIOD FOR SYSTEM_TIME """, // """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var1 sysname; +SELECT @var1 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customers]') AND [c].[name] = N'End'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var0 + '];'); +IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var1 + '];'); ALTER TABLE [Customers] DROP COLUMN [End]; """, // """ -DECLARE @var1 sysname; -SELECT @var1 = [d].[name] +DECLARE @var2 sysname; +SELECT @var2 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customers]') AND [c].[name] = N'Start'); -IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var1 + '];'); +IF @var2 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var2 + '];'); ALTER TABLE [Customers] DROP COLUMN [Start]; """, // @@ -10641,8 +10641,8 @@ ALTER TABLE [Customers] SET (SYSTEM_VERSIONING = OFF) """, // """ -DECLARE @historyTableSchema sysname = SCHEMA_NAME() -EXEC(N'ALTER TABLE [NewCustomers] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema + '].[NewHistoryTable]))') +DECLARE @historyTableSchema1 sysname = SCHEMA_NAME() +EXEC(N'ALTER TABLE [NewCustomers] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [' + @historyTableSchema1 + '].[NewHistoryTable]))') """); } @@ -10724,22 +10724,22 @@ ALTER TABLE [Customers] DROP PERIOD FOR SYSTEM_TIME """, // """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var1 sysname; +SELECT @var1 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customers]') AND [c].[name] = N'End'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var0 + '];'); +IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var1 + '];'); ALTER TABLE [Customers] DROP COLUMN [End]; """, // """ -DECLARE @var1 sysname; -SELECT @var1 = [d].[name] +DECLARE @var2 sysname; +SELECT @var2 = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Customers]') AND [c].[name] = N'Start'); -IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var1 + '];'); +IF @var2 IS NOT NULL EXEC(N'ALTER TABLE [Customers] DROP CONSTRAINT [' + @var2 + '];'); ALTER TABLE [Customers] DROP COLUMN [Start]; """, // diff --git a/test/EFCore.SqlServer.FunctionalTests/Migrations/SqlServerMigrationsSqlGeneratorTest.cs b/test/EFCore.SqlServer.FunctionalTests/Migrations/SqlServerMigrationsSqlGeneratorTest.cs index 9e8f89ad5f6..0b4f87a279e 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Migrations/SqlServerMigrationsSqlGeneratorTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Migrations/SqlServerMigrationsSqlGeneratorTest.cs @@ -227,12 +227,12 @@ public override void AlterColumnOperation_without_column_type() AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'LuckyNumber'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] ALTER COLUMN [LuckyNumber] int NOT NULL; """); } @@ -262,12 +262,12 @@ public virtual void AlterColumnOperation_with_identity_legacy() AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[People]') AND [c].[name] = N'Id'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [People] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [People] ALTER COLUMN [Id] int NOT NULL; """); } @@ -296,12 +296,12 @@ public virtual void AlterColumnOperation_with_index_no_oldColumn() AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Person]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Person] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [Person] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [Person] ALTER COLUMN [Name] nvarchar(30) NULL; """); } @@ -336,12 +336,12 @@ public virtual void AlterColumnOperation_with_added_index() AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Person]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Person] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [Person] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [Person] ALTER COLUMN [Name] nvarchar(30) NULL; GO @@ -378,12 +378,12 @@ public virtual void AlterColumnOperation_with_added_index_no_oldType() AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Person]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Person] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [Person] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [Person] ALTER COLUMN [Name] nvarchar(450) NULL; GO @@ -411,12 +411,12 @@ public virtual void AlterColumnOperation_identity_legacy() AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Person]') AND [c].[name] = N'Id'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Person] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [Person] DROP CONSTRAINT [' + @var + '];'); ALTER TABLE [Person] ALTER COLUMN [Id] bigint NOT NULL; """); } @@ -595,8 +595,8 @@ public virtual void AlterDatabaseOperation_collation_to_default() """ BEGIN DECLARE @db_name nvarchar(max) = DB_NAME(); -DECLARE @defaultCollation nvarchar(max) = CAST(SERVERPROPERTY('Collation') AS nvarchar(max)); -EXEC(N'ALTER DATABASE [' + @db_name + '] COLLATE ' + @defaultCollation + N';'); +DECLARE @defaultCollation1 nvarchar(max) = CAST(SERVERPROPERTY('Collation') AS nvarchar(max)); +EXEC(N'ALTER DATABASE [' + @db_name + '] COLLATE ' + @defaultCollation1 + N';'); END """); @@ -1264,12 +1264,12 @@ public virtual void AlterColumn_make_required_with_idempotent() AssertSql( """ -DECLARE @var0 sysname; -SELECT @var0 = [d].[name] +DECLARE @var sysname; +SELECT @var = [d].[name] FROM [sys].[default_constraints] [d] INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Person]') AND [c].[name] = N'Name'); -IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Person] DROP CONSTRAINT [' + @var0 + '];'); +IF @var IS NOT NULL EXEC(N'ALTER TABLE [Person] DROP CONSTRAINT [' + @var + '];'); EXEC(N'UPDATE [Person] SET [Name] = N'''' WHERE [Name] IS NULL'); ALTER TABLE [Person] ALTER COLUMN [Name] nvarchar(max) NOT NULL; ALTER TABLE [Person] ADD DEFAULT N'' FOR [Name]; diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs index 14db73c59cb..f7569611bb0 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs @@ -9380,6 +9380,20 @@ FROM [Factions] AS [f] """); } + public override async Task Project_equality_with_value_converted_property(bool async) + { + await base.Project_equality_with_value_converted_property(async); + + AssertSql( + """ +SELECT CASE + WHEN [m].[Difficulty] = N'Unknown' THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END +FROM [Missions] AS [m] +"""); + } + public override async Task Contains_on_readonly_enumerable(bool async) { await base.Contains_on_readonly_enumerable(async); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindMiscellaneousQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindMiscellaneousQuerySqlServerTest.cs index ddad65e8400..839f136e9fc 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindMiscellaneousQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindMiscellaneousQuerySqlServerTest.cs @@ -7461,6 +7461,32 @@ FROM [Orders] AS [o] """); } + public override async Task Column_access_inside_subquery_predicate(bool async) + { + await base.Column_access_inside_subquery_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 EXISTS ( + SELECT 1 + FROM [Orders] AS [o] + WHERE [c].[CustomerID] = N'ALFKI') +"""); + } + + public override async Task Cast_to_object_over_parameter_directly_in_lambda(bool async) + { + await base.Cast_to_object_over_parameter_directly_in_lambda(async); + + AssertSql( + """ +SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] +FROM [Orders] AS [o] +"""); + } + private void AssertSql(params string[] expected) => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindWhereQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindWhereQuerySqlServerTest.cs index 132b41e85bb..437ba3f5b4f 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindWhereQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindWhereQuerySqlServerTest.cs @@ -3425,7 +3425,21 @@ FROM [Orders] AS [o] """); } - #region Evaluation order of predicates + public override async Task Simplifiable_coalesce_over_nullable(bool async) + { + await base.Simplifiable_coalesce_over_nullable(async); + + AssertSql( + """ +@__p_0='10248' + +SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] +FROM [Orders] AS [o] +WHERE [o].[OrderID] = @__p_0 +"""); + } + + #region Evaluation order of operators public override async Task Take_and_Where_evaluation_order(bool async) { @@ -3483,7 +3497,7 @@ ORDER BY [c].[ContactTitle] """); } - #endregion Evaluation order of predicates + #endregion Evaluation order of operators private void AssertSql(params string[] expected) => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQueryOldSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQueryOldSqlServerTest.cs index d23ea73a1ce..1041c1e10c1 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQueryOldSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQueryOldSqlServerTest.cs @@ -498,6 +498,24 @@ WHERE [p].[Int] NOT IN (10, 999) """); } + public override async Task Parameter_collection_ImmutableArray_of_ints_Contains_int(bool async) + { + await base.Parameter_collection_ImmutableArray_of_ints_Contains_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 [p].[Int] IN (10, 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].[Int] NOT IN (10, 999) +"""); + } + public override async Task Parameter_collection_of_ints_Contains_nullable_int(bool async) { await base.Parameter_collection_of_ints_Contains_nullable_int(async); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs index a42b4ac42f7..9aea6357ba3 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs @@ -516,6 +516,34 @@ 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_ImmutableArray_of_ints_Contains_int(bool async) + { + await base.Parameter_collection_ImmutableArray_of_ints_Contains_int(async); + + AssertSql( + """ +@__ints_0='[10,999]' (Nullable = false) (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]' (Nullable = false) (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 ( diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerJsonTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerJsonTypeTest.cs index d382ca0642d..29656d04fe6 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerJsonTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerJsonTypeTest.cs @@ -532,6 +532,34 @@ 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_ImmutableArray_of_ints_Contains_int(bool async) + { + await base.Parameter_collection_ImmutableArray_of_ints_Contains_int(async); + + AssertSql( + """ +@__ints_0='[10,999]' (Nullable = false) (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]' (Nullable = false) (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 ( diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs index de05c4c3797..0708539aaa5 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs @@ -539,6 +539,34 @@ 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_ImmutableArray_of_ints_Contains_int(bool async) + { + await base.Parameter_collection_ImmutableArray_of_ints_Contains_int(async); + + AssertSql( + """ +@__ints_0='[10,999]' (Nullable = false) (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]' (Nullable = false) (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 ( diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs index f8d41c87f63..0eca14b01d9 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs @@ -12341,6 +12341,20 @@ FROM [LocustHordes] AS [l] """); } + public override async Task Project_equality_with_value_converted_property(bool async) + { + await base.Project_equality_with_value_converted_property(async); + + AssertSql( + """ +SELECT CASE + WHEN [m].[Difficulty] = N'Unknown' THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END +FROM [Missions] AS [m] +"""); + } + public override async Task FirstOrDefault_on_empty_collection_of_DateTime_in_subquery(bool async) { await base.FirstOrDefault_on_empty_collection_of_DateTime_in_subquery(async); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPTGearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPTGearsOfWarQuerySqlServerTest.cs index e2260d6cc08..fb8d0803c80 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TPTGearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPTGearsOfWarQuerySqlServerTest.cs @@ -10507,6 +10507,20 @@ FROM [Factions] AS [f] """); } + public override async Task Project_equality_with_value_converted_property(bool async) + { + await base.Project_equality_with_value_converted_property(async); + + AssertSql( + """ +SELECT CASE + WHEN [m].[Difficulty] = N'Unknown' THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END +FROM [Missions] AS [m] +"""); + } + public override async Task FirstOrDefault_on_empty_collection_of_DateTime_in_subquery(bool async) { await base.FirstOrDefault_on_empty_collection_of_DateTime_in_subquery(async); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs index 6895ee561b1..01ccc04db5a 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs @@ -6999,6 +6999,20 @@ public override async Task Comparison_with_value_converted_subclass(bool async) """); } + public override async Task Project_equality_with_value_converted_property(bool async) + { + await base.Project_equality_with_value_converted_property(async); + + AssertSql( + """ +SELECT CASE + WHEN [m].[Difficulty] = N'Unknown' THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END +FROM [Missions] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [m] +"""); + } + public override async Task Navigation_access_on_derived_materialized_entity_using_cast(bool async) { await base.Navigation_access_on_derived_materialized_entity_using_cast(async); diff --git a/test/EFCore.Sqlite.FunctionalTests/Migrations/MigrationsInfrastructureSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Migrations/MigrationsInfrastructureSqliteTest.cs index 05b25da32f2..54031150080 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Migrations/MigrationsInfrastructureSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Migrations/MigrationsInfrastructureSqliteTest.cs @@ -12,9 +12,9 @@ namespace Microsoft.EntityFrameworkCore.Migrations public class MigrationsInfrastructureSqliteTest(MigrationsInfrastructureSqliteTest.MigrationsInfrastructureSqliteFixture fixture) : MigrationsInfrastructureTestBase(fixture) { - public override void Can_generate_migration_from_initial_database_to_initial() + public override async Task Can_generate_migration_from_initial_database_to_initial() { - base.Can_generate_migration_from_initial_database_to_initial(); + await base.Can_generate_migration_from_initial_database_to_initial(); Assert.Equal( """ @@ -29,9 +29,9 @@ public override void Can_generate_migration_from_initial_database_to_initial() ignoreLineEndingDifferences: true); } - public override void Can_generate_no_migration_script() + public override async Task Can_generate_no_migration_script() { - base.Can_generate_no_migration_script(); + await base.Can_generate_no_migration_script(); Assert.Equal( """ diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs index 6fff187cf93..aec1ce784fe 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs @@ -3076,6 +3076,17 @@ public override async Task Comparison_with_value_converted_subclass(bool async) """); } + public override async Task Project_equality_with_value_converted_property(bool async) + { + await base.Project_equality_with_value_converted_property(async); + + AssertSql( + """ +SELECT "m"."Difficulty" = 'Unknown' +FROM "Missions" AS "m" +"""); + } + public override async Task GetValueOrDefault_in_filter_non_nullable_column(bool async) { await base.GetValueOrDefault_in_filter_non_nullable_column(async); diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs index ce27814d118..58b6bb73a75 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs @@ -529,6 +529,34 @@ 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" +FROM "PrimitiveCollectionsEntity" AS "p" +WHERE "p"."Int" NOT IN ( + SELECT "i"."value" + FROM json_each(@__ints_0) AS "i" +) +"""); + } + + public override async Task Parameter_collection_ImmutableArray_of_ints_Contains_int(bool async) + { + await base.Parameter_collection_ImmutableArray_of_ints_Contains_int(async); + + AssertSql( + """ +@__ints_0='[10,999]' (Nullable = false) (Size = 8) + +SELECT "p"."Id", "p"."Bool", "p"."Bools", "p"."DateTime", "p"."DateTimes", "p"."Enum", "p"."Enums", "p"."Int", "p"."Ints", "p"."NullableInt", "p"."NullableInts", "p"."NullableString", "p"."NullableStrings", "p"."String", "p"."Strings" +FROM "PrimitiveCollectionsEntity" AS "p" +WHERE "p"."Int" IN ( + SELECT "i"."value" + FROM json_each(@__ints_0) AS "i" +) +""", + // + """ +@__ints_0='[10,999]' (Nullable = false) (Size = 8) + SELECT "p"."Id", "p"."Bool", "p"."Bools", "p"."DateTime", "p"."DateTimes", "p"."Enum", "p"."Enums", "p"."Int", "p"."Ints", "p"."NullableInt", "p"."NullableInts", "p"."NullableString", "p"."NullableStrings", "p"."String", "p"."Strings" FROM "PrimitiveCollectionsEntity" AS "p" WHERE "p"."Int" NOT IN (