Skip to content

Use shadow properties for the key and an alternate key: configuration order matters #3093

@boulc

Description

@boulc

I was trying to use shadow properties for the key and an alternate key:

    public class EntityTypeConfiguration : IEntityTypeConfiguration<Entity>
    {
        public void Configure(EntityTypeBuilder<Entity> builder)
        {
            builder.ToTable("Table");

            builder.HasKey("PrimaryKey");
            builder.HasAlternateKey("AdditionalKey");

            builder
                .Property<int>("PrimaryKey") // The name of the shadow property
                .HasColumnName("PK")
                .ValueGeneratedOnAdd()
                .IsRequired();

            builder
                .Property<int>("AdditionalKey") // The name of the shadow property
                .HasColumnName("U")
                .IsRequired();
        }
    }

I got the below exception:

System.InvalidOperationException: The property 'PrimaryKey' cannot be added to the type 'Entity' because there was no property type specified and there is no corresponding CLR property or field. To add a shadow state property the property type must be specified.
   at Microsoft.EntityFrameworkCore.Metadata.Internal.InternalEntityTypeBuilder.Property(Type propertyType, String propertyName, MemberInfo memberInfo, Nullable`1 typeConfigurationSource, Nullable`1 configurationSource)
   at Microsoft.EntityFrameworkCore.Metadata.Internal.InternalEntityTypeBuilder.Property(Type propertyType, String propertyName, Nullable`1 typeConfigurationSource, Nullable`1 configurationSource)
   at Microsoft.EntityFrameworkCore.Metadata.Internal.InternalEntityTypeBuilder.GetOrCreateProperties(IReadOnlyList`1 propertyNames, Nullable`1 configurationSource, IReadOnlyList`1 referencedProperties, Boolean required, Boolean useDefaultType)
   at Microsoft.EntityFrameworkCore.Metadata.Internal.InternalEntityTypeBuilder.PrimaryKey(IReadOnlyList`1 propertyNames, ConfigurationSource configurationSource)
   at Microsoft.EntityFrameworkCore.Metadata.Builders.EntityTypeBuilder.HasKey(String[] propertyNames)

Declaring the keys after the properties did the trick, thank to the hint in Relationships - EF Core page:

We recommend explicitly adding the shadow property to the model before using it as a foreign key (as shown below).

Final working code:

    public class EntityTypeConfiguration : IEntityTypeConfiguration<Entity>
    {
        public void Configure(EntityTypeBuilder<Entity> builder)
        {
            builder.ToTable("Table");

            builder
                .Property<int>("PrimaryKey") // The name of the shadow property
                .HasColumnName("PK")
                .ValueGeneratedOnAdd()
                .IsRequired();

            builder
                .Property<int>("AdditionalKey") // The name of the shadow property
                .HasColumnName("U")
                .IsRequired();

            builder.HasKey("PrimaryKey");
            builder.HasAlternateKey("AdditionalKey");
        }
    }

Wouldn't it be worth mentioning that the shadow property to the model must be added before using it as primary or alternate key?


Document Details

Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions