How to Seed self referencing tree using Entity Framework Core 2.2

entity-framework-core entity-framework-core-2.2

Question

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
            }
        };
}
1
2
3/26/2019 3:16:49 PM

Accepted Answer

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);
2
3/26/2019 3:09:51 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow