Shadow properties are fields that don’t exist in the class itself, but are treated as if they did by Entity Framework. They can participate in queries, create/update operations, and database migrations. Microsoft envisions two main scenarios for shadow properties:
- Allowing the data access layer to work with properties that shouldn’t be exposed via the domain model to the rest of the application
- Allowing developers to effectively add properties to a class that they don’t have the source code for
Shadow properties are defined in the OnModelCreating event, which is exposed as an overridable method in DBContext. Here is an example of attaching a DateTime property called LastUpdated to the Blog entity.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>().Property<DateTime>("LastUpdated");
}
A common use case for this property is automatically setting the LastUpdated property when performing a save operation. To do this, you can use the DBContext.ChangeTracker to get a list of DBEntry objects. From there you can write:
foreach (var item in modifiedEntries)
{
Item.Property("LastModified").CurrentValue = DateTime.Now;
}
Usually this would be done by overriding the SaveChanges() method in the DBContext class. By putting it here, you eliminate the possibility that it will be included for some, but not necessarily all, places that update records.
While the ChangeTracker is great for modifying save events, there will be times where you want to access shadow properties without using a DBEntry directly. This can be done using the EF.Property function as shown below:
EF.Property<DateTime>(entity, "LastModified")
This expression can be placed within a query to generate server-side WHERE and ORDER BY clauses.
You can learn more about this feature in the Channel 9 video titled Shadow Properties in Entity Framework 7.