0

I need to insert parent record through for loop and based on newly generate ID need to create child records, but EF doesn't seem to be working well.

Based on answers suggested in different stackoverflow questions, I call db.savechanges() after all foreach loop but it's just creating two records whereas foreach loop contains 6 items.

Exception:

System.InvalidOperationException: 'The changes to the database were committed successfully, but an error occurred while updating the object context. The ObjectContext might be in an inconsistent state. Inner exception message: A referential integrity constraint violation occurred: The property value(s) of 'new_job.job_id' on one end of a relationship do not match the property value(s) of 'job_address_point.job_id' on the other end.'

InvalidOperationException: A referential integrity constraint violation occurred: The property value(s) of 'new_job.job_id' on one end of a relationship do not match the property value(s) of 'job_address_point.job_id' on the other end.

Code:

foreach (var cartype in cartypes)
{
    if (cartype.TotalCar != 0)
    {
        for (int i = 0; i < cartype.TotalCar; i++)
        {
            //new_job job = new new_job();
            //new_job_db object same as new_job where I'm assigning all values to properties 
            //received in parameter

            new_job job = new_job_db.CloneJson();

            job.job_ref = str + createRandomNumber();
            job.car_type_id = cartype.CarTypeId;
            db.new_job.Add(job);
            db.SaveChanges();
            var jobId = job.job_id;
            var jobDate = job.job_date;
            //multi address
            foreach (SelectedPoint p in _newjobdto.addresses)
            {
                job_address_point addr = new job_address_point();
                addr.job_id = jobId;
                addr.passenger_id = passengerId;
                addr.job_date = jobDate;
                addr.point_seq = Convert.ToInt32(p.PointSeq);
                addr.place_id = p.PlaceId;
                addr.formatted_address = p.FormattedAddress;
                addr.lat = p.Lat;
                addr.lng = p.Lng;
                addr.post_code = p.PostCode;
                addr.zone_name = p.ZoneName;
                addr.mile = p.Miles;
                addr.km = p.Kms;
                addr.charges = p.Charges;
                db.job_address_point.Add(addr);    
            }
            db.SaveChanges();
        }
    }
}

Update:

Here are debug result: on 1st round it generate the Id and on 2nd round it throwing the exception:

1st round: enter image description here

2nd round: enter image description here

cartypes: enter image description here

Update:

As comment to Gabriel Luci answer, I implemented CloneJson() extension method from this question but its giving same error. I want to take the processing of 20 properties outside of foreach loop and copy it into newly create object inside the foreach loop where there only two properties need to set.

Community
  • 1
  • 1
dawncode
  • 578
  • 1
  • 8
  • 22

1 Answers1

0

First:

new_job job = new new_job();
//new_job_db object same as new_job where I'm assigning all values to properties 
//received in parameter
job = new_job_db;

There are a couple questionable things about this:

  1. The second line is overwriting the first. Either set it to new new_job(), or set it to new_job_db, not both.
  2. What is new_job_db? If it's a record that has already been saved to the database, it's possible this is the reason for the exception, but I can't say without seeing how this is declared.

Next:

db.Entry(job).State = System.Data.Entity.EntityState.Added;
db.new_job.Add(job);

Don't set the State. You don't need to. Adding it to the db.new_job collection will do that for you. This could also be what's causing the exception.

Gabriel Luci
  • 38,328
  • 4
  • 55
  • 84
  • The db.Entry I added because I have seen suggestion in other question, but it didn't help and I have removed it now. The new_job_db is same new_job() object where I'm doing a lot of processing for each property which I don't really want to do inside the foreach loop, but that is where it causing the error, I change the code to new_job job = new_job_db; but it didn't work so I moved the whole new_job_db processing inside the foreach loop and its working now. – dawncode Dec 16 '18 at 07:09
  • There should be a way to prepare object with 20 properties outside of "foreach" loop and copy it into the newly created object inside the "foreach" loop where there are only a couple of properties need to change and save it to db. I look into deep cloning object through this question "https://stackoverflow.com/questions/78536/deep-cloning-objects" where I implemented CloneJson() method and make use of like new_job job = new_job_db.CloneJson(); but again it gave me same error. – dawncode Dec 16 '18 at 10:22
  • I'm looking at the exception a little closer now. It's complaining about the related records (the `job_address_point` records). Each model in EF will have properties that are collections of related records from other tables (probably called something like `job.job_address_points`). It looks like you're cloning those collections too, which will have the ID from the existing record. Either don't clone those collections, or call `job.job_address_points.Clear()` before `SaveChanges()` – Gabriel Luci Dec 16 '18 at 13:08