question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Migrations script: wrap queries in `sp_executesql` when using `--idempotent`

See original GitHub issue

What problem are you trying to solve?

When generating migration scripts with dotnet ef migrations script --idempotent, the tool generates invalid SQL in some cases. Consider the following migration:

public partial class CreateAView : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.Sql("create view MyView as select 1;");

This results in the following migration script:

IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20220301060232_CreateAView')
BEGIN

create view MyView as select 1;

END;
GO

This script is invalid because create view must be the only statement in an SQL query batch; it cannot appear inside IF.

Describe the solution you’d like

The easiest solution seems to me to wrap custom SQL inside sp_executesql. Something like this:

IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20220301060232_CreateAView')
BEGIN

DECLARE @query nvarchar(max) = N'
  create view MyView as select 1;
';
EXECUTE sp_executesql @query;

END;
GO

This works for Microsoft SQL server – I’m sure other dialects have their own equivalent of dynamic SQL.

Issue Analytics

  • State:open
  • Created a year ago
  • Reactions:2
  • Comments:12 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
Sjlvercommented, Apr 19, 2022

@roji That all makes sense.

I’m just wondering why we would want to put the burden on the user (and write docs, and answer the occasional question if users don’t find the docs, etc.). Is the increase in complexity of the raw SQL feature really so large as to outweigh the benefits for the users? It might well be; I don’t know how the feature is implemented… but my hunch is that it would probably be less than 30 LOC to add a call to sp_executesql. Plus a unit test. Plus optionally another few lines and a regular expression to only wrap those SQL statements that need it.

Anyway, at this point I feel like I’ve been vocal enough 😉 Let me just use this opportunity to express my gratitude to EF. It’s a great software, and I shudder when I think of previous projects that used stored procedures instead of an ORM… so: thank you!

1reaction
Sjlvercommented, Apr 4, 2022

@ajcvickers Yes, that’s absolutely right.

I would prefer to not do this for two reasons:

  • It makes the migration more complicated. For example, I’d have to escape certain characters in the raw SQL when putting it inside a string literal.
  • It’s unnecessary in most cases. When using dotnet ef database update, the migration works just fine. It even works just fine when used with dotnet ef migrations script. Only when adding the --idempotent switch does the problem occur.

The latter point makes me think that the problem is really with --idempotent, and not with the raw SQL.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Creating Idempotent DDL Scripts for Database Migrations
I'll demonstrate how to achieve this, using either the information schema views or system functions to check the required conditions, and then ...
Read more >
EF Core idempotent migration script fails despite check on ...
The script fails in Azure DevOps release when using SQLCMD and also fails when using Azure Data Studio, both accessing the Azure SQL...
Read more >
Can sp_executesql be configured / used by default?
So I wondered if there is kind of a configuration I do not know yet that forces the software to wrap queries with...
Read more >
Untitled
We are generating an idempotent migrations SQL script using the command line: dotnet ef ... Migrations script: wrap queries in `sp_executesql` when using...
Read more >
Database Access for Enterprise Applications
Task 2: Add properties to the Item class, and then use a migration to update the database with fields to match the properties...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found