Nate
Nate

Reputation: 2084

Entity Error 4.1 ObjectStateManager-an object with the same key already exists in the objectstatemanager

I simply load a page using the find() method which returns one record for display as a summary and my viewmodel also returns a list of what I call metrics so that the customer can visually identify the metrics they used for a project. If they did not use those metrics, then they can update the value to zero. Once they update the metrics, they click save to insert these metrics into the table. So what we find is that I originally had metrics pulled in from the Metrics table with a status ='Planned' for planned metrics. When they load these metrics into the page, these metrics will get updated with new values if necessary and then reinserted as new rows with the status='Actual'.

Original planned metric record - metricid = 1, metricstatus = 'Planned' New Actual metircs record - no id prior to insert, metricstatus = 'Actual'

I get the following error during insert.

An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key. This is how I insert the record

IList<Metric> MetricList = new List<Metric>();

foreach (var projectMetric in ProjectMetrics){
    if (projectMetric.MetricTypeId != 0)
    {
        var metric = new Metric
        {
            Value = Int32.Parse(projectMetric.Value),
            MetricTypeId = projectMetric.MetricTypeId,
            ProjectId = project.ProjectId,
            MetricPhase = "Actual"

        };

        project.Metrics.Add(metric);

    }
}

This is how I save the change

this.Context.Projects.Attach(project);
this.Context.Entry(project).State = System.Data.EntityState.Modified;

this.Context.SaveChanges();

Any help is greatly appreciated.


public Project GetProjectByID(int? id)
        {
            Project ProjectQuery = Context.Projects.Find(id);

            return ProjectQuery;

        }

I actually send a json string back to the server which has all of my metrics. I deserialize my json string as follows:


List InsertableProjectMetrics = JsonConvert.DeserializeObject>(metricsJSON);

I then call the InsertMetricMethod which loops through the Jason metric data.



 public void InsertProjectMetrics(List ProjectMetrics, int projectid, ref Project project, string Status)
        {
            //Insert Record: Insert New Record
            try
            {
                this.Context.Projects.Attach(project);

                foreach (var projectMetric in ProjectMetrics)
                {
                    if (projectMetric.MetricTypeId != 0)
                    {
                        var metric = new Metric
                        {
                            Value = Int32.Parse(projectMetric.Value),
                            MetricTypeId = projectMetric.MetricTypeId,
                            ProjectId = project.ProjectId,
                            MetricPhase = "Actual"
                        };

                        project.Metrics.Add(metric);

                    }
                }

Upvotes: 0

Views: 1628

Answers (2)

cloudBird
cloudBird

Reputation: 41

Please check below mention things when facing this error:

  1. When inserting database table, having primary key of datatype, uniqueidentitifer, then set primary key column value in code behind as well. E.g. RequestId = Guid.NewGuid(); Eventhough primary key is being populated within insert stored procedure using sql function newid().
  2. When updating a row in database table, do not set primary key column value in code behind. Instead, update the row wrt to primary key column value.

Upvotes: 1

Slauma
Slauma

Reputation: 177133

The order when you add a new metric to project.Metrics and when you attach the project to the context is wrong.

You have many metrics with ID = 0 in the Metrics collection of your project. When you attach now this graph to the context EF puts the project and all children collections into Unchanged state. The exception complains that there is more than one instance with ID = 0.

To solve the problem you must call this line...

this.Context.Projects.Attach(project)

... before you start the foreach loop and add new metrics to the Metrics collection of the attached project. EF change detection will then automatically recognize them as new children and put them into Added state into the context. In Added state duplicate IDs are allowed (as long as your primary key is a database identity column).

Upvotes: 0

Related Questions