dotnet / efcore

EF Core is a modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations.
https://docs.microsoft.com/ef/
MIT License
13.8k stars 3.2k forks source link

Adding a stored procedure using raw SQL and then generating an idempotent migration script results in flawed SQL script #34555

Open ReinderWit opened 2 months ago

ReinderWit commented 2 months ago

I have a few stored procedures that I'd like to be created during a migration step in Entity Framework core 8.0.7. I added a new migration, and in the Up() method I put this simple script:

var sp = @"CREATE PROCEDURE [dbo].[MyStoredProcedureFromMigration]
    AS
    BEGIN
        SET NOCOUNT ON;
        select * from Students where FirstName like '%dummy%'
    END";

migrationBuilder.Sql(sp);

In my Azure Devops pipeline, I generate the idempotent migration script with a DotNetCoreCli task:

  - task: UseDotNet@2
    inputs:
      packageType: "sdk"
      version: "8.0.x"

  - task: DotNetCoreCLI@2
    displayName: 'Install dotnet-ef tool'
    inputs:
      command: custom
      custom: tool
      arguments: 'update -g dotnet-ef'

  - task: DotNetCoreCLI@2
    displayName: 'Create EntityFramework migration script'
    inputs:
      command: custom
      custom: ef
      arguments: 'migrations script --idempotent --project $(Build.SourcesDirectory)/src/[MigrationsProject].csproj --startup-project $(Build.SourcesDirectory)/src/[MigrationsProject].csproj --output $(System.ArtifactsDirectory)/script.sql'
      workingDirectory: $(Build.SourcesDirectory)

But EntityFramework then generates this script:

IF NOT EXISTS (
    SELECT * FROM [__EFMigrationsHistory]
    WHERE [MigrationId] = N'20240827132758_NameOfMigration'
)
BEGIN
    CREATE PROCEDURE [dbo].[MyStoredProcedureFromMigration]
       AS
       BEGIN
          SET NOCOUNT ON;
          select * from Students where FirstName like '%dummy%'
       END
END;
GO

which returns an error when running from a SqlAzureDacpacDeployment task in the pipeline:

Incorrect syntax near the keyword 'PROCEDURE'.

If I remove the --idempotent argument, the script is valid but then I get errors because some of the tables already exist, as the generated script is no longer idempotent.

How can I generate a valid new migration script that runs without errors when it contains the creation of stored procedures?

AndriySvyryd commented 2 months ago

Likely duplicate of https://github.com/dotnet/efcore/issues/33337