We are using EF 4.2 in an ASP.NET app linked to an Oracle 11 g database with Oracle’s EF provider.
The parent table is called CASE_PHASE and has a primary key called ID. The child table is called CASE_STAGE and has a primary key called ID. The primary keys for both inserted with a Before Insert Trigger. This question implies the trigger could be the problem.
This code looks like samples I find in Julia Lerman’s book but only inserts a new CASE_PHASE. There are no exceptions thrown but the child is not inserted.
//from the controllers CREATE with hard coded values for testing purposes
// POST: /CasePhase/Create
[HttpPost]
public ActionResult Create(CASE_PHASE case_phase)
{
var caseStage = new CASE_STAGE
{
CREATED_BY_USER_ID = 1604,
LAST_MODIFIED_BY_USER_ID = 1604,
CURRENT = 1,
STAGE_ID = 1752,
DATE_CREATED = DateTime.Now,
DATE_LAST_MODIFIED = DateTime.Now
};
if (ModelState.IsValid)
{
//join new stage to phase
caseStage.CASE_PHASE = case_phase;
//attach linked entities to context
//debugging shows case_phase has the values it needs
//but caseStage does not
db.CASE_PHASE.Attach(case_phase);
db.CASE_PHASE.Add(case_phase);
db.SaveChanges();
What am I missing?
I made sure Visual Studio had service pack 1 after seeing the bug about changes to the StoreGeneratedPattern=”Identity” not being copied. All the primary keys are now properly identified in the model.
Sequences had been created. After modifying the StoreGeneratedPattern I had to modify the triggers so that the insert fired when the primary key was null. It doesn’t matter what value you set the primary key to in the code. If the primary key has the Identity pattern then EF will not send the values to the database.
This works but it’s stupid, two commits for one linked transaction
Using ADO DBContext and Oracle Entity Framework Beta (I don’t expect different behaviour in the production release that is now out because the trigger/sequence idea that Oracle uses does not seem to mix well with EF.
Alternately you could leave the ID fields to the default setting for StoreGeneratedPattern and then get a Primary key direct from the database using a Database.SqlQuery. Add it to the parent and then add it as the foreign key to the child.
You can take your pick: one select sequence from dual and one db.SaveChanges which at least adheres to the idea of an atomic transaction or two db.SaveChanges.