我有ProjekRumah和ProjekKMDetails表。 当我在ProjekRumah数据上使用entities.SaveChanges()时,带有ProjectID的新行将产生其Identity。假设这个数字是7。
然后我拿这个ProjekID = 7来创建ProjekKMDetails数据。然后,entities.SaveChanges()。使用ProjectID = 7作为外键重复相同的步骤Table1,Table2,Table3,Table 4等。
阳光灿烂的日子一切都很好。如果ProjekID = 7已经存在于其中一个表中,假设在表3中,该怎么办。
我明白这不应该发生。但是假设它的星期五13日实习生可能会放弃所有约束而忘记截断Table3。或者一些邪恶的数据腐败。
using (MyDBEntities entities = new MyDBEntities())
{
using (var dbContextTransaction = entities.Database.BeginTransaction())
{
try
{
var dataRumah = new ProjekRumah
{
ProjekStatus = 'SpecialScenario',
ProjekName = data.ProjekName, //data passed in from UI
};
entities.ProjekRumah.Add(dataRumah);
entities.SaveChanges(); // the first .SaveChanges to acquire Identity increment
var dataKMDetails = new ProjekKMDetails
{
ProjekID = dataRumah.ProjekID, //identity ID
KMJPBDNo = data.KMJPBDNumber, //data passed in from UI
};
entities.ProjekKMDetails.Add(dataKMDetails);
var table3Details = new Table3
{
ProjekID = dataRumah.ProjekID, //identity ID
Table3Stuff = data.ForTable3Stuff, //data passed in from UI
};
entities.Table3.Add(table3Details );
//..... No .SaveChanges anywhere
//..... more tables, Tables 4, 5 6 etc
//..... No round trips to database
entities.SaveChanges(); //the second and final .SaveChanges()
dbContextTransaction.Commit();
}
catch (Exception ex)
{
dbContextTransaction.Rollback();
}
}
我的意图是防御性和安全性,是否有语法检查Table3是否已经有ProjectID = 7的行?
据我所知,尝试从Table3删除任何内容都需要删除ProjekRumah和ProjekKMDetails和Table4中相同的ID,依此类推:
ProjekRumah kmContext = new ProjekRumah {
ProjekID = 7,
ProjekKMDetails = new ProjekKMDetails { ProjekID = 7 },
Table3= new Table3 { ProjekID = 7 }
};
entities.ProjekRumah.Attach(kmContext);
entities.ProjekRumah.Remove(kmContext);
entities.SaveChanges(); //this actually deletes from multiple tables
但是在这个阶段,ProjekRumah表中没有(应该)这样的记录,因为之前:entities.Table3.Add(dataTable3Details)将是非法的并导致回滚。
如果“外键已经存在”,我如何编写代码以防守? 或者这种情况永远不会发生101%? 如果可能的话,我想用EF功能清洁,尽可能简洁。
PS:我想我可以总结一下我的问题: 假设在外键约束的情况下找到了一个孤儿行(我认为永远不应该发生),但是如何在单个事务中使用EF来处理这个问题(最好不要计数,选择,FirstorDefault等往返)?