Home > Enterprise >  EF Core (Code First) unable to seed data in One To Many relationship
EF Core (Code First) unable to seed data in One To Many relationship

Time:09-17

I am trying to create a Quiz application and I have two entities. QuestionItem and AnswerItem.

One Question can have multiple answers (One to Many Relationship).

Here are my Models.

public class TblQuestionItem
{
    //removing constructors to keep the code short

    [Key]
    public int QuestionID { get; set; }
    
    [Required]
    public string QuestionText { get; set; }

    public List<TblAnswerItem> AnswerList { get; set; }        
    
}

public class TblAnswerItem
{
    //removing constructors to keep the code short
    
    [Key]
    public int AnswerID { get; set; }
    
    [Required]
    public string AnswerText { get; set; }

    //this is required for foreign key relation 
    public int FkQuestionID { get; set; }
    public TblQuestionItem Question { get; set; }
}

Here is my context class

public class QuestionsDBContext : DbContext
{
    //Constructor
    public QuestionsDBContext(DbContextOptions<QuestionsDBContext> options) : base(options) { }

    public DbSet<TblQuestionItem> TblQuestions { get; set; }
    public DbSet<TblAnswerItem> TblAnswers { get; set; }

    //Seed initial data
    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        //Configure One to Many relationship
        
        builder.Entity<TblAnswerItem>()
            .HasOne(c => c.Question)
            .WithMany(e => e.AnswerList)
            .HasForeignKey(p => p.FkQuestionID)
            .OnDelete(DeleteBehavior.Cascade);

        //Seed data
        TblQuestionItem Question1 = new TblQuestionItem(1, "Who is the CEO of SpaceX ?");
        
        TblAnswerItem Answer1 = new TblAnswerItem(1, "Jeff Bezos", 1, Question1);
        TblAnswerItem Answer2 = new TblAnswerItem(2, "Elon Musk", 1, Question1);
        TblAnswerItem Answer3 = new TblAnswerItem(3, "Bill Gates", 1, Question1);
        TblAnswerItem Answer4 = new TblAnswerItem(4, "Sundar Pichai", 1, Question1);            

        Question1.AnswerList.Add(Answer1);
        Question1.AnswerList.Add(Answer2);
        Question1.AnswerList.Add(Answer3);
        Question1.AnswerList.Add(Answer4);
                   
        builder.Entity<TblQuestionItem>().HasData(Question1);
       
        builder.Entity<TblAnswerItem>().HasData(Answer1);
        builder.Entity<TblAnswerItem>().HasData(Answer2);
        builder.Entity<TblAnswerItem>().HasData(Answer3);
        builder.Entity<TblAnswerItem>().HasData(Answer4);           

    }

}

Now when I am running the Migration, my expectation is the code will create a database and two tables in it, along with the initial data. however the migration is failing with error:

The seed entity for entity type 'TblAnswerItem' cannot be added because it has the 
navigation 'Question' set. To seed relationships, add the entity seed to 'TblAnswerItem' 
and specify the foreign key values {'QuestionID'}. 
Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the involved 
property values.

I tried the solution mentioned Here it did not help. What am I doing wrong here?

CodePudding user response:

I suggest defining a class for your default data, it's more understandable.

First I define this :

public static class DefaultData
{
    public static readonly List<TblQuestionItem> Questions = new List<TblQuestionItem>
    {
        new TblQuestionItem(1, "Who is the CEO of SpaceX ?")
    };

    public static readonly IEnumerable<TblAnswerItem> Answers = new TblAnswerItem[]
    {
        new TblAnswerItem(1, "Jeff Bezos", 1),
        new TblAnswerItem(2, "Elon Musk", 1),
        new TblAnswerItem(3, "Bill Gates", 1),
        new TblAnswerItem(4, "Sundar Pichai", 1)

    };
}

and OnModelCreating Method you [MOST] just need call like these

// seed data
builder.Entity<TblQuestionItem>().HasData(DefaultData.Questions);
builder.Entity<TblAnswerItem>().HasData(DefaultData.Answers);

CodePudding user response:

Do following changes and it should work:

  1. Remove following code(no need to populate navigation property):

    Question1.AnswerList.Add(Answer1); Question1.AnswerList.Add(Answer2); Question1.AnswerList.Add(Answer3); Question1.AnswerList.Add(Answer4);

  2. Remove Question1 parameter from TblAnswerItem constructor. Same reasoning as in item 1.

  • Related