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



enter image description here


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?





Isn't it easier to just add a public int PostGroupDataModelId { get; set; } property to the PostDataModel 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


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.

Popular posts from this blog

api-platform.com Unable to generate an IRI for the item of type

How to set up datasource with Spring for HikariCP?

Display dokan vendor name on Woocommerce single product pages