Skip to content

Instantly share code, notes, and snippets.

@danielplawgo
Created February 15, 2022 06:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danielplawgo/d54cf779062bcddac36b72b600201326 to your computer and use it in GitHub Desktop.
Save danielplawgo/d54cf779062bcddac36b72b600201326 to your computer and use it in GitHub Desktop.
EF Core 6 Temporal Tables
public partial class AddProducts : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Products",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
Name = table.Column<string>(type: "nvarchar(max)", nullable: false),
Description = table.Column<string>(type: "nvarchar(max)", nullable: false),
PeriodEnd = table.Column<DateTime>(type: "datetime2", nullable: false)
.Annotation("SqlServer:IsTemporal", true)
.Annotation("SqlServer:TemporalPeriodEndColumnName", "PeriodEnd")
.Annotation("SqlServer:TemporalPeriodStartColumnName", "PeriodStart"),
PeriodStart = table.Column<DateTime>(type: "datetime2", nullable: false)
.Annotation("SqlServer:IsTemporal", true)
.Annotation("SqlServer:TemporalPeriodEndColumnName", "PeriodEnd")
.Annotation("SqlServer:TemporalPeriodStartColumnName", "PeriodStart")
},
constraints: table =>
{
table.PrimaryKey("PK_Products", x => x.Id);
})
.Annotation("SqlServer:IsTemporal", true)
.Annotation("SqlServer:TemporalHistoryTableName", "ProductsHistory")
.Annotation("SqlServer:TemporalHistoryTableSchema", null)
.Annotation("SqlServer:TemporalPeriodEndColumnName", "PeriodEnd")
.Annotation("SqlServer:TemporalPeriodStartColumnName", "PeriodStart");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Products")
.Annotation("SqlServer:IsTemporal", true)
.Annotation("SqlServer:TemporalHistoryTableName", "ProductsHistory")
.Annotation("SqlServer:TemporalHistoryTableSchema", null)
.Annotation("SqlServer:TemporalPeriodEndColumnName", "PeriodEnd")
.Annotation("SqlServer:TemporalPeriodStartColumnName", "PeriodStart");
}
}
public class DataContext : DbContext
{
public DbSet<Product> Products { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Product>()
.ToTable("Products", b => b.IsTemporal());
}
}
static async Task DisplayHistoryWithDates(Guid id)
{
await using DataContext db = new DataContext();
var historyItems = await db.Products
.TemporalAll()
.Where(p => p.Id == id)
.Select(p => new
{
p.Name,
p.Description,
PeriodStart = EF.Property<DateTime>(p, "PeriodStart"),
PeriodEnd = EF.Property<DateTime>(p, "PeriodEnd")
})
.ToListAsync();
foreach (var item in historyItems)
{
Console.WriteLine($"{item.Name}: {item.Description}, Start: {item.PeriodStart}, End: {item.PeriodEnd}");
}
}
exec sp_executesql N'SELECT [p].[Name], [p].[Description], [p].[PeriodStart], [p].[PeriodEnd]
FROM [Products] FOR SYSTEM_TIME ALL AS [p]
WHERE [p].[Id] = @__id_0',N'@__id_0 uniqueidentifier',@__id_0='DD2E351A-25B6-4638-8FD0-EE40F82C57E3'
public class Product
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
var id = await CreateProduct();
await UpdateProduct(id);
await RemoveProduct(id);
static async Task<Guid> CreateProduct()
{
await using DataContext db = new DataContext();
var product = new Product()
{
Id = Guid.NewGuid(),
Name = "product name",
Description = "product description"
};
await db.Products.AddAsync(product);
await db.SaveChangesAsync();
return product.Id;
}
static async Task UpdateProduct(Guid id)
{
await using DataContext db = new DataContext();
var product = await db.Products.FirstAsync(p => p.Id == id);
product.Name = "new product name";
await db.SaveChangesAsync();
}
static async Task RemoveProduct(Guid id)
{
await using DataContext db = new DataContext();
var product = await db.Products.FirstAsync(p => p.Id == id);
db.Products.Remove(product);
await db.SaveChangesAsync();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment