Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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.Linq;
using System.Text;
using Microsoft.EntityFrameworkCore.Sqlite.Internal;
using Microsoft.EntityFrameworkCore.Sqlite.Metadata.Internal;
Expand Down Expand Up @@ -373,6 +374,22 @@ private IReadOnlyList<MigrationOperation> RewriteOperations(
continue;
}

// Skip autoincrement primary key columns that are being added in this migration
var isAutoincrement = column.FindAnnotation(SqliteAnnotationNames.Autoincrement)?.Value as bool? == true;
var isPrimaryKey = column.Table.PrimaryKey?.Columns.Contains(column) == true;

if (isAutoincrement && isPrimaryKey)
{
// Check if this column is being added in the current migration
var isNewColumn = migrationOperations.OfType<AddColumnOperation>()
.Any(op => op.Table == key.Table && op.Schema == key.Schema && op.Name == column.Name);

if (isNewColumn)
{
continue; // Skip newly added autoincrement columns
}
}

if (first)
{
first = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2275,6 +2275,79 @@ protected override bool AssertConstraintNames
protected override string NonDefaultCollation
=> "NOCASE";

[ConditionalFact]
public virtual async Task Replace_string_primary_key_with_autoincrement_identity()
{
await Test(
builder => builder.Entity(
"Person", e =>
{
e.Property<string>("Ssn");
e.HasKey("Ssn");
}),
builder => { },
builder => builder.Entity(
"Person", e =>
{
e.Property<int>("Id").ValueGeneratedOnAdd();
e.Property<string>("Ssn");
e.HasKey("Id");
e.HasIndex("Ssn").IsUnique();
}),
model =>
{
var table = Assert.Single(model.Tables);
Assert.Equal("Person", table.Name);
Assert.Equal(2, table.Columns.Count());

var idColumn = Assert.Single(table.Columns, c => c.Name == "Id");
Assert.False(idColumn.IsNullable);
});

// Expectation: the INSERT should NOT include the Id column because it's AUTOINCREMENT
AssertSql(
"""
ALTER TABLE "Person" ADD "Id" INTEGER NOT NULL DEFAULT 0;
""",
//
"""
CREATE UNIQUE INDEX "IX_Person_Ssn" ON "Person" ("Ssn");
""",
//
"""
CREATE TABLE "ef_temp_Person" (
"Id" INTEGER NOT NULL CONSTRAINT "PK_Person" PRIMARY KEY AUTOINCREMENT,
"Ssn" TEXT NULL
);
""",
//
"""
INSERT INTO "ef_temp_Person" ("Ssn")
SELECT "Ssn"
FROM "Person";
""",
//
"""
PRAGMA foreign_keys = 0;
""",
//
"""
DROP TABLE "Person";
""",
//
"""
ALTER TABLE "ef_temp_Person" RENAME TO "Person";
""",
//
"""
PRAGMA foreign_keys = 1;
""",
//
"""
CREATE UNIQUE INDEX "IX_Person_Ssn" ON "Person" ("Ssn");
""");
}

protected virtual async Task AssertNotSupportedAsync(Func<Task> action, string? message = null)
{
var ex = await Assert.ThrowsAsync<NotSupportedException>(action);
Expand Down
Loading