0

I have the following classes that I am looking to add to a database:

class Parent
{
   int Id;
   string Name;
   List<Child> Children;
}

class Child
{
   int Id;
   string Name;
   List<Parent> Parents;
}

And am using the following to save the objects:

foreach (var parent in parents)
{
    var parentModel = await this.context.Parents.FirstOrDefaultAsync(p => p.Id == parent.Id);

    if (parentModel == null)
    {
        await this.context.Parents.AddAsync(parent);
    }
    else
    {
        this.context.Entry(parentModel).CurrentValues.SetValues(parent);
    }
}

await this.context.SaveChangesAsync();

The source data parents is being created from a Web API, and can result in the same different Child objects with the same Id and Name being associated with different Parents.

e.g.

var child1 = new Child { Id = 11, Name = "Same Child ID, Different Object" };
var child2 = new Child { Id = 11, Name = "Same Child ID, Different Object" };

var parent1 = new Parent { Id = 1, Name = "1st Parent", Children = new[] { child1 } };
var parent2 = new Parent { Id = 2, Name = "2nd Parent", Children = new[] { child2 } };

var parents = new[] { parent1, parent2 };

When Entity Framework goes to add the 2nd parent the following error is received: The instance of entity type 'Child' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. This would be due to two different child objects being added with the same Id.

Is there anyway of telling Entity Framework that is OK to use one or the other child objects when saving as they are essentially the same data and should ultimately end up being the same thing? Or maybe I need to add in further code to deal with the children separately?

Or fix the underlying data so that there is only one child object and both parents reference this? This does work for me so maybe the ultimate issue is around the data relationships and I need to fully specify the relationships?

0

1 Answer 1

1

according to your model each child can have only one parent, but you are trying to add the same child to several parents. It is called many to many. you have to fix your model

class Child
{
   int Id;
   string Name;
   List<Parent> Parents;
}

and you can't add 2 objects with the same Id. it will be a primary key violation. you have to assign different primary keys or you can do this

var child = new Child { Id = 11, Name = "Same Child ID, Different Object" };

var parent1 = new Parent { Id = 1, Name = "1st Parent", Children = new[] { child } };
var parent2 = new Parent { Id = 2, Name = "2nd Parent", Children = new[] { child } };
Sign up to request clarification or add additional context in comments.

3 Comments

Yes, the navigation property from child to parent was missing in my example above but not in my actual code. The issue remains with the correct configuration.
@JazzyJ I am sorry but nobody will guess what else do you have. You have to post the whole code , including the way you create or update your object
The code above should suffice for the actual problem - but I think it come down tom as you said in the update, that you can't add 2 objects with the same ID. I'm just looking for a way around this as they both will contain the same data. I'll likely have to fix my data and relationships earlier in the process.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.