Skip to main content
Shadow Properties with Entity Framework Core

How to use Shadow Properties with Entity Framework Core

As mentioned in my earlier post Quick summary of what’s new in Entity Framework Core 1.0, “Shadow Properties” is one of the new feature of Entity Framework Core. Shadow Properties are fields which are not part of your entity class so they don’t exist in your class but they do exist in entity model. In this post, let’s find out how to use shadow properties in Entity Framework Core.

Use Shadow Properties with Entity Framework Core

The value and state of Shadow properties are maintained in the Change Tracker API. Shadow Properties are a useful in following conditions,

  • When you can’t make changes to existing entity class (third party) and you want to add some fields to your model.
  • When you want certain properties to be part of your context, but don’t wish to expose them.

So these properties are available for all database operations, but not available in the application as they are not exposed via entity class. Let’s see how to create and use them.

Creating Shadow Properties

For demonstration, let’s consider following entity class named Category. As per the domain class, there should be only 2 fields present in database Category table which are CategoryID and CategoryName.

public class Category
{
    public int CategoryID { get; set; }
    public string CategoryName { get; set; }
}

And we wish to add a new field to database table named CreatedDate but as a shadow property. At the time of writing this post, you can only create Shadow Properties via Fluent API. So to create CreatedDate shadow property, override OnModelCreating and add the following code. Use Property() method to define the data type and name of the property.

protected override void OnModelCreating(ModelBuilder modelbuilder)
{
    modelbuilder.Entity<Category>().Property<DateTime>("CreatedDate");
}

As mentioned earlier, Change Tracker API is responsible for maintaining the shadow properties. So you can Get and Set value via Change Tracker API. Following code adds a category record in the database. See highlight line to set shadow property value.

Category c = new Category() { CategoryName = "Accessories" };
dataContext.Entry(c).Property("CreatedDate").CurrentValue = DateTime.Now;
dataContext.Categories.Add(c);
dataContext.SaveChanges();

If you don’t specify any value for shadow properties, then DateTime.MinValue will be taken as default value. You can also set the value in SaveChanges() method. Following code, first finds all the entities with added state and then set the created date for every record.

public override int SaveChanges()
{
    var modifiedEntries = ChangeTracker
                        .Entries().Where(x => x.State == EntityState.Added);

    foreach (var item in modifiedEntries)
    {
        item.Property("CreatedDate").CurrentValue = DateTime.Now;
    }
    return base.SaveChanges();
}

How to refer them in LINQ query?

Shadow properties can be referenced in LINQ queries via the EF.Property static method. Following code, retrieves the category list order by created date and then display them.

var cList = dataContext.Categories
        .OrderBy(b => EF.Property<DateTime>(b, "CreatedDate")).ToList();
foreach (var cat in cList)
{
   Console.Write("Category Name: " + cat.CategoryName);
   Console.WriteLine(" Created: " + dataContext.Entry(cat).Property("CreatedDate").CurrentValue);
}

To display or get the value, we need to use Change Tracker API only.

Shadow Property name matches with existing property name?

What happens when defined shadow property name matches one of the existing model property name? Is your code going to throw an exception? Well, no. The code will configure the existing property instead of creating a new shadow property. You can also configure column name to be different from Shadow Property. Like,

modelbuilder.Entity<Category>().Property<DateTime>("CreatedDate")
                   .HasColumnName("Created_Date");

Summary

That’s it. Shadow properties may come handy while working with any existing entity and you don’t have access to modify it.

Thank you for reading. Keep visiting this blog and share this in your network. Please put your thoughts and feedback in the comments section.

PS: If you found this content valuable and want to return the favour, then Buy Me A Coffee

2 thoughts to “How to use Shadow Properties with Entity Framework Core”

Leave a Reply

Your email address will not be published. Required fields are marked *