Thanks to visit codestin.com
Credit goes to github.com

Skip to content

SQL Server Migrations - SqlOperation.Sql is stripped of all empty lines #32730

@sergeitemkin

Description

@sergeitemkin

We've upgraded to EF Core 8.0.0 (from 7.0.8) and have started experiencing an issue with MigrationBuilder.Sql where all empty lines are dropped from the SQL executed by the resulting migration. This seems to be a result of the change in SqlServerMigrationsSqlGenerator.Generate(SqlOperation operation...) that was done to fix a regex timeout.

In the current code, it seems that new string.IsNullOrWhiteSpace(line) check is causing this issue. Here's the related snippet from SqlServerMigrationsSqlGenerator:

protected override void Generate(SqlOperation operation, IModel? model, MigrationCommandListBuilder builder)
{
    var preBatched = operation.Sql
        .Replace("\\\n", "")
        .Replace("\\\r\n", "")
        .Split(new[] { "\r\n", "\n" }, StringSplitOptions.None);

    var batchBuilder = new StringBuilder();
    foreach (var line in preBatched)
    {
        if (string.IsNullOrWhiteSpace(line)) <--- breaking change
        {
            continue;
        }

While some empty lines could be considered inconsequential, some are not, and currently all of them seem to be removed. For example, a migration like this:

public partial class TestMigrationWithLineBreaks : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.Sql("INSERT INTO SomeTable SELECT 'Some\n\nValue'");
    }
    protected override void Down(MigrationBuilder migrationBuilder) { }
}

Results in the below SQL execution (note the missing empty line):

INSERT INTO SomeTable SELECT 'Some
Value'

Sample Code w/ Issue

Another of our current use cases involves using MigrationBuilder.Sql to manage changes to stored procedures and other db objects, and the dropped empty lines reduce readability of the definitions for these objects in the db.

My current workaround is to create a separate generator that inherits from SqlServerMigrationsSqlGenerator, override the Generate(SqlOperation operation...) method with the addition of batchBuilder.AppendLine(line) inside of the aforementioned if block, and replacing the IMigrationsSqlGenerator service with this new implementation via UseSqlServer().ReplaceService<>. However, it would be awesome to not have to do that as we're losing potential future optimizations of the generator and introducing potential for incompatibility and maintenance overhead for our future EF Core updates.

EF Core version: 8.0.0
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET 8.0
Operating system: Windows 11 Pro 22H2
IDE: Visual Studio 2022 17.8.3

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions