Course contentsShow
← C#
Lesson 1140 of 1,90810. Entity Framework Core ModelingFree lesson

Handling Data Versioning

Implement business-level versioning alongside database schema migrations.

In this lesson, you will learn how to implement business-level versioning alongside your database migrations to track state changes that EF Core’s built-in schema tools might overlook.

While EF Core migrations handle structural changes to your database schema, business-level versioning is concerned with the lifecycle of the data itself. When you need to maintain a history of an entity—where every update creates a new, immutable record rather than overwriting the old one—you need a strategy that lives in your application layer.

Implementing a Versioned Entity

To implement this, we decouple the "current" state from the "historical" state. A common approach is to include a VersionNumber and an IsCurrent flag within your entity model.

public class Product
{
    public int Id { get; set; } // Database surrogate key
    public string ProductCode { get; set; } // Business key
    public string Name { get; set; }
    public int VersionNumber { get; set; }
    public bool IsCurrent { get; set; }
}

The Workflow

When you perform an update, you don't just execute a context.Update(). Instead, follow these steps:

  1. Mark Existing: Locate the current record (where ProductCode == x and IsCurrent == true) and set IsCurrent to false.
  2. Create New: Create a new instance of the entity with the same ProductCode, increment the VersionNumber, and set IsCurrent = true.
  3. Persist: Add the new entity to the DbSet.

By using this approach, your database migrations remain focused on the table structure (adding the VersionNumber column, for example), while your DbContext logic handles the business requirement of maintaining a full audit trail of product states. This effectively allows you to query any point-in-time state by filtering on the VersionNumber or simply grabbing the latest state via IsCurrent.

This manual approach complements your schema migrations by ensuring that your data integrity remains intact even as your table structure evolves.

Key Takeaway: Business-level versioning requires you to treat entities as immutable objects by creating new records for updates rather than modifying existing rows, allowing you to maintain a comprehensive historical timeline independent of schema migrations.