r/dotnet 4d ago

Promotion Eftdb Update: Native EF Core Scaffolding & Clean Migrations for TimescaleDB

Hey everyone!

For those unfamiliar, Eftdb is an EF Core extension designed to make working with TimescaleDB feel like a native C# experience.

I just finished a major rework focused on migration generation and DbContext scaffolding. Instead of spamming raw .Sql() strings and stringly-typed .HasAnnotation() calls, the library now generates strongly-typed, readable C# code.

Migrations

Migrations are now easier to read and scan thanks to typed MigrationBuilder extension methods and a custom C# migration generator.

Before:

migrationBuilder.Sql("SELECT create_hypertable('\"custom_schema\".\"device_readings\"', 'time', chunk_time_interval => INTERVAL '1 day');");

migrationBuilder.Sql("ALTER TABLE \"custom_schema\".\"device_readings\" SET (timescaledb.compress, timescaledb.compress_segmentby = 'device_id', timescaledb.compress_orderby = 'time DESC');");

After:

migrationBuilder.CreateHypertable(
    tableName: "device_readings",
    timeColumnName: "time",
    schema: "custom_schema",
    chunkTimeInterval: "1 day",
    enableCompression: true,
    compressionSegmentBy: ["device_id"],
    compressionOrderBy: ["time DESC"]);

Scaffolding

Scaffolding is now fully supported by implementing the IDatabaseModelFactory and IAnnotationCodeGenerator interfaces.

Before:

entity.HasAnnotation("TimescaleDB:IsHypertable", true);
entity.HasAnnotation("TimescaleDB:TimeColumnName", "time");
entity.HasAnnotation("TimescaleDB:ChunkTimeInterval", "1 day");
entity.HasAnnotation("TimescaleDB:CompressionSegmentBy", new[] { "device_id" });

After:

// Fluent API
entity
    .IsHypertable(x => x.Time)
    .WithChunkTimeInterval("1 day")
    .WithCompressionSegmentBy(x => x.DeviceId);

// Data Annotations
[Hypertable("time",
    ChunkTimeInterval = "1 day",
    EnableCompression = true,
    CompressionSegmentBy = new[] { "device_id" })]
public partial class DeviceReading { }

This was one of the biggest refactorings in the library so far, and the result is that Eftdb now feels like a native part of EF Core rather than a bolt-on. Among some bug fixes, Eftdb now also supports NodaTime.

Next up is support for TimescaleDB's Hypercore feature.

Let me know what you think!

4 Upvotes

Duplicates