-
Notifications
You must be signed in to change notification settings - Fork 3.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add SQL Ledger support #33226
Comments
Would database model first work for you? |
It's not what I was hoping for, but I will take anything to have a more integrated situation :) |
Note the similarity with temporal tables (docs). In any case, at least the main part of this would purely be a migration feature (from the docs: "Ledger and the historical data are managed transparently, offering protection without any application changes."). As with most such advanced migration features, it should be possible to use raw SQL in migrations to get the desired table definition (either by adding ALTER TABLE statements, or by replacing the CreateTable operation by a CREAT TABLE). While this isn't as nice as having EF model everything, it's unfeasible for EF to cover the DDL for every possible database feature. |
In this case the migration is what I'm looking for. I tried it with a raw SQL, but combining it with the versioning did not work (right away). |
Which versioning are you referring to? Note that EF wouldn't be able to do anything that you're not capable of doing yourself in raw SQL - that's why there's also relatively little value in adding support for such features in migrations. |
I added |
@Tealons from these docs, it sounds like it should be possible for the same table to be both temporal and ledger-backed... But that's something you'll need to figure out - I suggest looking for help in SQL Server forums (at this point it's no longer an EF-related question). |
Putting this in the backlog to gather user feedback. |
@roji: Indeed this is possible. I was just looking for a way via EF Core to create migrations for both temporal and ledger enabled tables. Now I use the b => b.IsTemporal() method were EF creates al the necessary migrations and makes temporal queries possible. I can also do this via raw sql, but I'm not sure how this would work in combination with the temporal option I now have enabled. But I will do some research next week and when I have something that works, I will also post it here. |
As suggested in here #33226 (comment). For me a "code first" model would be preferred. |
@the-programmer Is anything special needed for the database first scenario? Have you tried reverse engineering a ledger table? |
The only thing special is that it has to be combined with a code first model. So far I haven't tried anything, but reverse engineering is one of the topics I have to look into. |
Ok, So I added the table manually CREATE TABLE [Measurements]
(
Id INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
[ImportantFloat] FLOAT NOT NULL,
[ImportantNumber] BIGINT NOT NULL,
[Timestamp] DatetimeOffset NOT NULL
)
WITH (LEDGER = ON (APPEND_ONLY = ON)); And the reverse engineering also worked (using EF Core Power Tools). public class Measurement
{
public int Id { get; set; }
public double ImportantFloat { get; set; }
public long ImportantNumber { get; set; }
public DateTimeOffset Timestamp { get; set; }
public long LedgerStartTransactionId { get; set; }
public long LedgerStartSequenceNumber { get; set; }
} DbContext public virtual DbSet<Measurement> Measurements { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//....
modelBuilder.Entity<Measurement>(entity =>
{
entity.HasKey(e => e.Id).HasName("PK____3214EC075AA505CF");
entity.Property(e => e.LedgerStartSequenceNumber).HasColumnName("ledger_start_sequence_number");
entity.Property(e => e.LedgerStartTransactionId).HasColumnName("ledger_start_transaction_id");
});
} (Yes, it has some manual edits) However if I now do a "add-migration" the Measurements table gets added to my migration chain. I'm not 100% sure what to do with this migration. Can I just update it so the resulting migration to something like the following or what is best? migrationBuilder.Sql(@"CREATE TABLE [Measurements]
(
Id INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
[ImportantFloat] FLOAT NOT NULL,
[ImportantNumber] BIGINT NOT NULL,
[Timestamp] DatetimeOffset NOT NULL
)
WITH (LEDGER = ON (APPEND_ONLY = ON));"); |
@the-programmer you haven't shown the actual CreateTable migration created when doing |
@roji, I didn't think the CreateTable was required since that was "automatic". But anyway, hor reference for someone else who might need this in the future (until ledger support is officially there).
public partial class AddLedger: Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql(@"CREATE TABLE [Measurements]
(
[Id] INT NOT NULL IDENTITY,
[ImportantFloat ] FLOAT NOT NULL,
[ImportantNumber] BIGINT NOT NULL,
[Timestamp] DatetimeOffset NOT NULL,
CONSTRAINT [PK_Measurements] PRIMARY KEY ([Id]),
)
WITH (LEDGER = ON (APPEND_ONLY = ON));");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Measurements");
}
} |
In our project we want to add the Ledger feature to several tables that have high integrity requirements. We are planning to use the built-in Ledger support of MSSQL: https://learn.microsoft.com/en-us/sql/relational-databases/security/ledger/ledger-overview?view=sql-server-ver16
The problem is that because this feature is missing from EF Core, we need to create our own custom queries for migrations and exclude these tables from the EF Core migrations.
Could you please consider adding support for the Ledger feature which will enabled to create normal EF Core migrations for our tables.
The text was updated successfully, but these errors were encountered: