Turning off shadow property generation
Turning off shadow property generation
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
):
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?
public int PostGroupDataModelId { get; set; }
PostDataModel
@CamiloTerevinto That wouldn't stop EF from adding a shadow property along with the unnecessary foreign key.
– Lucas
Jul 2 at 0:56
1 Answer
1
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.
GroupId
The solution is to always use the Has
/ With
overloads that represent the presense / absence of a navigation property. In your case:
Has
With
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.
GroupId
.HasForeignKey("GroupId")
DeleteBehavior.Cascade
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasForeignKey("GroupId") // optional
.OnDelete(DeleteBehavior.Cascade) // optional
.IsRequired();
Of course specifying them explicitly won't hurt.
Great answer. Appreciate that.
– Lucas
Jul 2 at 11:52
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Isn't it easier to just add a
public int PostGroupDataModelId { get; set; }
property to thePostDataModel
class? That way your model does not depend on the ability to create columns and you are explicit about your intentions– Camilo Terevinto
Jul 2 at 0:42