EF Core creating shadow properties despite FK being configured

1.1k Views Asked by At

i am finding that EF core is generating shadow properties for my foreign keys despite the fact i am configuring them, from what i can tell from the documentation it should only do this if it cant match the data types of the columns, but they are both Guids. here is one part of my FK:

public class Property : BaseEntity<Guid>
{
    public Property(Guid Id, List<Classification> classifications) : this(Id)
    {
        _classifications = classifications;
    }
    public Property(Guid id)
    {
        Id = id;
        _attributes = new List<PropertyAttribute>();
        _classifications = new List<Classification>();
        _images = new List<PropertyImage>();
        _siteVistis = new List<PropertySiteVisitLink>();
    }
    private readonly List<Classification> _classifications;

    public IEnumerable<Classification> Classifications => _classifications.AsReadOnly();        
}

the other half:

public class Classification
{
    public Classification(Guid id, Guid propertyId, int classificationBatchId)
    {
        _id = id;
        PropertyId = propertyId;
        ClassificationBatchId = classificationBatchId;
        _classificationResults = new List<ClassificationResult>();
    }

    private Guid _id;

    public Guid Id => _id;
public Guid PropertyId { get; private set; }
}

the configuration for ef core is here:

    {
        public void Configure(EntityTypeBuilder<Property> builder)
        {
            builder.ToTable(ConfigConstants.PropertyTableName, ConfigConstants.VacantsSchema);
            builder.HasKey(p => p.Id);

            builder.Property(p => p.Id).HasColumnName("Id").ValueGeneratedNever();
          
            builder.HasMany<Classification>("_classifications").WithOne().HasForeignKey(c => c.PropertyId);
            builder.Navigation<Classification>(p => p.Classifications).UsePropertyAccessMode(PropertyAccessMode.Field).HasField("_classifications");
            
        }
    }

however when i do a migration, it creates a propertyId1 column and attaches a FK to that as well as the PropertyId field, any ideas why its creating this new column?

edit i think its something to do with the nullability(?) of the column and the FK, in the Classification object, PropertyId is a Guid and set to non nullable, the PropertyId1 one it always wants to create is a nullable Guid, but im not sure how to force it to be non nullable, or just use the property i tell it to?

1

There are 1 best solutions below

0
On BEST ANSWER

EF Core creating shadow properties despite FK being configured

The problem though is that here

builder.HasMany<Classification>("_classifications") // <--
    .WithOne()
    .HasForeignKey(c => c.PropertyId);

the FK is associated with the navigation represented by the _classifications field (by EF Core model terminology it is navigation property event though by the CLR/C# terminology it is a field). Thus the relationship represented by public IEnumerable<Classification> Classifications is unmapped and EF Core assumes it is separate relationship and maps it with conventional shadow FK (and column) name, which in this case has numeric suffix because the original conventional name is already reserved by the other already mapped explicitly relationship.

Of course you don't want two relationships, so just map the FK to the real property

builder.HasMany(e => e.Classifications) // collection navigation property
    .WithOne() // no inverse reference navigation property
    .HasForeignKey(c => c.PropertyId); // FK property 

The next line just associates the property with the backing field and sets the access mode used by EF. Since these are defaults for EFC 3.0+, it can safely be skipped (not needed, redundant)

builder.Navigation(e => e.Classifications)      
    .UsePropertyAccessMode(PropertyAccessMode.Field)
    .HasField("_classifications");