Sunteți pe pagina 1din 4

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 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 operations. They are very useful when the data of
some columns should not be exposed on 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 and my Model is exposing only two properties: Id and Name; and also, we want to
define "CreatedDate" as Shadow property. Using the following query, I have generated a table and
test data.
1. CREATE TABLE [dbo].[Employee](
2. [Id] [int] NOT NULL,
3. [Name] [varchar](50) NULL,
4. [CreatedDate] [datetime2](7) NOT NULL,
5. CONSTRAINT [PK_Employee] PRIMARY KEY CLUSTERED
6. (
7. [Id] ASC
8. )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCK
S = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
9. ) ON [PRIMARY]
10.
11. GO
12. SET ANSI_PADDING OFF
13. GO
14. INSERT [dbo].[Employee] ([Id], [Name], [CreatedDate]) VALUES (1, N'Jignesh', GETDATE())
15. INSERT [dbo].[Employee] ([Id], [Name], [CreatedDate]) VALUES (2, N'Rakesh', GETDATE())
16. INSERT [dbo].[Employee] ([Id], [Name], [CreatedDate]) VALUES (3, N'Tejas', GETDATE())
17. INSERT [dbo].[Employee] ([Id], [Name], [CreatedDate]) VALUES (4, N'Rajesh', GETDATE())

Employee.cs
1. using System.ComponentModel.DataAnnotations;
2. using System.ComponentModel.DataAnnotations.Schema;
3.
4. namespace ShadowProperties.Model
5. {
6. [Table("Employee")]
7. public class Employee
8. {
9. [Key]
10. public int Id { get; set; }
11. public string Name { get; set; }
12. }
13. }
When we query the employee entity, Entity Framework will automatically generate the query. To
analyze the query, I just added console logging provider to DbContextOptionsBuilder.

EntityModelContext.cs
1. using Microsoft.EntityFrameworkCore;
2. using Microsoft.Extensions.Logging;
3. using System;
4.
5. namespace ShadowProperties.Model
6. {
7. public class EntityModelContext : DbContext
8. {
9. protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
10. {
11. optionsBuilder.UseSqlServer(@"Server=(local);Database=Test;user Id=sa; passwor
d=Passwd@12;");
12. LoggerFactory loggerFactory = new LoggerFactory();
13. loggerFactory.AddConsole();
14. optionsBuilder.UseLoggerFactory(loggerFactory);
15. }
16. protected override void OnModelCreating(ModelBuilder modelBuilder)
17. {
18.
19. }
20. public DbSet<Employee> Employees { get; set; }
21. }
22. }

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 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 Employee class.
1. protected override void OnModelCreating(ModelBuilder modelBuilder)
2. {
3. modelBuilder.Entity<Employee>().Property<DateTime>("CreatedDate");
4. base.OnModelCreating(modelBuilder);
5. }

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.

Use 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 employee list order by created date.
1. var data1 = context.Employees
2. .OrderBy(b => EF.Property<DateTime>(b, "CreatedDate")).ToList();
We can also retrieve the Shadow property with an anonymous type.
1. var data1 = (from p in context.Employees
2. select new
3. {
4. Id = p.Id,
5. Name = p.Name,
6. CreateDate = EF.Property<DateTime>(p, "CreatedDate")
7. }).ToList();

Insert and Update the value in Shadow property

We can also insert/ update the value in Shadow properties using “EF.Property” static method.
1. using (EntityModelContext context = new EntityModelContext())
2. {
3. Employee emp = new Employee
4. {
5. Id = 5,
6. Name = "Vishal",
7. };
8. context.Entry(emp).Property("CreatedDate").CurrentValue = DateTime.Now;
9.
10. context.Add(emp);
11. context.SaveChanges();
12. }
1. using (EntityModelContext context = new EntityModelContext())
2. {
3. Employee emp = context.Employees.Where(p => p.Id == 5).FirstOrDefault();
4. emp.Name = "Meera";
5. context.Entry(emp).Property("CreatedDate").CurrentValue = DateTime.Now;
6. context.SaveChanges();
7. }

Summary

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. Using fluent API, we can create shadow
Properties, however we cannot create it using data annotations.

S-ar putea să vă placă și