Home > database >  Json into EF with duplicates
Json into EF with duplicates

Time:05-10

I have following sample JSON (simplified):

{
   "programmes":[
      {
             "programmeID":"163",
             "title":"Programme 1",
             "color":"#ff5f57",
             "moderators":[
                {
                   "moderatorID":"27",
                   "name":"Moderator 1",
                }
             ]
          },
          {
             "programmeID":"153",
             "title":"Programme 2",
             "color":"#ff5f57",
             "moderators":[
                {
                   "moderatorID":"27",
                   "name":"Moderator 1",
                }
             ]
          },

       ]
}

I want to convert into following objects:

    public class Programme
    {
        [Key]
        public string programmeID { get; set; }
        public string title { get; set; }

        //Navigational Property
        public virtual ICollection<Moderator> moderators { get; set; }
    }

    public class Moderator
    {
        [Key]
        public string moderatorID { get; set; }
        public string name { get; set; }

        //Navigational Property
        public virtual ICollection<Programme> programmes { get; set; }
    }

Everything is fine, objects looks great, populated correctly, but when trying to save into db a get this error:

The instance of entity type 'Moderator' cannot be tracked because another instance with the key value '{moderatorID: 27}' is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached.

This error happens when calling .Add with the list of Programmes:

List<Programme> programmes;
programmes = JsonSerializer.Deserialize<List<Programme>>(JSONcontent);
//... db init
db.AddRange(programmes);

I understand that there is a duplicity for Moderator (ID=27), but I think that it's quite a normal pattern in JSON. I can do some workaround, but wondering if there is any best practice how to handle this in EF directly?

CodePudding user response:

you can not add children you are created from deserialization as an existed ones. One of the solutions is finding the existed children at first

List<Programme> programmes = JsonSerializer.Deserialize<List<Programme>>(JSONcontent);

foreach (var program in programmes)
{
var moderators=new List<Moderator>();
foreach (var moderator in program.moderators)
{
     var existingModerator=db.Moderators.FirstOrDefault(i=> 
                 i.moderatorId=moderator.moderatorId);
    moderators.Add(existingModerator);
}
  programm.moderators=moderators;
}
db.AddRange(programmes);

but I usually prefer to create an explicit class for many to many relations. It will make all your code much more simple.

  • Related