Introduction
Entity Framework Core has been equipped with many new features but there are some features that were already present in older EF versions. One of the features of Entity Framework Core is "Shadow Properties". The feature "Shadow Properties" was originally introduced in EF 7.
Shadow Properties are properties that 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 operations. They are very useful when the data of some columns should not be exposed to the mapped entity types.
How to Define Shadow Properties
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 an Employee table in the database and it has three columns - Id, Name, and CreatedDate my Model exposes only two properties: Id and Name; and also, we want to define "CreatedDate" as a Shadow property. Using the following query, I have generated a table and test data.
CREATE TABLE [dbo].[Employee](
[Id] [int] NOT NULL,
[Name] [varchar](50) NULL,
[CreatedDate] [datetime2](7) NOT NULL,
CONSTRAINT [PK_Employee] PRIMARY KEY CLUSTERED
(
[Id] ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
INSERT [dbo].[Employee] ([Id], [Name], [CreatedDate]) VALUES (1, N'Jignesh', GETDATE())
INSERT [dbo].[Employee] ([Id], [Name], [CreatedDate]) VALUES (2, N'Rakesh', GETDATE())
INSERT [dbo].[Employee] ([Id], [Name], [CreatedDate]) VALUES (3, N'Tejas', GETDATE())
INSERT [dbo].[Employee] ([Id], [Name], [CreatedDate]) VALUES (4, N'Rajesh', GETDATE())
Employee. cs
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace ShadowProperties.Model
{
[Table("Employee")]
public class Employee
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
}
}
When we query the employee entity, Entity Framework will automatically generate the query. To analyze the query, I just added a console logging provider to DbContextOptionsBuilder.
EntityModelContext.cs
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
namespace ShadowProperties.Model
{
public class EntityModelContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(@"Server=(local);Database=Test;user Id=sa; password=Passwd@12;");
LoggerFactory loggerFactory = new LoggerFactory();
loggerFactory.AddConsole();
optionsBuilder.UseLoggerFactory(loggerFactory);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
}
public DbSet<Employee> Employees { get; set; }
}
}





Join the conversation! Your thoughts help the community grow.