7

I'm adding a new entity that is built through an external class and I get this error : A referential integrity constraint violation occurred: A primary key property that is a part of referential integrity constraint cannot be changed when the dependent object is Unchanged unless it is being set to the association's principal object. The principal object must be tracked and not marked for deletion. :

Edit : The ReconFact entity is not linked to any other entities

The code (edited) :

// the context class
AccountingModelContext db = new AccountingModelContext();
// query some data
List<Reconciliation> recon = db.Reconciliations
        .Where(r => r.ReconNum == 112293)  // scenario 18 
        .Include(r => r.ReconciliationDetails.Select(rd => rd.JrnlEntryDetail).Select(jd => jd.JrnlEntry).Select(j => j.ARInvoices.Select(i => i.ARInvoiceDetails)))
        .Include(r => r.ReconciliationDetails.Select(rd => rd.JrnlEntryDetail).Select(jd => jd.JrnlEntry).Select(j => j.ARCredMemoes.Select(c => c.ARCredMemoDetails)))
        .ToList();
// class that will manager business logic and generate facts with above data
ReconFactGenerator generator = new ReconFactGenerator(recon);
// call to the method that will return a list of facts
List<ReconFact> scenario18 = generator.GenerateFacts();
// ERROR RAISED HERE
scenario18.ForEach(f => db.ReconFacts.Add(f));
// never reached
db.SaveChanges();

It's very basic I build a list of ReconFactentities with ReconFactGeneratorclass. No ID's are specified as they are new entities.

edited It works perfectly if I create a new entity in the same method like here Before I query data from the context :

ReconFact testfact = new ReconFact { ItemCode = "test", ReconNum = 1234, ReconDate = DateTime.Parse("2099-01-01"), ShortName = "L_SZTREDFD", InvoiceAmount = 0, CredMemoAmount = 0, IncomingPayAmount = 0, OutgoingPayAmount = 0, JrnlEntryAmount = 0, OtherAmount = 0 };
db.ReconFacts.Add(testfact); // no problems no error raised
db.SaveChanges(); // I can see the new record in my database 
                  // the ID was generated successfully 
                  // as I've specified identity(1,1) in the database

Added Edit 2 After I query data from the context like this :

 List<Reconciliation> recon = db.Reconciliations
        .Where(r => r.ReconNum == 112293)  // scenario 18 
        .Include(r => r.ReconciliationDetails.Select(rd => rd.JrnlEntryDetail).Select(jd => jd.JrnlEntry).Select(j => j.ARInvoices.Select(i => i.ARInvoiceDetails)))
        .Include(r => r.ReconciliationDetails.Select(rd => rd.JrnlEntryDetail).Select(jd => jd.JrnlEntry).Select(j => j.ARCredMemoes.Select(c => c.ARCredMemoDetails)))
        .ToList();

The context is not able to save anymore returning the above error.

edited Why is an error raised when I want to save after I query the context and raises no error before ?

Arno 2501
  • 8,921
  • 8
  • 37
  • 55

2 Answers2

1

Found out how to get around though it doesn't explain why the error occurs :

// the context class
AccountingModelContext db = new AccountingModelContext();
// query some data
List<Reconciliation> recon = db.Reconciliations
        .Where(r => r.ReconNum == 112293)  // scenario 18 
        .Include(r => r.ReconciliationDetails.Select(rd => rd.JrnlEntryDetail).Select(jd => jd.JrnlEntry).Select(j => j.ARInvoices.Select(i => i.ARInvoiceDetails)))
        .Include(r => r.ReconciliationDetails.Select(rd => rd.JrnlEntryDetail).Select(jd => jd.JrnlEntry).Select(j => j.ARCredMemoes.Select(c => c.ARCredMemoDetails)))
        .ToList();
// class that will manager business logic and generate facts with above data
ReconFactGenerator generator = new ReconFactGenerator(recon);
// call to the method that will return a list of facts
List<ReconFact> scenario18 = generator.GenerateFacts();

// ERROR RAISED HERE
// scenario18.ForEach(f => db.ReconFacts.Add(f));

// INSTEAD OF REUSING THE CONTEXT I CREATE A NEW ONE PROBLEM SOLVED !
using (db = new AccountingModelContext())
{
  scenario18.ForEach(f => db.ReconFacts.Add(f));
  db.SaveChanges();
}
db.SaveChanges();
Arno 2501
  • 8,921
  • 8
  • 37
  • 55
  • I've been similarly baffled by this problem. For me, I had some lookup data that I initially queried up via EF, and stored it during Application Startup (and thought the context was dead to me, since it long since gone out of scope). I had to take this [SO answer](http://stackoverflow.com/a/28499105/1520850) into account and refactor my App start-up routine to properly detach the old context. – bkwdesign Sep 09 '15 at 16:42
0

Out of interest, do you get the same issue when you replace the List<T>.ForEach() with an actual ForEach, so change:

scenario18.ForEach(f => db.ReconFacts.Add(f));

To:

foreach(var f in scenario18)
{
  db.ReconFacts.Add(f);
}

db.SaveChanges();
Christian Phillips
  • 18,399
  • 8
  • 53
  • 82
  • Sure I've tested that too ... same result sorry. As long as the created entity comes from a class external to the method it raises the error. – Arno 2501 Nov 29 '13 at 10:14