I have table ProjekRumah and ProjekKMDetails. When I use entities.SaveChanges() on ProjekRumah data, new row with ProjectID will yield its Identity. Suppose that number is 7.
Then I take this ProjekID=7, to create ProjekKMDetails data. Then, entities.SaveChanges(). Repeat same step Table1, Table2, Table3, Table 4 and so on with ProjectID=7 as Foreign Key.
All is fine on sunny day. What if ProjekID=7 already exists in one of these table, suppose hypothetically in Table3.
I understand this is not suppose to happen. But suppose its Friday the 13th an intern might drop all constraints and forgot to truncate Table3. Or some evil data corruption.
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();
}
}
My intent is to be defensive and safe side, is there a syntax to check if Table3 already have row with ProjectID = 7?
To my understanding attempting to delete anything from Table3 will require delete on same corresponding ID in ProjekRumah and ProjekKMDetails and Table4 and so on:
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
But at this stage there is no (should be) such record in ProjekRumah table because earlier on: entities.Table3.Add(dataTable3Details) would be illegal and caused rollback.
How do I write code to be on defensive side in case 'Foreign Key Already Exist' happens? Or such a scenario can never ever 101% to happen? If possible, I would like to cleanse with EF functions as succinct and as elegant as possible.
PS: I guess I can summarize my question as this: Suppose an orphan row was found despite Foreign Key constrains (should never happen I believe), but how do I use EF to handle this in a single transaction (preferably with no round trips such as Count, Select, FirstorDefault etc)?