Introduction
Entity framework is one of the most powerful ORM (Object Relation Mapper) frameworks. Entity framework 7 has come with lots of new features. One of the features of Entity framework 7 is "Shadow Properties".
Shadow Properties are properties which are not present in our entity model class. The values can be changed and maintained by the Change Tracker API. They can also participate in LINQ to Entity query, database migration and Create/Update operation.
Advantages of Shadow Properties
- It allows developers to add properties to the class which does not have source code (property is not defined in model class).
- Allowing the data access layer to access the properties without defining it domain model.
Defining Shadow property using Fluent API
Fluent API can help us to create and configure shadow properties. They are defined at overridable events of DBcontext called "OnModelCreating".
For example, I have "User" table in database and it has three columns "Id", "Name" and "CreatedDate" and my Model is exposing on two properties "Id" and "Name" and also "CreatedDate" want to define as Shadow property.
User Model definition
- public class Users
- {
- public int ID
- {
- get;
- set;
- }
- public string Name {
- get;
- set;
- }
- }
-
- // Definition of DbContext class
- public class MyContext: DbContext
- {
- public DbSet < Users > Users {
- get;
- set;
- }
-
- protected override void OnModelCreating(ModelBuildermodelBuilder)
- {
-
- }
- }
To create shadow property, the first step is to override "OnModelCreating" event of DbContext and we can define shadow property by using "Property" method of modelBuilder.Entity class. Here, if the name passed to the "Property" method matches with the name of existing entity model class property, then Entity framework uses this existing property rather than creating a new shadow property.
The following code helps us to create shadow properties “CreatedDate” in User class.
- protected override void OnModelCreating(ModelBuildermodelBuilder)
- {
- modelBuilder.Entity < Users > ()
- .Property < DateTime > ("CreatedDate");
- }
How to use Shadow Property
As mentioned earlier, Shadow properties are not a part of entity model class and the value and state of Shadow properties are maintained by the Change Tracker API.
Modify the value of Shadow Properties
Change tracker API is responsible for obtaining and changing the value of Shadow properties by using the following code. We can modify the value of shadow property.
- context.Entry(user).Property("CreatedDate").CurrentValue = DateTime.Now;
In above code, “context” is our DbContent class object and “user” is User entity object.
Use Shadow property with LINQ query
Shadow property can also be used in LINQ query by using “EF.Property” static method. For example, the following code can be used to retrieve user list order by created date.
- var users = context.User
- .OrderBy(b =>EF.Property<DateTime>(b, "CreatedDate"));
One of the common cases where we can use the shadow property is automatic set up property value when savechange method is called. For example, "CreatedDate" column is part of all tables and we want to set this property value at the time of savechange automatically. In this case, we can create the shadow property and assign its value at the time of performing a save changes method called.
- var modifiedEntries = context.ChangeTracker
- .Entries().Where(x => x.State == EntityState.Modified)
- .Select(x => x.Entity)
- .ToList();
-
- foreach(var item in modifiedEntries)
- {
- Item.Property("CreatedDate").CurrentValue = DateTime.Now;
- }
Summary
Shadow properties are not defined in entity data model but we can access this by using the above described method. Shadow property cannot be created using data annotations.
Read more articles on Entity framework: