I know there are similar questions on stackoverflow – and I looked through them and think my issue is somewhat similar, but haven’t been able to find a solution by looking at any of these other questions/answers.
I’m getting the error when attempting to execute the following code:
Private Sub btnReserve_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnReserve.Click
' Check that the room is still available.
Dim dbCheckOccupants As New pbu_housingEntities
Dim hall As String = CStr(Session("hall"))
Dim room As String = CStr(Session("room"))
Dim checkOccupants = From p In dbCheckOccupants.Rooms _
Let building_id = p.Building1.id _
Where p.building_name = hall _
Where p.room1 = room _
Select p.current_occupancy, p.max_occupancy, p.id, building_id
If checkOccupants.First.current_occupancy >= checkOccupants.First.max_occupancy Then
' If it isn't available, let student know.
lblResult.Text = "Sorry, this room is now fully occupied. Please choose another room."
Else
' If it is available, add the student to the room.
Dim AddOccupant As New pbu_housingEntities
Dim Occupant As New Resident
Dim gender As String = CStr(Session("gender"))
Dim person_name As String = CStr(Session("person_name"))
Dim class_level As String = CStr(Session("class_level"))
Dim semester As String = CStr(Session("term"))
Dim people_code_id As String = CStr(Session("people_code_id"))
Dim first_name As String = CStr(Session("first_name"))
Dim last_name As String = CStr(Session("last_name"))
Dim building_id As String = checkOccupants.First.building_id
Dim room_id As String = checkOccupants.First.id
Occupant.building = building_id
Occupant.room = room_id
Occupant.gender = gender
Occupant.person_name = person_name
Occupant.class_level = class_level
Occupant.semester = semester
Occupant.people_code_id = people_code_id
Occupant.create_date = Date.Now
Occupant.first_name = first_name
Occupant.last_name = last_name
AddOccupant.Residents.AddObject(Occupant)
AddOccupant.SaveChanges()
' Increment the number of occupants in the room.
Dim UpdateRoomOccupancy As New pbu_housingEntities
Dim UpdateOccupancy = (From p In UpdateRoomOccupancy.Rooms _
Where p.building_name = hall _
Where p.room1 = room _
Select p).First
UpdateOccupancy.current_occupancy = UpdateOccupancy.current_occupancy + 1
UpdateRoomOccupancy.SaveChanges()
' Add the student to a bed.
Dim AddBed As New pbu_housingEntities
Dim UpdateBed = From p In AddBed.Beds _
Where p.building = building_id _
Where p.room = room_id _
Where p.occupant = "" _
Select p
' Get the student's ID from the residency table.
Dim GetID = From p In AddBed.Residents _
Where p.people_code_id = people_code_id _
Order By p.id Descending _
Select p
Dim myID As String = GetID.First.id.ToString
UpdateBed.First.occupant = myID
AddBed.SaveChanges()
lblResult.Text = "Success! You have successfully requested residency in this room!"
End If
End Sub
It is catching an error on this line:
Dim myID As String = GetID.First.id.ToString
As far as I can tell I’m not using multiple contexts?
I don’t see exactly why you could get an exception on the line you indicated but the code has in my opinion two flaws: You instantiate 4 different contexts in this method (although I do not see that you mix objects from those contexts) and you don’t dispose any of them. (The database context references an external resource (database connection) which to dispose explicitely is a good practice.)
Try to rewrite it so that you have only one context
dbContext,SaveChangesis only called once and this single context is disposed at the end of the method (through theUsingblock):With a little luck the error disappears and the code is still doing the same as before.
Edit
I just add quickly a general note: Perhaps you have the (wrong) idea that you need a new context for every query, Insert or Delete operation. That’s not the case and actually bad practice with a high risk to mix objects among different contexts. In most situations you can follow a standard pattern in your methods like so:
It’s also important to know that SaveChanges will execute a database transaction, so it’s an All-Or-Nothing operation. I could imagine that this is also important in your method. For instance the two operations you have commented with
Increment the number of occupants in the room.andAdd the student to a bed., shouldn’t they happen either both or none of them to avoid an inconsistent state in the database? With your different contexts it could be possible that the first operation succeeds but the second fails, leaving your data in an inconsistent state in the DB.