Saw
Saw

Reputation: 6426

Adding to many-to-many collection without querying the main entities

I have a batch work, I need to add new relations between existing entities, the entities have big data, I can't get the entities and add them, I have tried this:

  for .........
                Class Class = new Class() { ClassID = myClassId };
                context.AddToClasses(Class);
                Student std = new Student() { Id = myStdId };
                context.AddToStudents(std);
                context.ObjectStateManager.ChangeObjectState(Class, System.Data.EntityState.Unchanged);
                context.ObjectStateManager.ChangeObjectState(std, System.Data.EntityState.Unchanged);
                Class.ClassStudents.Add(std);

  .............

The first call will success, but the second one will give me this exception:

AcceptChanges cannot continue because the object's key values conflict with another object in the ObjectStateManager. Make sure that the key values are unique before calling AcceptChanges.

Tried :

  for .........
                Class Class = new Class() { ClassID = myClassId };
                context.Attach(Class);
                Student std = new Student() { Id = myStdId };
                context.Attach(std);
                context.ObjectStateManager.ChangeObjectState(Class, System.Data.EntityState.Unchanged);
                context.ObjectStateManager.ChangeObjectState(std, System.Data.EntityState.Unchanged);
                Class.ClassStudents.Add(std);

  .............

Exception:

An object with a null EntityKey value cannot be attached to an object context.

How can I do this?

Upvotes: 0

Views: 401

Answers (1)

Slauma
Slauma

Reputation: 177163

If the pairs of myClassId and myStdId can be repetitive and in no particular order in the loop you are running over this code I would use two dictionaries to hold the already created and attached entities to avoid that you create and attach an entity with the same key a second time, like so:

var classDict = new Dictionary<int, Class>();
var studentDict = new Dictionary<int, Student>();

// for ... loop starts here

Class Class;
if (!classDict.TryGetValue(myClassId, out Class))
{
    Class Class = new Class() { ClassID = myClassId };
    context.Classes.Attach(Class);
    classDict.Add(myClassId, Class);
}

Student std;
if (!studentDict.TryGetValue(myStdId, out std))
{
    Student std = new Student() { Id = myStdId };
    context.Students.Attach(std);
    classDict.Add(myStdId, std);
}

Class.ClassStudents.Add(std);

// loop ends here

context.SaveChanges();

Upvotes: 1

Related Questions