When I try to add migration there is the following exception:
The seed entity for entity type 'Genre' cannot be added because it has the navigation 'SubGenres' set. To seed relationships, you need to add the related entity seed to 'Genre' and specify the foreign key values {'ParentId'}
How I can properly setup seed in EntityFrameworkCore 2.2
I have the next entity
public class Genre
{
[Key] public int Id { get; set; }
[Required] [MaxLength(50)] public string Name { get; set; }
public virtual ICollection<GameGenre> GameGenre { get; set; } = new List<GameGenre>();
public int? ParentId { get; set; }
public virtual Genre ParentGenre { get; set; }
public virtual ICollection<Genre> SubGenres { get; set; } = new List<Genre>();
}
DbContext
public class OnlineGameContext : DbContext
{
public OnlineGameContext(DbContextOptions<OnlineGameContext> options)
: base(options)
{
}
public DbSet<Genre> Genres { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.Entity<Genre>()
.HasMany(u => u.SubGenres)
.WithOne(p => p.ParentGenre)
.HasForeignKey(p => p.ParentId);
modelBuilder.Entity<Genre>().HasData(DefaultGenresFactories.Action);
base.OnModelCreating(modelBuilder);
}
}
Factories
public static class DefaultGenresFactories
{
public static Genre Action =>
new Genre
{
Id = 5,
Name = "Action",
SubGenres = DefaultSubGenresFactories.Action
};
}
public static class DefaultSubGenresFactories
{
public static ICollection<Genre> Action => new List<Genre>
{
new Genre
{
Id = 15,
Name = "FPS",
ParentId = 5
},
new Genre
{
Id = 16,
Name = "TPS",
ParentId = 5
},
new Genre
{
Id = 17,
Name = "Misc",
ParentId = 5
}
};
}
The exception message is telling you that you cannot use navigation properties when seeding with HasData
method, but instead you could specify the relationships only via FK properties.
In other words, you can't use SubGenres
and ParentGenre
navigation properties for specifying the relations, they can be specified only via ParentId
property.
So remove the
SubGenres = DefaultSubGenresFactories.Action
line, and either consolidate the DefaultSubGenresFactories.Action
and DefaultGenresFactories.Action
to a single list of Genre
and use that list in HasData
call, or if you want to keep the DefaultGenresFactories
and DefaultSubGenresFactories
classes separate as they are currently, simply call HasData
for both (it's additive):
modelBuilder.Entity<Genre>().HasData(DefaultGenresFactories.Action);
modelBuilder.Entity<Genre>().HasData(DefaultSubGenresFactories.Action);