向EF添加新实体时出错:发生了参照完整性约束违规

时间:2013-11-29 08:58:45

标签: c# entity-framework-5

我正在添加一个通过外部类构建的新实体,我收到此错误: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.

修改ReconFact实体未与任何其他实体相关联

代码(已修改):

// 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();

这是非常基础的我构建了ReconFactReconFactGenerator实体的列表。没有指定ID,因为它们是新实体。

编辑 如果我在这里使用相同的方法创建一个新实体,那么它的工作非常完美。在我从上下文查询数据之前:

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

添加了编辑2 在我从上下文查询数据之后:

 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();

上下文无法再保存以返回上述错误。

已编辑为什么在查询上下文后我想要保存时出现错误并且之前没有出现错误?

2 个答案:

答案 0 :(得分:1)

了解如何解决虽然它无法解释错误发生的原因:

// 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();

答案 1 :(得分:0)

出于兴趣,当您将List<T>.ForEach()替换为实际ForEach时,是否会遇到同样的问题,因此请更改:

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

致:

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

db.SaveChanges();