Click here to Skip to main content
13,451,047 members (53,190 online)
Click here to Skip to main content
Add your own
alternative version


2 bookmarked
Posted 22 Mar 2017

Implementing Common Audit Fields with EF Core’s Shadow Property

, 22 Mar 2017
Rate this:
Please Sign up or sign in to vote.
Know how to use Entity Framework's new shadow property feature for easily implementing common audit fields for entities

One of the coolest features of EF Core is that you can define properties that don’t exist in the Entity class. They are called shadow properties. While working on EF6, I needed some common audit fields that every entity will extend. Like, when a row of a table is updated, when a row is created, what is the row version, etc. Since there was no concept of shadow properties in EF6, what I and many other developers did is create an interface with those common fields and implement that interface in required entities. Then add or update the values of these fields through change tracking. Like this:

public interface IAuditable
    DateTime Created { get; set; }
    DateTime Modified { get; set; }

Implement the interface where it is needed:

public class Person : IAuditable
    public int Id { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }

    public DateTime Created { get; set; }
    public DateTime Modified { get; set; }

Update values of the audit fields through entity change tracking:

public override int SaveChanges()
    foreach (var auditableEntity in ChangeTracker.Entries<IAuditable>())
        if (auditableEntity.State == EntityState.Added ||
            auditableEntity.State == EntityState.Modified)
            auditableEntity.Entity.Modified = DateTime.Now;

            if (auditableEntity.State == EntityState.Added)
                auditableEntity.Entity.Created = DateTime.Now;
    return base.SaveChanges();

Instead of creating an interface and implementing it in every entity, we can also add the audit fields as shadow fields. It’s just another way, not a preferred way. So be very choosy when you are designing your entities.

protected override void OnModelCreating(ModelBuilder builder)


Here, the question mark after the data types means that there can be a null value for that mapped column type in the database. If you don't specify it, for datetime column types, ef core will set a default datetime string which sometimes can be confusing.

Since shadow properties are not directly part of the concrete entities, accessing them and working with their values is pretty much different from the usual way.

public override int SaveChanges()
    var modifiedEntries = ChangeTracker.Entries()
        .Where(e => e.State == EntityState.Added || e.State == EntityState.Modified);

    foreach (EntityEntry entry in modifiedEntries)
        var entityType = entry.Context.Model.FindEntityType(entry.Entity.GetType());

        var modifiedProperty = entityType.FindProperty("Modified");
        var createdProperty = entityType.FindProperty("Created");

        if (entry.State == EntityState.Modified && modifiedProperty != null)
            entry.Property("Modified").CurrentValue = DateTime.Now;

        if (entry.State == EntityState.Added && createdProperty != null)
            entry.Property("Created").CurrentValue = DateTime.Now;

    return base.SaveChanges();

And that’s it! This is how you can use shadow properties for implementing audit fields for your entities in a different kind of way. But it is up to you whether you want to use them or not.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Fiyaz Hasan
Software Developer
Bangladesh Bangladesh
#Versatile #Tech #Developer

I am Fiyaz Bin Hasan, above three hash tags perfectly define me. I like to work with different technologies on different platforms. And of course it is not so tough for me to grasp new things. I am confident enough and I think I can solve any enterprise level problems. I love the logic and structure of coding and always strive to write elegant and efficient code. I introduce design patterns in my code which ultimately talks for me.

You may also be interested in...


Comments and Discussions

QuestionI'd rather use viewmodels to hide audit properties Pin
Brady Kelly27-Mar-17 0:16
memberBrady Kelly27-Mar-17 0:16 
AnswerRe: I'd rather use viewmodels to hide audit properties Pin
Fiyaz Hasan27-Mar-17 5:45
memberFiyaz Hasan27-Mar-17 5:45 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.180318.3 | Last Updated 22 Mar 2017
Article Copyright 2017 by Fiyaz Hasan
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid