I'm having a weird issue with setting Entity Framework Core foreign keys. EF keeps adding a shadow property automatically for my property and is creating a foreign key of it.
That would be perfectly fine for me, however - I want to be able to set the foreign key delete behaviour to cascade - using that "automatic" shadow property I'm not allowed to do that.
Therefore I decided to create my own foreign key with the Fluent API:
modelBuilder.Entity<PostDataModel>(e =>
{
// Primary key
e.HasKey(c => c.Id);
// Relation
e.HasOne<PostGroupDataModel>()
.WithMany()
.HasForeignKey("GroupId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
This however, did not help much - automatically generated shadow property is still being generated for the table (GroupId1
):
public class PostGroupDataModel
{
public int Id { get; set; }
public string Name { get; set; }
public string Params { get; set; }
public List<PostDataModel> Posts { get; set; }
}
public class PostDataModel
{
public int Id { get; set; }
public string Content { get; set; }
public PostGroupDataModel Group { get; set; }
}
Is there a way to turn off automatic generation of the shadow property in EF Core? or at least modify the generated shadow property to delete on cascade?
Shadow properties are properties that aren't defined in your . NET entity class but are defined for that entity type in the EF Core model. The value and state of these properties are maintained purely in the Change Tracker.
InsuranceSubjectID1' was created in shadow state because a conflicting property with the simple name 'InsuranceSubjectID' exists in the entity type, but is either not mapped, is already used for another relationship, or is incompatible with the associated primary key type.
If you want the foreign key to reference a property other than the primary key, you can use the Fluent API to configure the principal key property for the relationship. The property that you configure as the principal key will automatically be set up as an alternate key.
The [ForeignKey(name)] attribute can be applied in three ways: [ForeignKey(NavigationPropertyName)] on the foreign key scalar property in the dependent entity. [ForeignKey(ForeignKeyPropertyName)] on the related reference navigation property in the dependent entity.
The problem is not the shadow property, but the fluent configuration:
e.HasOne<PostGroupDataModel>()
.WithMany()
By using parameterless overloads you are effectively telling EF to create relationship with no navigation properties at both ends, which it does. However, you do have navigation properties, hence EF Core creates another relationship with conventional FK property/column name. Just because the default name GroupId
is already reserved for your explicit relationship it appends number to it in order to make it unique.
The solution is to always use the Has
/ With
overloads that represent the presense / absence of a navigation property. In your case:
e.HasOne(x => x.Group)
.WithMany(x => x.Posts)
You can keep the rest of the fluent config, but since GroupId
is the default value of the FK property/column in this case, .HasForeignKey("GroupId")
can be skipped. Also because the DeleteBehavior.Cascade
is the default for required relationships, .OnDelete(DeleteBehavior.Cascade)
can be skipped too and the only remaining could be .IsRequired()
. I.e.
.HasForeignKey("GroupId") // optional
.OnDelete(DeleteBehavior.Cascade) // optional
.IsRequired();
Of course specifying them explicitly won't hurt.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With