-
Notifications
You must be signed in to change notification settings - Fork 13
Description
Description
When using Google.Cloud.EntityFrameworkCore.Spanner with EF Core migrations, creating a table via migrationBuilder.CreateTable(...) results in the error above:
No primary key was found in the database for table Table TestEntities.
Call SpannerModelValidationConnectionProvider.Instance.EnableDatabaseModelValidation(false)
to disable model validation if this error is a false positive.
It happens because the model validation starts before migrations are applied and therefore fails.
The only workaround suggested by the error message is disabling database model validation globally:
SpannerModelValidationConnectionProvider.Instance.EnableDatabaseModelValidation(false);
This is a significant behavioral change and not acceptable for production use.
Environment
EF Core version: 8.0.22
Google.Cloud.EntityFrameworkCore.Spanner version: 3.8.0
Database: Google Cloud Spanner
Migrations enabled ✅
Reproduction steps
Create a new C# Project with EF Core using the Spanner provider
Add the following migration:
20251216161442_InitialCreate.cs
public partial class InitialCreate : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "TestEntities",
columns: table => new
{
Id = table.Column<Guid>(type: "STRING(36)", nullable: false),
Name = table.Column<string>(type: "STRING", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_TestEntities", x => x.Id);
}
);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(name: "TestEntities");
}
}
20251216161442_InitialCreate.Designer.cs
[DbContext(typeof(TestDbContext))]
[Migration("20251216161442_InitialCreate")]
partial class InitialCreate
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.Entity("YOUR_NAMESPACE", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("STRING(36)");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("STRING");
b.HasKey("Id");
b.ToTable("TestEntities");
});
#pragma warning restore 612, 618
}
}
[DbContext(typeof(TestDbContext))]
partial class TestDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "6.0.16");
modelBuilder.Entity("YOUR_NAMESPACE", b =>
{
b.Property<Guid>("Id")
.HasColumnType("STRING(36)");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("STRING");
b.HasKey("Id");
b.ToTable("TestEntities");
});
#pragma warning restore 612, 618
}
}
public class TestDbContext(DbContextOptions<TestDbContext> options, string connectionString)
: DbContext(options)
{
public virtual DbSet<TestEntity> TestEntities { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSpanner(connectionString, options =>
{
options.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery);
});
}
base.OnConfiguring(optionsBuilder);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<TestEntity>(entity =>
{
entity.HasKey(it => it.Id);
entity.ToTable("TestEntities");
});
base.OnModelCreating(modelBuilder);
}
}
Important is to have this property as part of the DBContext. If it's not present, everything works as expected:
public virtual DbSet<TestEntity> TestEntities { get; set; }
Start the application or integration test with SpannerEmulator and apply the migration to Cloud Spanner:
Expected behavior:
The generated Spanner table should have a primary key defined
EF Core model validation should succeed
No runtime error should occur
Actual behavior
On startup, EF Core throws:
Error Message Appears: No primary key was found in the database for table Table TestEntities. Call SpannerModelValidationConnectionProvider.Instance.EnableDatabaseModelValidation(false) to disable model validation if this error is a false positive.
Setting SpannerModelValidationConnectionProvider.Instance.EnableDatabaseModelValidation(false) fixes the issue but is inacceptable.
Thanks in advance!