Search code examples
entity-frameworkef-code-firstentity-framework-migrationsdbcontextseeding

Entity Framework: Populating a many-to-many relationship with existing data (seed)


In my Code-First database i have a many-to-many relationship between the object "Question" and the object "Section", which is noted as follows: In Section:

public List<Question> Questions { get; set; }

In Question:

public List<Section> Sections { get; set; }

This does create a link table between the two, called QuestionSections. However, when I try to run my seed method, the link table does not get populated.

The relevant part of the code of the seed method is as follows:

var Sections = new List<Section>
{
    new Section
    {
        InternalSectionId = 1,
        Name = "Global information",
        SurveyId = context.Surveys.First(s => s.Title == "Test Survey").Id
    },
    new Section
    {
        InternalSectionId = 2,
        Name = "More specific",
        SurveyId = context.Surveys.First(s => s.Title == "Test Survey").Id
    },
    new Section
    {
        InternalSectionId = 3,
        Name = "TestingSection",
        SurveyId = context.Surveys.First(s => s.Title == "Test Survey").Id
    }
};
Sections.ForEach(x => context.Sections.AddOrUpdate(ss => ss.Name, x));
context.SaveChanges();

List<Section> section1 = context.Sections.Where(sect => sect.InternalSectionId == 1 && sect.SurveyId == 1)
    .ToList();
List<Section> section2 = context.Sections.Where(sect => sect.InternalSectionId == 2 && sect.SurveyId == 1)
    .ToList();
List<Section> section3 = context.Sections.Where(sect => sect.InternalSectionId == 3 && sect.SurveyId == 1)
    .ToList();

var questions = new List<Question>
            {
                new Question
                {
                    Sections = section1,
                    Title = "What is 1+1?",
                    QuestionOrderId = 1,
                    AnswerRequired = true,
                    InputTypeId = context.InputTypes.First(ip => ip.VisibleName.Equals("Dropdownbox")).Id,
                    StorageType = (int)Constants.Constants.StorageTypes.BoolType
                },
                new Question
                {
                    Sections = section2,
                    Title = "What is 2/1?",
                    QuestionOrderId = 1,
                    AnswerRequired = true,
                    InputTypeId = context.InputTypes.First(ip => ip.VisibleName.Equals("Text")).Id,
                    StorageType = (int)Constants.Constants.StorageTypes.IntType
                    }
                }
            }
questions.ForEach(x => context.Questions.AddOrUpdate(q => q.Title, x));
context.Configuration.ValidateOnSaveEnabled = false;
context.SaveChanges();

The questions get created, the sections get created, but the link table is not populated. I have checked if the objects section1, section2, and section3 are initiated and populated, and they are.

What am I doing wrong?


Solution

  • You have to write the similar code to Link table also. questions.ForEach(x => context.Questions.AddOrUpdate(q => q.Title, x)); because DBContext has no idea of this link table when you are calling context.SaveChanges();.