Link to home
Start Free TrialLog in
Avatar of itnifl
itniflFlag for Norway

asked on

Eagerly loading related objects in entity framework

I do this:

public List<Alarm> GetSystemIndirectAlarms(Guid systemId) {
 using (SQLConnectionContext db = new SQLConnectionContext()) {
	/* Check if there are alarms on users attached to this system:*/
	 List<Alarm> lstUserAlarmsOnSystem = (from alarm in db.Alarms.Include(a => a.Certificate).
										  Include(a => a.Systems).Include(a => a.User)
										  join usr in db.Users
					on alarm.User.UserID equals usr.UserID
					join dsu in db.DataSystemUsers
					on usr.UserID equals dsu.User.UserID
					where dsu.DataSystem.DataSystemId == systemId && (alarm.ApprovedBy == null || alarm.ApprovedBy == Guid.Empty)
				 select alarm).ToList();


	/* Check if there are alarms on certificates attached to this system: */
	List<Alarm> certificateAlarmsOnSystem = (from alarm in db.Alarms.Include(a => a.Certificate)
											 .Include(a => a.Systems).Include(a => a.User)
											 join cert in db.Certificates
												on alarm.CertificatedId equals cert.CertificateId
											 where cert.Systems.Any(x => x.DataSystemId == systemId) &&
											 alarm.ApprovedBy == null || alarm.ApprovedBy == Guid.Empty
											 select alarm).ToList();


	if (lstUserAlarmsOnSystem != null && certificateAlarmsOnSystem != null) {
	   return (lstUserAlarmsOnSystem.Union(certificateAlarmsOnSystem)).ToList();
	} else if (lstUserAlarmsOnSystem != null) {
	   return lstUserAlarmsOnSystem;
	} else if (certificateAlarmsOnSystem != null) {
	   return certificateAlarmsOnSystem;
	}

 }
 //We seem to have found nothing, so lets return an empty list instead of a null value:
 return new List<Alarm>();
}

Open in new window


But when trying to access the attached certificate to an alarm, I catch a ObjectDisposedException: "The ObjectContext instance has been disposed and can no longer be used for operations that require a connection."

So I thought I was going to avoid that by using eager loading as shown above.

Any thoughts?
Avatar of Fernando Soto
Fernando Soto
Flag of United States of America image

Where, what line of code are you getting the exception on? If there is also an inner exception please post that as well.
Avatar of itnifl

ASKER

Exception screen dump:
User generated image
I have never seen inner exceptions on these type of exceptions.
They simply means that the Entity Framework context used to load the object from database has been disposed and that any further loading of related objects throws this error (since the context is no longer there to do the work). The loading of related objects only when accessed is called lazy loading. In order to eagerly load these objects so that they are available even after the context is disposed, I use the include statements in line 4 and 5, 15 and 16. The context is declared in line two in the code above. It is terminated when the using clause ends.

This has normally worked in other code previously, but then I used lambda and not linq. It shouldn't matter, I thought.

The code that creates the error is the custom ToString method of the Alarm objects I am selecting. It checks if there Alarm.Certificate == null, but Certificate has not yet been loaded by the context even if Certificate was included in the EF query to fetch it (as described above), and the context to load it is disposed.

So back to the original question (and this is Entity Framework specific), why are the objects I want included with the Alarm objects (in this case alarm.Certificate) not being included/loaded when I specify them to be?
ASKER CERTIFIED SOLUTION
Avatar of Fernando Soto
Fernando Soto
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of itnifl

ASKER

Yes, my next step was to try to use what I knew worked, the method based approach. But actually I wanted to know and learn why the query based approach didn't work. But since I have no more time to dwell into t his, I will accept the workaround as the solution.
Seeming that this may be a bug you may want to place a bug report with Microsoft to get an answer to your question.