Home > OS >  EF : no mapping specified for properties
EF : no mapping specified for properties

Time:09-21

I have two tables MeetingPollingQuestion and MeetingPollingParts. Meeting polling question pk MeetingPollingQuestionId is a foreign key to meeting polling parts. I would like to insert the MeetingPollingQuestion and then use the PK to then insert rows into MeetingPollingParts. I am getting this error about "No mapping specified for properties" and I am not sure what that means.

enter image description here

My code:

   mf.MeetingPollingId = mpq.MeetingPollingId;
   mf.MeetingPollingQuestionType = mpq.MeetingPollingQuestionType;
   mf.SequenceOrder = mpq.SequenceOrder;
    
   db.MeetingPollingQuestions.Add(mf);
    
   var MeetingPollingPartList = new List<EFModel.MeetingPollingPart>();
    
   foreach (var p in mpq.MeetingPollingParts)
   {
       var mfParts = new EFModel.MeetingPollingPart();
       mfParts.MeetingPollingQuestionId = mf.MeetingPollingQuestionId;
       mfParts.Type = p.Type;
       MeetingPollingPartList.Add(mfParts);
   }

   db.MeetingPollingParts.AddRange(MeetingPollingPartList);
    
   db.SaveChanges();
   dbTran.Commit();

This is the error I get:

Problem in mapping fragments starting at line 4481:No mapping specified for properties MeetingPollingPart.MeetingPollingQuestionMeetingPollingQuestionId, MeetingPollingPart.MeetingPollingQuestionMeetingPollingQuestionId1 in Set MeetingPollingParts.
An entity with key (PK) will not round-trip

CodePudding user response:

Use navigation properties to insert related entities.

The issue with your approach is that when EF is set up to use identity columns you won't have a PK to use as a FK until after you call SaveChanges on a DbContext. If you use tracked navigation properties then EF will automatically ensure that the entities are inserted in the correct order and associate the FKs for newly inserted parent records.

For instance, a MeetingPolling should have a collection of MeetingPollingQuestions, and a MeetingPollingQuestion would have a collection of MeetingPollingParts.

I.e.

public class MeetingPolling
{
    // ID, and various fields...

    public virtual ICollection<MeetingPollingQuestion> MeetingPollingQuestions { get; protected set; } = new List<MeetingPollingQuestion>();
}

public class MeetingPollingQuestion
{
    // ID, and various fields....

    public virtual ICollection<MeetingPollingPart> MeetingPollingParts { get; protected set; } = new List<MeetingPollingPart>();
}

The next important detail when updating an existing MeetingPolling to add/update questions and parts is to ensure that these collections are eager loaded so they can be modified:

var meetingPolling = db.MeetingPollings
    .Include(x => x.MeetingPollingQuestions)
        .ThenInclude(x => x.MeetingPollingParts)
    .Single(x => x.Id == meetingPollingId);

Now when you go to create your question, you populate a new MeetingPollingQuestion and fill in the details much like you are now, except rather than adding it to the DbContext, you add it to the MeetingPolling's questions collection that you had loaded:

meetingPolling.MeetingPollingQuestions.Add(newMeetingPollingQuestion);

The same goes for populating the MeetingPollingParts. Create a new entity populating the details, but append those to the new MeetingPollingQuestion.

The ends result would look more like this:

var meetingPolling = db.MeetingPollings
    .Include(x => x.MeetingPollingQuestions)
        .ThenInclude(x => x.MeetingPollingParts)
    .Single(x => x.Id == meetingPollingId);

var newMeetingPollingQuestion = new MeetingPollingQuestion
{
    MeetingPollingQuestionType = mpq.MeetingPollingQuestionType,
    SequenceOrder = mpq.SequenceOrder,
    // ...
    MeetingPollingParts = mpq.MeetingPollingParts.Select(p => new MeetingPollingPart
    {
        Type = p.Type,
        // ...
    }).ToList()
};

meetingPolling.MeetingPollingQuestions.Add(newMeetingPollingQuestion);
db.SaveChanges();

EF will take care of all of the FK assignments for new records automatically.

  • Related