3

I have two table like this:

**Complaint**
-Id
-CreatedBy
-CreatedDate
....

**Solution**
-Id
-ComplaintId

Sometimes, a complaint has an instant solution, which means, when it is created, a solution is also created. The Database is Oracle, and to insert new record into database, I set the StoredGeneratePattern to Identity and use trigger to insert a sequence's value.

here my code:    

using (var context = new Entities())
        {
        var complaint = new Complaint
                            {
                                Title = TitleTextBox.Text.Trim(),
                                CreatedBy = CurrentUser.UserID,
                                Description = DescriptionTextBox.Text.Trim(),
                                ServiceId = Convert.ToDecimal(ddlService2.Value),
                                Contact = ContactTextBox.Text.Trim(),
                                CreatedDate = DateTime.Now,
                                Customer = txtUserName.Text.Trim(),
                                ResellerId = CurrentUser.ResellerID,
                                Status = ComplaintStatus.GetStatusCode("New complaint")
                            };
        if (CompletedCheckBox.Checked)
        {
            complaint.Status = ComplaintStatus.GetStatusCode("Completed");
            var solution = new Solution
                               {
                                   CreatedBy = CurrentUser.UserID,
                                   CreatedDate = DateTime.Now,
                                   SolutionDesc = DescriptionTextBox.Text,
                                   ComplaintId = complaint.Id
                               };            
            context.Solutions.AddObject(solution);

        }

            context.Complaints.AddObject(complaint);
            if(context.SaveChanges() > 0)
            {
                ResetFrom();
                return true;
            }

        }

the problem is, I can't get the id of newly created complaint to set the field in the solution. How can I do that?

Thank you.

Delta76
  • 13,931
  • 30
  • 95
  • 128

5 Answers5

1

Could you not perform the first operation call SaveChanges() and then query your complaint object which should now have a complaintID.

MattC
  • 3,984
  • 1
  • 33
  • 49
1

Assuming you are using a trigger/sequence with Oracle, you will need to do a get after you save changes to get an object with the Id populated. If you are not using a trigger, you can set the Id manually on the new object by getting the next value from the sequence.

Matthew
  • 2,210
  • 1
  • 19
  • 30
  • I'm actually using trigger, can you provide more detail about "doing a get"? Thank you :) – Delta76 Mar 30 '11 at 08:45
  • Now that I've had a little more time to think about it, since you are using a sequence/trigger, I think what you should do is after you create/persist the object just call back to oracle to get the current value of the sequence and populate the ID value of the object with the value from the trigger. LINQ/EF isn't really great for Oracle. NHibernate works awesome with Oracle. If you do need to use EF, check out [this SO post](http://stackoverflow.com/questions/82644/can-you-use-microsoft-entity-framework-with-oracle) – Matthew Mar 30 '11 at 12:54
  • I'm already using Oracle provider for EF, can you please provide me the actual code of calling back to Oracle? thank you :) – Delta76 Mar 30 '11 at 15:56
  • Can't really provide code since I don't have an oracle installation to test with. I suggest that you create a stored proc in oracle to return the current value of the sequence for that table and then map a funciton in EF to that proc. Then you can call the function and get the value. – Matthew Mar 30 '11 at 17:41
0

If you add the complaint and SaveChanges() before you create the solution the complaint object will have the Identity value, then after creating the solution add it to the context and call SaveChanges() a second time.

context.Complaints.AddObject(complaint);


if (CompletedCheckBox.Checked)
    {

        complaint.Status = ComplaintStatus.GetStatusCode("Completed");
        context.SaveChanges();

        var solution = new Solution
                           {
                               CreatedBy = CurrentUser.UserID,
                               CreatedDate = DateTime.Now,
                               SolutionDesc = DescriptionTextBox.Text,
                               ComplaintId = complaint.Id
                           };            
        context.Solutions.AddObject(solution);

    }


        if(context.SaveChanges() > 0)
        {
            ResetFrom();
            return true;
        }

Also if you were to add a Foreign Key Relationship Between the Solution and the Complaint, you would no set the ComplaintId, you would just set solution.Complaint = complaint and the Ids would be set correctly during the save.

Wes Grant
  • 2,044
  • 16
  • 14
  • I tried, but even after calling SaveChanges(), the Id field of complaint entity still 0 :( – Delta76 Mar 23 '11 at 10:13
  • 1
    As per the second part of Wes' response, if you've got the database relationship correctly set up then you shouldn't need to think about it. When you create the new solution, just set the complaint to be the new complaint. – Timbo Mar 23 '11 at 10:29
  • Here is a post about this same problem, the above has worked for me, but the person in this post had to set the Results Column Binding. http://stackoverflow.com/questions/1187175/entity-framework-savechanges-doesnt-get-the-generated-identity-key – Wes Grant Mar 23 '11 at 10:34
  • I'm using Oracle, this may explain why I can't get the complaintID, as with SQL Server – Delta76 Mar 24 '11 at 09:04
  • Is there any way that you can add a foreign key from the solutions table to the complaint Id for that field? I you do this will add the navigation property to just say Solution.Complaint = complaint and save both objects at once. If you don't use this feature of Entity Framework I think you are missing out of one of the greatest benefits that it has to offer. – Wes Grant Mar 24 '11 at 12:33
0

The answer is actually easy. In this case I do not believe you need the ID at all (at least not just to add this relationship), but in case you do, do this:

Make sure you have the ID on the Complaint entity to refresh on Insert (We use DevArt, but I forget the exact setting name here, but if you select the ID on the entity you should see an UpdateMode or something like that that needs to be set to UpdateOnInsert i think), then

To just insert this relationship do this:

using (var context = new MyContext())
{
  var complaint = new Complaint {...};
  context.Complaints.AddObject(complaint);
  var solution = new Solution {..., Complaint = complaint};
  context.Solutions.AddObject(solution);
  context.SaveChanges();
}

You will not want to do SaveChanges twice as that requires a separate transactionscope. This way you don't need it.

Mirko
  • 4,284
  • 1
  • 22
  • 19
0

You can add the Complaint to the Solutions "Complaint" navigation property.

So create your solution object like you are doing then do the following:

Soltion.Complaint = newCreatedComplaintObject;
Ryan
  • 4,354
  • 2
  • 42
  • 78