Caution

This documentation is for EF7 onwards. For EF6.x and earlier release see http://msdn.com/data/ef.

Note

This article uses EF 7.0.0-rc1 which is the latest pre-release available on NuGet.org. You can find nightly builds of the EF7 code base hosted on https://www.myget.org/F/aspnetvnext/ but we do not maintain up-to-date documentation for nightly builds.

Shadow Properties

Shadow properties are properties that do not exist in your entity class. The value and state of these properties is maintained purely in the Change Tracker.

Shadow property values can be obtained and changed through the ChangeTracker API.

context.Entry(myBlog).Property("LastUpdated").CurrentValue = DateTime.Now;

Shadow properties can be referenced in LINQ queries via the EF.Property static method.

var blogs = context.Blogs
    .OrderBy(b => EF.Property<DateTime>(b, "LastUpdated"));

In this article:

Conventions

By convention, shadow properties are only created when a relationship is discovered but no foreign key property is found in the dependent entity class. In this case, a shadow foreign key property will be introduced with the name <principal type name><principal key property name>.

For example, the following code listing will result in a BlogBlogId shadow property being introduced to the Post entity.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
    class MyContext : DbContext
    {
        public DbSet<Blog> Blogs { get; set; }
        public DbSet<Post> Posts { get; set; }
    }

    public class Blog
    {
        public int BlogId { get; set; }
        public string Url { get; set; }

        public List<Post> Posts { get; set; }
    }

    public class Post
    {
        public int PostId { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }

        public Blog Blog { get; set; }
    }

Data Annotations

Shadow properties can not be created with data annotations.

Fluent API

You can use the Fluent API to configure shadow properties. Once you have called the string overload of Property you can chain any of the configuration calls you would for other properties.

If the name supplied to the Property method matches the name of an existing property (a shadow property or one defined on the entity class), then the code will configure that existing property rather than introducing a new shadow property.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
    class MyContext : DbContext
    {
        public DbSet<Blog> Blogs { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Blog>()
                .Property<DateTime>("LastUpdated");
        }
    }

    public class Blog
    {
        public int BlogId { get; set; }
        public string Url { get; set; }
    }